diff --git a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java index 7e60b536..f60db63e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java @@ -28,8 +28,6 @@ public class HexConfig { } public interface ClientConfigAccess { - double patternPointSpeedMultiplier(); - boolean ctrlTogglesOffStrokeOrder(); boolean invertSpellbookScrollDirection(); @@ -60,9 +58,11 @@ public class HexConfig { ScrollQuantity scrollsForLootTable(ResourceLocation lootTable); - int DEFAULT_MAX_RECURSE_DEPTH = 64; + int DEFAULT_MAX_RECURSE_DEPTH = 512; int DEFAULT_MAX_SPELL_CIRCLE_LENGTH = 1024; int DEFAULT_OP_BREAK_HARVEST_LEVEL = 3; + + boolean DEFAULT_VILLAGERS_DISLIKE_MIND_MURDER = true; List DEFAULT_FEW_SCROLL_TABLES = List.of("minecraft:chests/jungle_temple", "minecraft:chests/simple_dungeon", "minecraft:chests/village/village_cartographer"); List DEFAULT_SOME_SCROLL_TABLES = List.of("minecraft:chests/bastion_treasure", diff --git a/Common/src/main/resources/assets/hexcasting/lang/en_us.json b/Common/src/main/resources/assets/hexcasting/lang/en_us.json index 17329d06..306b0348 100644 --- a/Common/src/main/resources/assets/hexcasting/lang/en_us.json +++ b/Common/src/main/resources/assets/hexcasting/lang/en_us.json @@ -172,6 +172,46 @@ "emi.category.hexcasting.villager_leveling": "Trade Leveling", "emi.category.hexcasting.villager_profession": "Villager Profession", + "text.autoconfig.hexcasting.title": "Hexcasting Config", + "text.autoconfig.hexcasting.category.common": "Common", + "text.autoconfig.hexcasting.category.client": "Client", + "text.autoconfig.hexcasting.category.server": "Server", + "text.autoconfig.hexcasting.option.common.dustMediaAmount": "Dust Media Amount", + "text.autoconfig.hexcasting.option.common.shardMediaAmount": "Shard Media Amount", + "text.autoconfig.hexcasting.option.common.chargedCrystalMediaAmount": "Charged Crystal Media Amount", + "text.autoconfig.hexcasting.option.common.mediaToHealthRate": "Media To Health Rate", + "text.autoconfig.hexcasting.option.common.dustMediaAmount.@Tooltip": "How much media a single Amethyst Dust item is worth", + "text.autoconfig.hexcasting.option.common.shardMediaAmount.@Tooltip": "How much media a single Amethyst Shard item is worth", + "text.autoconfig.hexcasting.option.common.chargedCrystalMediaAmount.@Tooltip": "How much media a single Charged Amethyst Crystal item is worth", + "text.autoconfig.hexcasting.option.common.mediaToHealthRate.@Tooltip": "How many points of media a half-heart is worth when casting from HP", + "text.autoconfig.hexcasting.option.client.ctrlTogglesOffStrokeOrder": "Ctrl Toggles Off Stroke Order", + "text.autoconfig.hexcasting.option.client.invertSpellbookScrollDirection": "Invert Spellbook Scroll Direction", + "text.autoconfig.hexcasting.option.client.invertAbacusScrollDirection": "Invert Abacus Scroll Direction", + "text.autoconfig.hexcasting.option.client.gridSnapThreshold": "Grid Snap Threshold", + "text.autoconfig.hexcasting.option.client.ctrlTogglesOffStrokeOrder.@Tooltip": "Whether the ctrl key will instead turn *off* the color gradient on patterns", + "text.autoconfig.hexcasting.option.client.invertSpellbookScrollDirection.@Tooltip": "Whether scrolling up (as opposed to down) will increase the page index of the spellbook, and vice versa", + "text.autoconfig.hexcasting.option.client.invertAbacusScrollDirection.@Tooltip": "Whether scrolling up (as opposed to down) will increase the page index of the abacus, and vice versa", + "text.autoconfig.hexcasting.option.client.gridSnapThreshold.@Tooltip": "When using a staff, the distance from one dot you have to go to snap to the next dot, where 0.5 means 50% of the way (0.5-1)", + "text.autoconfig.hexcasting.option.server.opBreakHarvestLevel": "Break Harvest Level", + "text.autoconfig.hexcasting.option.server.maxRecurseDepth": "Max Recurse Depth", + "text.autoconfig.hexcasting.option.server.maxSpellCircleLength": "Max Spell Circle Length", + "text.autoconfig.hexcasting.option.server.actionDenyList": "Action Deny List", + "text.autoconfig.hexcasting.option.server.circleActionDenyList": "Circle Action Deny List", + "text.autoconfig.hexcasting.option.server.villagersOffendedByMindMurder": "Villagers Offended By Mind Murder", + "text.autoconfig.hexcasting.option.server.fewScrollTables": "Few Scroll Tables", + "text.autoconfig.hexcasting.option.server.someScrollTables": "Some Scroll Tables", + "text.autoconfig.hexcasting.option.server.manyScrollTables": "Many Scroll Tables", + "text.autoconfig.hexcasting.option.server.opBreakHarvestLevel.@Tooltip": "The harvest level of the Break Block spell.\n0 = wood, 1 = stone, 2 = iron, 3 = diamond, 4 = netherite.", + "text.autoconfig.hexcasting.option.server.maxRecurseDepth.@Tooltip": "How many times an action can recursively cast other actions", + "text.autoconfig.hexcasting.option.server.maxSpellCircleLength.@Tooltip": "The maximum number of slates in a spell circle", + "text.autoconfig.hexcasting.option.server.actionDenyList.@Tooltip": "Resource locations of disallowed actions. Trying to cast one of these will result in a mishap.", + "text.autoconfig.hexcasting.option.server.circleActionDenyList.@Tooltip": "Resource locations of disallowed actions withhin circles. Trying to cast one of these from a circle will result in a mishap.", + "text.autoconfig.hexcasting.option.server.villagersOffendedByMindMurder.@Tooltip": "Whether villagers should be angry at the player when other villagers are mindflayed", + "text.autoconfig.hexcasting.option.server.fewScrollTables.@Tooltip": "Loot tables that a small number of Ancient Scrolls are injected into", + "text.autoconfig.hexcasting.option.server.someScrollTables.@Tooltip": "Loot tables that a decent number of Ancient Scrolls are injected into", + "text.autoconfig.hexcasting.option.server.manyScrollTables.@Tooltip": "Loot tables that a huge number of Ancient Scrolls are injected into", + + "advancement.hexcasting:root": "Hexcasting Research", "advancement.hexcasting:root.desc": "Find and mine a concentrated form of media growing deep beneath the earth.", "advancement.hexcasting:enlightenment": "Achieve Enlightenment", @@ -187,7 +227,7 @@ "advancement.hexcasting:lore": "Hexcasting Lore", "advancement.hexcasting:lore.desc": "Read a Lore Fragment", "advancement.hexcasting:lore/terabithia1": "Terabithia Steles", - "advancement.hexcasting:lore/terabithia1.desc": "Letter from Terabithia Steles to Her Father, #2", + "advancement.hexcasting:lore/terabithia1.desc": "Letter from Terabithia Steles to Her Father, #1", "advancement.hexcasting:lore/terabithia2": "Terabithia Steles", "advancement.hexcasting:lore/terabithia2.desc": "Letter from Terabithia Steles to Her Father, #2", "advancement.hexcasting:lore/terabithia3": "Terabithia Steles", @@ -195,7 +235,7 @@ "advancement.hexcasting:lore/terabithia4": "Terabithia Steles", "advancement.hexcasting:lore/terabithia4.desc": "Letter from Terabithia Steles to Her Father, #3, 2/2", "advancement.hexcasting:lore/terabithia5": "Terabithia Steles", - "advancement.hexcasting:lore/terabithia5.desc": "Letter from Terabithia Steles to Her Father, #5", + "advancement.hexcasting:lore/terabithia5.desc": "Letter from Terabithia Steles to Her Father, #4", "advancement.hexcasting:lore/experiment1": "Wooleye Instance Notes", "advancement.hexcasting:lore/experiment2": "Wooleye Interview Logs", "advancement.hexcasting:lore/inventory": "Restoration Log 72", diff --git a/Fabric/build.gradle b/Fabric/build.gradle index 9ee65819..6bc7b5db 100644 --- a/Fabric/build.gradle +++ b/Fabric/build.gradle @@ -78,9 +78,6 @@ dependencies { modImplementation "at.petra-k.paucal:paucal-fabric-$minecraftVersion:$paucalVersion" modImplementation "vazkii.patchouli:Patchouli:$minecraftVersion-$patchouliVersion-FABRIC" - modImplementation "me.zeroeightsix:fiber:$fiberVersion" - include "me.zeroeightsix:fiber:$fiberVersion" - modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-api:$cardinalComponentsVersion" modImplementation "com.jamieswhiteshirt:reach-entity-attributes:${entityReachVersion}" @@ -107,7 +104,7 @@ dependencies { // *Something* is including an old version of modmenu with a broken mixin // We can't figure out what it is // so i'm just including a fresher version - modImplementation("com.terraformersmc:modmenu:4.1.0") + modImplementation("com.terraformersmc:modmenu:$modmenuVersion") // i am speed // sodium is causing frustum mixin errors so don't use it diff --git a/Fabric/gradle.properties b/Fabric/gradle.properties index 09ad6fbf..59d27dfd 100644 --- a/Fabric/gradle.properties +++ b/Fabric/gradle.properties @@ -2,7 +2,6 @@ fabricVersion=0.64.0+1.19.2 fabricLoaderVersion=0.14.10 # These are all included -fiberVersion=0.23.0-2 cardinalComponentsVersion=5.0.2 serializationHooksVersion=0.3.24 entityReachVersion=2.3.0 @@ -12,6 +11,8 @@ gravityApiVersion=0.7.12+fabric clothConfigVersion=8.2.88 trinketsVersion=3.4.0 +modmenuVersion=4.1.1 + # Optimizations sodiumVersion=mc1.19.2-0.4.4 lithiumVersion=mc1.19.2-0.10.2 diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java index 7fe04bf9..82c895f7 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java @@ -4,292 +4,192 @@ import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.misc.ScrollQuantity; import at.petrak.hexcasting.api.mod.HexConfig; import at.petrak.hexcasting.xplat.IXplatAbstractions; -import io.github.fablabsmc.fablabs.api.fiber.v1.builder.ConfigTreeBuilder; -import io.github.fablabsmc.fablabs.api.fiber.v1.exception.ValueDeserializationException; -import io.github.fablabsmc.fablabs.api.fiber.v1.schema.type.derived.ConfigTypes; -import io.github.fablabsmc.fablabs.api.fiber.v1.serialization.FiberSerialization; -import io.github.fablabsmc.fablabs.api.fiber.v1.serialization.JanksonValueSerializer; -import io.github.fablabsmc.fablabs.api.fiber.v1.tree.ConfigTree; -import io.github.fablabsmc.fablabs.api.fiber.v1.tree.PropertyMirror; +import me.shedaniel.autoconfig.AutoConfig; +import me.shedaniel.autoconfig.ConfigData; +import me.shedaniel.autoconfig.annotation.Config; +import me.shedaniel.autoconfig.annotation.ConfigEntry; +import me.shedaniel.autoconfig.serializer.JanksonConfigSerializer; +import me.shedaniel.autoconfig.serializer.PartitioningSerializer; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; -import java.io.*; -import java.nio.file.*; import java.util.List; import static at.petrak.hexcasting.api.mod.HexConfig.anyMatch; import static at.petrak.hexcasting.api.mod.HexConfig.noneMatch; -// https://github.com/VazkiiMods/Botania/blob/1.18.x/Fabric/src/main/java/vazkii/botania/fabric/FiberBotaniaConfig.java -public class FabricHexConfig { - private static final Common COMMON = new Common(); - private static final Client CLIENT = new Client(); - private static final Server SERVER = new Server(); +@Config(name = HexAPI.MOD_ID) +@Config.Gui.Background("minecraft:textures/block/calcite.png") +@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"}) - private static void writeDefaultConfig(ConfigTree config, Path path, JanksonValueSerializer serializer) { - try (OutputStream s = new BufferedOutputStream( - Files.newOutputStream(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW))) { - FiberSerialization.serialize(config, s, serializer); - } catch (FileAlreadyExistsException ignored) { - } catch (IOException e) { - HexAPI.LOGGER.error("Error writing default config", e); - } - } - - private static void setupConfig(ConfigTree config, Path p, JanksonValueSerializer serializer) { - writeDefaultConfig(config, p, serializer); - - try (InputStream s = new BufferedInputStream( - Files.newInputStream(p, StandardOpenOption.READ, StandardOpenOption.CREATE))) { - FiberSerialization.deserialize(config, s, serializer); - } catch (IOException | ValueDeserializationException e) { - HexAPI.LOGGER.error("Error loading config from {}", p, e); - } - } +public class FabricHexConfig extends PartitioningSerializer.GlobalData { + @ConfigEntry.Category("common") + @ConfigEntry.Gui.TransitiveObject + private final Common common = new Common(); + @ConfigEntry.Category("client") + @ConfigEntry.Gui.TransitiveObject + private final Client client = new Client(); + @ConfigEntry.Category("server") + @ConfigEntry.Gui.TransitiveObject + private final Server server = new Server(); public static void setup() { - try { - Files.createDirectory(Paths.get("config")); - } catch (FileAlreadyExistsException ignored) { - } catch (IOException e) { - HexAPI.LOGGER.warn("Failed to make config dir", e); - } - - var serializer = new JanksonValueSerializer(false); - var common = COMMON.configure(ConfigTree.builder()); - setupConfig(common, Paths.get("config", HexAPI.MOD_ID + "-common.json5"), serializer); - HexConfig.setCommon(COMMON); + AutoConfig.register(FabricHexConfig.class, PartitioningSerializer.wrap(JanksonConfigSerializer::new)); + var instance = AutoConfig.getConfigHolder(FabricHexConfig.class).getConfig(); + HexConfig.setCommon(instance.common); // We care about the client only on the *physical* client ... if (IXplatAbstractions.INSTANCE.isPhysicalClient()) { - var client = CLIENT.configure(ConfigTree.builder()); - setupConfig(client, Paths.get("config", HexAPI.MOD_ID + "-client.json5"), serializer); - HexConfig.setClient(CLIENT); + HexConfig.setClient(instance.client); } // but we care about the server on the *logical* server // i believe this should Just Work without a guard? assuming we don't access it from the client ever - var server = SERVER.configure(ConfigTree.builder()); - setupConfig(server, Paths.get("config", HexAPI.MOD_ID + "-server.json5"), serializer); - HexConfig.setServer(SERVER); - + HexConfig.setServer(instance.server); } - private static final class Common implements HexConfig.CommonConfigAccess { - private final PropertyMirror dustMediaAmount = PropertyMirror.create(ConfigTypes.NATURAL); - private final PropertyMirror shardMediaAmount = PropertyMirror.create(ConfigTypes.NATURAL); - private final PropertyMirror chargedCrystalMediaAmount = PropertyMirror.create(ConfigTypes.NATURAL); - private final PropertyMirror mediaToHealthRate = PropertyMirror.create( - ConfigTypes.DOUBLE.withMinimum(0d)); + @Config(name = "common") + private static final class Common implements HexConfig.CommonConfigAccess, ConfigData { + @ConfigEntry.Gui.Tooltip + private int dustMediaAmount = DEFAULT_DUST_MEDIA_AMOUNT; + @ConfigEntry.Gui.Tooltip + private int shardMediaAmount = DEFAULT_SHARD_MEDIA_AMOUNT; + @ConfigEntry.Gui.Tooltip + private int chargedCrystalMediaAmount = DEFAULT_CHARGED_MEDIA_AMOUNT; + @ConfigEntry.Gui.Tooltip + private double mediaToHealthRate = DEFAULT_MEDIA_TO_HEALTH_RATE; - public ConfigTree configure(ConfigTreeBuilder bob) { - bob.fork("Media Amounts") - .beginValue("dustMediaAmount", ConfigTypes.NATURAL, DEFAULT_DUST_MEDIA_AMOUNT) - .withComment("How much media a single Amethyst Dust item is worth") - .finishValue(dustMediaAmount::mirror) - - .beginValue("shardMediaAmount", ConfigTypes.NATURAL, DEFAULT_SHARD_MEDIA_AMOUNT) - .withComment("How much media a single Amethyst Shard item is worth") - .finishValue(shardMediaAmount::mirror) - - .beginValue("chargedCrystalMediaAmount", ConfigTypes.NATURAL, DEFAULT_CHARGED_MEDIA_AMOUNT) - .withComment("How much media a single Charged Amethyst Crystal item is worth") - .finishValue(chargedCrystalMediaAmount::mirror) - - .beginValue("mediaToHealthRate", ConfigTypes.DOUBLE, DEFAULT_MEDIA_TO_HEALTH_RATE) - .withComment("How many points of media a half-heart is worth when casting from HP") - .finishValue(mediaToHealthRate::mirror) - .finishBranch(); - - return bob.build(); + @Override + public void validatePostLoad() throws ValidationException { + this.dustMediaAmount = Math.max(this.dustMediaAmount, 0); + this.shardMediaAmount = Math.max(this.shardMediaAmount, 0); + this.chargedCrystalMediaAmount = Math.max(this.chargedCrystalMediaAmount, 0); + this.mediaToHealthRate = Math.max(this.mediaToHealthRate, 0); } @Override public int dustMediaAmount() { - return dustMediaAmount.getValue(); + return dustMediaAmount; } @Override public int shardMediaAmount() { - return shardMediaAmount.getValue(); + return shardMediaAmount; } @Override public int chargedCrystalMediaAmount() { - return chargedCrystalMediaAmount.getValue(); + return chargedCrystalMediaAmount; } @Override public double mediaToHealthRate() { - return mediaToHealthRate.getValue(); + return mediaToHealthRate; } } - private static final class Client implements HexConfig.ClientConfigAccess { - private final PropertyMirror patternPointSpeedMultiplier = PropertyMirror.create( - ConfigTypes.DOUBLE.withMinimum(0d)); - private final PropertyMirror ctrlTogglesOffStrokeOrder = PropertyMirror.create(ConfigTypes.BOOLEAN); - private final PropertyMirror invertSpellbookScrollDirection = PropertyMirror.create(ConfigTypes.BOOLEAN); - private final PropertyMirror invertAbacusScrollDirection = PropertyMirror.create(ConfigTypes.BOOLEAN); - private final PropertyMirror gridSnapThreshold = PropertyMirror.create( - ConfigTypes.DOUBLE.withMinimum(0.5).withMaximum(1.0)); - - public ConfigTree configure(ConfigTreeBuilder bob) { - bob - .beginValue("patternPointSpeedMultiplier", ConfigTypes.DOUBLE, DEFAULT_PATTERN_POINT_SPEED_MULTIPLIER) - .withComment("How fast the point showing you the stroke order on patterns moves. Must be positive.") - .finishValue(patternPointSpeedMultiplier::mirror) - - .beginValue("ctrlTogglesOffStrokeOrder", ConfigTypes.BOOLEAN, DEFAULT_CTRL_TOGGLES_OFF_STROKE_ORDER) - .withComment("Whether the ctrl key will instead turn *off* the color gradient on patterns") - .finishValue(ctrlTogglesOffStrokeOrder::mirror) - - .beginValue("invertSpellbookScrollDirection", ConfigTypes.BOOLEAN, DEFAULT_INVERT_SPELLBOOK_SCROLL) - .withComment("Whether scrolling up (as opposed to down) will increase the page index of the spellbook, and vice versa") - .finishValue(invertSpellbookScrollDirection::mirror) - - .beginValue("invertAbacusScrollDirection", ConfigTypes.BOOLEAN, DEFAULT_INVERT_ABACUS_SCROLL) - .withComment("Whether scrolling up (as opposed to down) will increase the value of the abacus, and vice versa") - .finishValue(invertAbacusScrollDirection::mirror) - - .beginValue("gridSnapThreshold", ConfigTypes.DOUBLE, DEFAULT_GRID_SNAP_THRESHOLD) - .withComment( - "When using a staff, the distance from one dot you have to go to snap to the next dot, where 0.5 means 50% of the way. Valid range is 0.5 to 1.0, and may cause client crashes if set above or below those values.") - .finishValue(gridSnapThreshold::mirror); - - return bob.build(); - } + @Config(name = "client") + private static final class Client implements HexConfig.ClientConfigAccess, ConfigData { + @ConfigEntry.Gui.Tooltip + private boolean ctrlTogglesOffStrokeOrder = DEFAULT_CTRL_TOGGLES_OFF_STROKE_ORDER; + @ConfigEntry.Gui.Tooltip + private boolean invertSpellbookScrollDirection = DEFAULT_INVERT_SPELLBOOK_SCROLL; + @ConfigEntry.Gui.Tooltip + private boolean invertAbacusScrollDirection = DEFAULT_INVERT_SPELLBOOK_SCROLL; + @ConfigEntry.Gui.Tooltip + private double gridSnapThreshold = DEFAULT_GRID_SNAP_THRESHOLD; @Override - public double patternPointSpeedMultiplier() { - return patternPointSpeedMultiplier.getValue(); + public void validatePostLoad() throws ValidationException { + this.gridSnapThreshold = Mth.clamp(this.gridSnapThreshold, 0.5, 1.0); } @Override public boolean ctrlTogglesOffStrokeOrder() { - return ctrlTogglesOffStrokeOrder.getValue(); + return ctrlTogglesOffStrokeOrder; } @Override public boolean invertSpellbookScrollDirection() { - return invertSpellbookScrollDirection.getValue(); + return invertSpellbookScrollDirection; } @Override public boolean invertAbacusScrollDirection() { - return invertAbacusScrollDirection.getValue(); + return invertAbacusScrollDirection; } @Override public double gridSnapThreshold() { - return gridSnapThreshold.getValue(); + return gridSnapThreshold; } } - private static final class Server implements HexConfig.ServerConfigAccess { - private final PropertyMirror opBreakHarvestLevel = PropertyMirror.create( - ConfigTypes.INTEGER.withValidRange(0, 4, 1)); - private final PropertyMirror maxRecurseDepth = PropertyMirror.create(ConfigTypes.NATURAL); - private final PropertyMirror maxSpellCircleLength = PropertyMirror.create( - ConfigTypes.INTEGER.withMinimum(4)); - private final PropertyMirror> actionDenyList = PropertyMirror.create( - ConfigTypes.makeList(ConfigTypes.STRING)); - private final PropertyMirror> circleActionDenyList = PropertyMirror.create( - ConfigTypes.makeList(ConfigTypes.STRING)); - private final PropertyMirror villagersOffendedByMindMurder = PropertyMirror.create( - ConfigTypes.BOOLEAN); - private final PropertyMirror> fewScrollTables = PropertyMirror.create( - ConfigTypes.makeList(ConfigTypes.STRING)); - private final PropertyMirror> someScrollTables = PropertyMirror.create( - ConfigTypes.makeList(ConfigTypes.STRING)); - private final PropertyMirror> manyScrollTables = PropertyMirror.create( - ConfigTypes.makeList(ConfigTypes.STRING)); + @Config(name = "server") + private static final class Server implements HexConfig.ServerConfigAccess, ConfigData { + @ConfigEntry.BoundedDiscrete(min = 0, max = 4) + @ConfigEntry.Gui.Tooltip + private int opBreakHarvestLevel = DEFAULT_OP_BREAK_HARVEST_LEVEL; + @ConfigEntry.Gui.Tooltip + private int maxRecurseDepth = DEFAULT_MAX_RECURSE_DEPTH; + @ConfigEntry.Gui.Tooltip + private int maxSpellCircleLength = DEFAULT_MAX_SPELL_CIRCLE_LENGTH; + @ConfigEntry.Gui.Tooltip + private List actionDenyList = List.of(); + @ConfigEntry.Gui.Tooltip + private List circleActionDenyList = List.of(); + @ConfigEntry.Gui.Tooltip + private boolean villagersOffendedByMindMurder = DEFAULT_VILLAGERS_DISLIKE_MIND_MURDER; - public ConfigTree configure(ConfigTreeBuilder bob) { - bob.fork("Spells") - .beginValue("maxRecurseDepth", ConfigTypes.NATURAL, DEFAULT_MAX_RECURSE_DEPTH) - .withComment("How many times a spell can recursively cast other spells") - .finishValue(maxRecurseDepth::mirror) + @ConfigEntry.Gui.Tooltip + private List fewScrollTables = DEFAULT_FEW_SCROLL_TABLES; + @ConfigEntry.Gui.Tooltip + private List someScrollTables = DEFAULT_SOME_SCROLL_TABLES; + @ConfigEntry.Gui.Tooltip + private List manyScrollTables = DEFAULT_MANY_SCROLL_TABLES; - .beginValue("opBreakHarvestLevel", ConfigTypes.NATURAL, DEFAULT_OP_BREAK_HARVEST_LEVEL) - .withComment("The harvest level of the Break Block spell.\n" + - "0 = wood, 1 = stone, 2 = iron, 3 = diamond, 4 = netherite.") - .finishValue(opBreakHarvestLevel::mirror) - .finishBranch() - - .fork("Spell Circles") - .beginValue("maxSpellCircleLength", ConfigTypes.NATURAL, DEFAULT_MAX_SPELL_CIRCLE_LENGTH) - .withComment("The maximum number of slates in a spell circle. Must be at least 4.") - .finishValue(maxSpellCircleLength::mirror) - - .beginValue("circleActionDenyList", ConfigTypes.makeList(ConfigTypes.STRING), List.of()) - .withComment( - "Resource locations of disallowed actions within circles. Trying to cast one of these in a circle will result in a mishap.") - .finishValue(circleActionDenyList::mirror) - .finishBranch() - - .beginValue("actionDenyList", ConfigTypes.makeList(ConfigTypes.STRING), List.of()) - .withComment( - "Resource locations of disallowed actions. Trying to cast one of these will result in a mishap.") - .finishValue(actionDenyList::mirror) - - .beginValue("villagersOffendedByMindMurder", ConfigTypes.BOOLEAN, true) - .withComment("Should villagers take offense when you flay the mind of their fellow villagers?") - .finishValue(villagersOffendedByMindMurder::mirror) - - .fork("Scrolls in Loot") - .beginValue("fewScrollTables", ConfigTypes.makeList(ConfigTypes.STRING), DEFAULT_FEW_SCROLL_TABLES) - .withComment("Which loot tables should a small number of Ancient Scrolls be injected into?") - .finishValue(fewScrollTables::mirror) - - .beginValue("someScrollTables", ConfigTypes.makeList(ConfigTypes.STRING), DEFAULT_SOME_SCROLL_TABLES) - .withComment("Which loot tables should a decent number of Ancient Scrolls be injected into?") - .finishValue(someScrollTables::mirror) - - .beginValue("manyScrollTables", ConfigTypes.makeList(ConfigTypes.STRING), DEFAULT_MANY_SCROLL_TABLES) - .withComment("Which loot tables should a huge number of Ancient Scrolls be injected into?") - .finishValue(manyScrollTables::mirror) - .finishBranch(); - - return bob.build(); + @Override + public void validatePostLoad() throws ValidationException { + this.maxRecurseDepth = Math.max(this.maxRecurseDepth, 0); + this.maxSpellCircleLength = Math.max(this.maxSpellCircleLength, 4); } @Override public int opBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort() { - return opBreakHarvestLevel.getValue(); + return opBreakHarvestLevel; } @Override public int maxRecurseDepth() { - return maxRecurseDepth.getValue(); + return maxRecurseDepth; } @Override public int maxSpellCircleLength() { - return maxSpellCircleLength.getValue(); + return maxSpellCircleLength; } @Override public boolean isActionAllowed(ResourceLocation actionID) { - return noneMatch(actionDenyList.getValue(), actionID); + return noneMatch(actionDenyList, actionID); } @Override public boolean isActionAllowedInCircles(ResourceLocation actionID) { - return noneMatch(circleActionDenyList.getValue(), actionID); + return noneMatch(circleActionDenyList, actionID); } @Override public boolean doVillagersTakeOffenseAtMindMurder() { - return villagersOffendedByMindMurder.getValue(); + return villagersOffendedByMindMurder; } @Override public ScrollQuantity scrollsForLootTable(ResourceLocation lootTable) { - if (anyMatch(fewScrollTables.getValue(), lootTable)) { + if (anyMatch(fewScrollTables, lootTable)) { return ScrollQuantity.FEW; - } else if (anyMatch(someScrollTables.getValue(), lootTable)) { + } else if (anyMatch(someScrollTables, lootTable)) { return ScrollQuantity.SOME; - } else if (anyMatch(manyScrollTables.getValue(), lootTable)) { + } else if (anyMatch(manyScrollTables, lootTable)) { return ScrollQuantity.MANY; } return ScrollQuantity.NONE; diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/interop/ModMenuInterop.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/interop/ModMenuInterop.java new file mode 100644 index 00000000..39b6586d --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/interop/ModMenuInterop.java @@ -0,0 +1,16 @@ +package at.petrak.hexcasting.fabric.interop; + +import at.petrak.hexcasting.fabric.FabricHexConfig; +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; +import me.shedaniel.autoconfig.AutoConfig; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class ModMenuInterop implements ModMenuApi { + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return parent -> AutoConfig.getConfigScreen(FabricHexConfig.class, parent).get(); + } +} diff --git a/Fabric/src/main/resources/fabric.mod.json b/Fabric/src/main/resources/fabric.mod.json index 74daa54f..4aa0be25 100644 --- a/Fabric/src/main/resources/fabric.mod.json +++ b/Fabric/src/main/resources/fabric.mod.json @@ -2,7 +2,6 @@ "schemaVersion": 1, "id": "hexcasting", "version": "${version}", - "name": "Hex Casting", "description": "Cast powerful Hexes on the fly by drawing patterns with a staff.", "authors": [ @@ -12,17 +11,21 @@ "homepage": "https://www.curseforge.com/minecraft/mc-mods/hexcasting", "sources": "https://github.com/gamma-delta/HexMod" }, - "license": "MIT", "icon": "logo.png", - "environment": "*", "entrypoints": { "main": [ - {"adapter": "kotlin", "value": "at.petrak.hexcasting.fabric.FabricHexInitializer"} + { + "adapter": "kotlin", + "value": "at.petrak.hexcasting.fabric.FabricHexInitializer" + } ], "client": [ - {"adapter": "kotlin", "value": "at.petrak.hexcasting.fabric.FabricHexClientInitializer"} + { + "adapter": "kotlin", + "value": "at.petrak.hexcasting.fabric.FabricHexClientInitializer" + } ], "fabric-datagen": [ "at.petrak.hexcasting.fabric.datagen.HexFabricDataGenerators" @@ -32,6 +35,9 @@ ], "emi": [ "at.petrak.hexcasting.fabric.interop.emi.HexEMIPlugin" + ], + "modmenu": [ + "at.petrak.hexcasting.fabric.interop.ModMenuInterop" ] }, "mixins": [ @@ -39,15 +45,12 @@ "fabricasting.mixins.json" ], "accessWidener": "fabricasting.accesswidener", - "depends": { "minecraft": "=1.19.2", "java": ">=17", - "fabricloader": ">=0.14", "fabric": ">=0.64", "fabric-language-kotlin": ">=1.7.4+kotlin.1.6.21", - "patchouli": ">=1.19.2-77", "paucal": "0.5.x" }, @@ -55,7 +58,6 @@ "gravitychanger": "0.7.21+fabric", "pehkui": "3.6.0+1.14.4-1.19" }, - "custom": { "cardinal-components": [ "hexcasting:brainswept", @@ -64,7 +66,6 @@ "hexcasting:flight", "hexcasting:harness", "hexcasting:patterns", - "hexcasting:colorizer", "hexcasting:iota_holder", "hexcasting:media_holder", diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java b/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java index 2f823c6e..d58fb684 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java @@ -50,28 +50,25 @@ public class ForgeHexConfig implements HexConfig.CommonConfigAccess { } public static class Client implements HexConfig.ClientConfigAccess { - private static ForgeConfigSpec.DoubleValue patternPointSpeedMultiplier; private static ForgeConfigSpec.BooleanValue ctrlTogglesOffStrokeOrder; private static ForgeConfigSpec.BooleanValue invertSpellbookScrollDirection; private static ForgeConfigSpec.BooleanValue invertAbacusScrollDirection; private static ForgeConfigSpec.DoubleValue gridSnapThreshold; public Client(ForgeConfigSpec.Builder builder) { - patternPointSpeedMultiplier = builder.comment( - "How fast the point showing you the stroke order on patterns moves") - .defineInRange("patternPointSpeedMultiplier", DEFAULT_PATTERN_POINT_SPEED_MULTIPLIER, 0.0, - Double.POSITIVE_INFINITY); ctrlTogglesOffStrokeOrder = builder.comment( "Whether the ctrl key will instead turn *off* the color gradient on patterns") .define("ctrlTogglesOffStrokeOrder", DEFAULT_CTRL_TOGGLES_OFF_STROKE_ORDER); invertSpellbookScrollDirection = builder.comment( - "Whether scrolling up (as opposed to down) will increase the page index of the spellbook, and vice versa") + "Whether scrolling up (as opposed to down) will increase the page index of the spellbook, and " + + "vice versa") .define("invertSpellbookScrollDirection", DEFAULT_INVERT_SPELLBOOK_SCROLL); invertAbacusScrollDirection = builder.comment( "Whether scrolling up (as opposed to down) will increase the value of the abacus, and vice versa") .define("invertAbacusScrollDirection", DEFAULT_INVERT_ABACUS_SCROLL); gridSnapThreshold = builder.comment( - "When using a staff, the distance from one dot you have to go to snap to the next dot, where 0.5 means 50% of the way.") + "When using a staff, the distance from one dot you have to go to snap to the next dot, where 0.5 " + + "means 50% of the way.") .defineInRange("gridSnapThreshold", DEFAULT_GRID_SNAP_THRESHOLD, 0.5, 1.0); } @@ -85,11 +82,6 @@ public class ForgeHexConfig implements HexConfig.CommonConfigAccess { return invertAbacusScrollDirection.get(); } - @Override - public double patternPointSpeedMultiplier() { - return patternPointSpeedMultiplier.get(); - } - @Override public boolean ctrlTogglesOffStrokeOrder() { return ctrlTogglesOffStrokeOrder.get(); @@ -131,7 +123,8 @@ public class ForgeHexConfig implements HexConfig.CommonConfigAccess { .defineInRange("maxSpellCircleLength", DEFAULT_MAX_SPELL_CIRCLE_LENGTH, 4, Integer.MAX_VALUE); circleActionDenyList = builder.comment( - "Resource locations of disallowed actions within circles. Trying to cast one of these in a circle will result in a mishap.") + "Resource locations of disallowed actions within circles. Trying to cast one of these in a circle" + + " will result in a mishap.") .defineList("circleActionDenyList", List.of(), obj -> obj instanceof String s && ResourceLocation.isValidResourceLocation(s)); builder.pop(); @@ -210,7 +203,8 @@ public class ForgeHexConfig implements HexConfig.CommonConfigAccess { // then we are in develop env AND this is being called in the new world screen (it loads datapacks for // world generation options) // config values don't exist yet because config is per-world on Forge, and in dev it throws an exn - // (in release it just silently returns default, which is expected behavior here, but the comment suggests + // (in release it just silently returns default, which is expected behavior here, but the comment + // suggests // it will start throwing at some point soon.) } return ScrollQuantity.NONE;