badn't config

This commit is contained in:
petrak@ 2022-11-21 14:07:27 -06:00
parent 138580cbf5
commit 3f9c3a4561
8 changed files with 178 additions and 229 deletions

View file

@ -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<String> DEFAULT_FEW_SCROLL_TABLES = List.of("minecraft:chests/jungle_temple",
"minecraft:chests/simple_dungeon", "minecraft:chests/village/village_cartographer");
List<String> DEFAULT_SOME_SCROLL_TABLES = List.of("minecraft:chests/bastion_treasure",

View file

@ -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",

View file

@ -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

View file

@ -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

View file

@ -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<Integer> dustMediaAmount = PropertyMirror.create(ConfigTypes.NATURAL);
private final PropertyMirror<Integer> shardMediaAmount = PropertyMirror.create(ConfigTypes.NATURAL);
private final PropertyMirror<Integer> chargedCrystalMediaAmount = PropertyMirror.create(ConfigTypes.NATURAL);
private final PropertyMirror<Double> 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<Double> patternPointSpeedMultiplier = PropertyMirror.create(
ConfigTypes.DOUBLE.withMinimum(0d));
private final PropertyMirror<Boolean> ctrlTogglesOffStrokeOrder = PropertyMirror.create(ConfigTypes.BOOLEAN);
private final PropertyMirror<Boolean> invertSpellbookScrollDirection = PropertyMirror.create(ConfigTypes.BOOLEAN);
private final PropertyMirror<Boolean> invertAbacusScrollDirection = PropertyMirror.create(ConfigTypes.BOOLEAN);
private final PropertyMirror<Double> 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<Integer> opBreakHarvestLevel = PropertyMirror.create(
ConfigTypes.INTEGER.withValidRange(0, 4, 1));
private final PropertyMirror<Integer> maxRecurseDepth = PropertyMirror.create(ConfigTypes.NATURAL);
private final PropertyMirror<Integer> maxSpellCircleLength = PropertyMirror.create(
ConfigTypes.INTEGER.withMinimum(4));
private final PropertyMirror<List<String>> actionDenyList = PropertyMirror.create(
ConfigTypes.makeList(ConfigTypes.STRING));
private final PropertyMirror<List<String>> circleActionDenyList = PropertyMirror.create(
ConfigTypes.makeList(ConfigTypes.STRING));
private final PropertyMirror<Boolean> villagersOffendedByMindMurder = PropertyMirror.create(
ConfigTypes.BOOLEAN);
private final PropertyMirror<List<String>> fewScrollTables = PropertyMirror.create(
ConfigTypes.makeList(ConfigTypes.STRING));
private final PropertyMirror<List<String>> someScrollTables = PropertyMirror.create(
ConfigTypes.makeList(ConfigTypes.STRING));
private final PropertyMirror<List<String>> 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<String> actionDenyList = List.of();
@ConfigEntry.Gui.Tooltip
private List<String> 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<String> fewScrollTables = DEFAULT_FEW_SCROLL_TABLES;
@ConfigEntry.Gui.Tooltip
private List<String> someScrollTables = DEFAULT_SOME_SCROLL_TABLES;
@ConfigEntry.Gui.Tooltip
private List<String> 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;

View file

@ -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();
}
}

View file

@ -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",

View file

@ -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;