possibly, maybe, get config working as a warmup

This commit is contained in:
gamma-delta 2022-04-25 15:52:03 -05:00
parent 7f71e146c5
commit 0938673eb8
12 changed files with 464 additions and 90 deletions

View file

@ -1,87 +1,105 @@
package at.petrak.hexcasting.api.mod;
import at.petrak.hexcasting.api.HexAPI;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Tier;
import net.minecraft.world.item.Tiers;
import net.minecraftforge.common.ForgeConfigSpec;
import java.util.List;
public class HexConfig {
public static ForgeConfigSpec.IntValue dustManaAmount;
public static ForgeConfigSpec.IntValue shardManaAmount;
public static ForgeConfigSpec.IntValue chargedCrystalManaAmount;
public static ForgeConfigSpec.DoubleValue manaToHealthRate;
public interface CommonConfigAccess {
int dustManaAmount();
int shardManaAmount();
int chargedCrystalManaAmount();
double manaToHealthRate();
int DEFAULT_DUST_MANA_AMOUNT = 10_000;
int DEFAULT_SHARD_MANA_AMOUNT = 50_000;
int DEFAULT_CHARGED_MANA_AMOUNT = 100_000;
double DEFAULT_MANA_TO_HEALTH_RATE = 200_000.0 / 20.0;
public HexConfig(ForgeConfigSpec.Builder builder) {
builder.push("Mana Amounts");
dustManaAmount = builder.comment("How much mana a single Amethyst Dust item is worth")
.defineInRange("dustManaAmount", 10_000, 0, Integer.MAX_VALUE);
shardManaAmount = builder.comment("How much mana a single Amethyst Shard item is worth")
.defineInRange("shardManaAmount", 50_000, 0, Integer.MAX_VALUE);
chargedCrystalManaAmount = builder.comment("How much mana a single Charged Amethyst Crystal item is worth")
.defineInRange("chargedCrystalManaAmount", 100_000, 0, Integer.MAX_VALUE);
manaToHealthRate = builder.comment("How many points of mana a half-heart is worth when casting from HP")
.defineInRange("manaToHealthRate", 200_000.0 / 20.0, 0.0, Double.POSITIVE_INFINITY);
builder.pop();
}
public static class Client {
public static ForgeConfigSpec.DoubleValue patternPointSpeedMultiplier;
public static ForgeConfigSpec.BooleanValue ctrlTogglesOffStrokeOrder;
public interface ClientConfigAccess {
double patternPointSpeedMultiplier();
public Client(ForgeConfigSpec.Builder builder) {
patternPointSpeedMultiplier = builder.comment(
"How fast the point showing you the stroke order on patterns moves")
.defineInRange("manaToHealthRate", 1.0, 0.0, Double.POSITIVE_INFINITY);
ctrlTogglesOffStrokeOrder = builder.comment(
"Whether the ctrl key will instead turn *off* the color gradient on patterns")
.define("ctrlTogglesOffStrokeOrder", false);
}
boolean ctrlTogglesOffStrokeOrder();
double DEFAULT_PATTERN_POINT_SPEED_MULTIPLIER = 1;
boolean DEFAULT_CTRL_TOGGLES_OFF_STROKE_ORDER = false;
}
public static class Server {
public static ForgeConfigSpec.IntValue opBreakHarvestLevel;
public static ForgeConfigSpec.IntValue maxRecurseDepth;
public interface ServerConfigAccess {
int opBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort();
public static ForgeConfigSpec.IntValue maxSpellCircleLength;
int maxRecurseDepth();
public static ForgeConfigSpec.ConfigValue<List<? extends String>> actionDenyList;
int maxSpellCircleLength();
public Server(ForgeConfigSpec.Builder builder) {
builder.push("Spells");
maxRecurseDepth = builder.comment("How many times a spell can recursively cast other spells")
.defineInRange("maxRecurseDepth", 64, 0, Integer.MAX_VALUE);
opBreakHarvestLevel = builder.comment(
"The harvest level of the Break Block spell.",
"0 = wood, 1 = stone, 2 = iron, 3 = diamond, 4 = netherite."
).defineInRange("opBreakHarvestLevel", 3, 0, 4);
builder.pop();
boolean isActionAllowed(ResourceLocation actionID);
builder.push("Spell Circles");
maxSpellCircleLength = builder.comment("The maximum number of slates in a spell circle")
.defineInRange("maxSpellCircleLength", 256, 4, Integer.MAX_VALUE);
builder.pop();
int DEFAULT_MAX_RECURSE_DEPTH = 64;
int DEFAULT_MAX_SPELL_CIRCLE_LENGTH = 1024;
int DEFAULT_OP_BREAK_HARVEST_LEVEL = 3;
// We can't have default values for the break harvest level or if
actionDenyList = builder.comment(
"Resource locations of disallowed actions. Trying to cast one of these will result in a mishap.")
.defineList("actionDenyList", List.of(),
obj -> obj instanceof String s && ResourceLocation.isValidResourceLocation(s));
}
/**
* i'm not kidding look upon net.minecraftforge.common.TierSortingRegistry and weep
*/
public static Tier getOpBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort() {
return switch (opBreakHarvestLevel.get()) {
default Tier opBreakHarvestLevel() {
return switch (this.opBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort()) {
case 0 -> Tiers.WOOD;
case 1 -> Tiers.STONE;
case 2 -> Tiers.IRON;
case 3 -> Tiers.DIAMOND;
case 4 -> Tiers.NETHERITE;
default -> throw new RuntimeException("unreachable");
default -> throw new RuntimeException("please only return a value in 0<=x<=4");
};
}
}
// oh man this is aesthetically pleasing
private static CommonConfigAccess common = null;
private static ClientConfigAccess client = null;
private static ServerConfigAccess server = null;
public static CommonConfigAccess common() {
return common;
}
public static ClientConfigAccess client() {
return client;
}
public static ServerConfigAccess server() {
return server;
}
public static void setCommon(CommonConfigAccess access) {
if (common != null) {
HexAPI.LOGGER.warn("CommonConfigAccess was replaced! Old {} New {}",
common.getClass().getName(), access.getClass().getName());
}
common = access;
}
public static void setClient(ClientConfigAccess access) {
if (client != null) {
HexAPI.LOGGER.warn("ClientConfigAccess was replaced! Old {} New {}",
client.getClass().getName(), access.getClass().getName());
}
client = access;
}
public static void setServer(ServerConfigAccess access) {
if (server != null) {
HexAPI.LOGGER.warn("ServerConfigAccess was replaced! Old {} New {}",
server.getClass().getName(), access.getClass().getName());
}
server = access;
}
}

View file

@ -1,19 +1,29 @@
package at.petrak.hexcasting.xplat;
import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.common.command.PatternResLocArgument;
import net.minecraft.commands.synchronization.ArgumentTypes;
import net.minecraft.commands.synchronization.EmptyArgumentSerializer;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
public interface IXplatAbstractions {
default Platform platform() {
return Platform.UNKNOWN;
}
Platform platform();
boolean isPhysicalClient();
default void init() {
HexAPI.LOGGER.info("Hello Hexcasting! This is {}!", this.platform());
ArgumentTypes.register(
"hexcasting:pattern",
PatternResLocArgument.class,
new EmptyArgumentSerializer<>(PatternResLocArgument::id)
);
}
IXplatAbstractions INSTANCE = find();
private static IXplatAbstractions find() {

View file

@ -1,5 +1,5 @@
package at.petrak.hexcasting.xplat;
public enum Platform {
UNKNOWN, FORGE, FABRIC
FORGE, FABRIC
}

View file

@ -6,6 +6,11 @@ plugins {
archivesBaseName = "${modName}-fabric-${minecraftVersion}"
repositories {
mavenCentral()
maven { url "https://maven.shedaniel.me/" }
}
dependencies {
minecraft "com.mojang:minecraft:${minecraftVersion}"
mappings loom.officialMojangMappings()
@ -20,6 +25,7 @@ dependencies {
modImplementation("vazkii.patchouli:Patchouli:$minecraftVersion-$patchouliVersion:api")
modImplementation("net.fabricmc:fabric-language-kotlin:1.7.4+kotlin.1.6.21")
implementation "me.zeroeightsix:fiber:$fiberVersion"
}
loom {
@ -75,6 +81,3 @@ publishing {
}
}
}
repositories {
mavenCentral()
}

1
Fabric/gradle.properties Normal file
View file

@ -0,0 +1 @@
fiberVersion=0.23.0-2

View file

@ -1,8 +1,11 @@
import at.petrak.hexcasting.fabric.FabricHexConfig
import at.petrak.hexcasting.xplat.IXplatAbstractions
import net.fabricmc.api.ModInitializer
object HexMod : ModInitializer {
override fun onInitialize() {
IXplatAbstractions.INSTANCE.init()
FabricHexConfig.setup()
}
}

View file

@ -0,0 +1,203 @@
package at.petrak.hexcasting.fabric;
import at.petrak.hexcasting.api.HexAPI;
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 net.minecraft.resources.ResourceLocation;
import java.io.*;
import java.nio.file.*;
import java.util.List;
// https://github.com/VazkiiMods/Botania/blob/1.18.x/Fabric/src/main/java/vazkii/botania/fabric/FiberBotaniaConfig.java
public class FabricHexConfig {
private static Common COMMON;
private static Client CLIENT;
private static Server SERVER;
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 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);
if (IXplatAbstractions.INSTANCE.isPhysicalClient()) {
var client = CLIENT.configure(ConfigTree.builder());
setupConfig(client, Paths.get("config", HexAPI.MOD_ID + "-client.json5"), serializer);
HexConfig.setClient(CLIENT);
} else {
var server = SERVER.configure(ConfigTree.builder());
setupConfig(server, Paths.get("config", HexAPI.MOD_ID + "-client.json5"), serializer);
HexConfig.setServer(SERVER);
}
}
private static final class Common implements HexConfig.CommonConfigAccess {
private final PropertyMirror<Integer> dustManaAmount = PropertyMirror.create(ConfigTypes.NATURAL);
private final PropertyMirror<Integer> shardManaAmount = PropertyMirror.create(ConfigTypes.NATURAL);
private final PropertyMirror<Integer> chargedCrystalManaAmount = PropertyMirror.create(ConfigTypes.NATURAL);
private final PropertyMirror<Double> manaToHealthRate = PropertyMirror.create(
ConfigTypes.DOUBLE.withMinimum(0d));
public ConfigTree configure(ConfigTreeBuilder bob) {
bob.fork("Mana Amounts")
.beginValue("dustManaAmount", ConfigTypes.NATURAL, DEFAULT_DUST_MANA_AMOUNT)
.withComment("How much mana a single Amethyst Dust item is worth")
.finishValue(dustManaAmount::mirror)
.beginValue("shardManaAmount", ConfigTypes.NATURAL, DEFAULT_SHARD_MANA_AMOUNT)
.withComment("How much mana a single Amethyst Shard item is worth")
.finishValue(shardManaAmount::mirror)
.beginValue("chargedCrystalManaAmount", ConfigTypes.NATURAL, DEFAULT_CHARGED_MANA_AMOUNT)
.withComment("How much mana a single Charged Amethyst Crystal item is worth")
.finishValue(chargedCrystalManaAmount::mirror)
.beginValue("manaToHealthRate", ConfigTypes.DOUBLE, DEFAULT_MANA_TO_HEALTH_RATE)
.withComment("How many points of mana a half-heart is worth when casting from HP")
.finishValue(manaToHealthRate::mirror)
.finishBranch();
return bob.build();
}
@Override
public int dustManaAmount() {
return dustManaAmount.getValue();
}
@Override
public int shardManaAmount() {
return shardManaAmount.getValue();
}
@Override
public int chargedCrystalManaAmount() {
return chargedCrystalManaAmount.getValue();
}
@Override
public double manaToHealthRate() {
return manaToHealthRate.getValue();
}
}
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);
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")
.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);
return bob.build();
}
@Override
public double patternPointSpeedMultiplier() {
return patternPointSpeedMultiplier.getValue();
}
@Override
public boolean ctrlTogglesOffStrokeOrder() {
return ctrlTogglesOffStrokeOrder.getValue();
}
}
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));
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)
.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")
.finishValue(maxSpellCircleLength::mirror)
.finishBranch()
.beginValue("actionDenyList", ConfigTypes.makeList(ConfigTypes.STRING), List.of())
.withComment("The maximum number of slates in a spell circle")
.finishValue(actionDenyList::mirror);
return bob.build();
}
@Override
public int opBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort() {
return opBreakHarvestLevel.getValue();
}
@Override
public int maxRecurseDepth() {
return maxRecurseDepth.getValue();
}
@Override
public int maxSpellCircleLength() {
return maxSpellCircleLength.getValue();
}
@Override
public boolean isActionAllowed(ResourceLocation actionID) {
return actionDenyList.getValue().contains(actionID.toString());
}
}
}

View file

@ -2,10 +2,17 @@ package at.petrak.hexcasting.fabric.xplat;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import at.petrak.hexcasting.xplat.Platform;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
public class FabricXplatImpl implements IXplatAbstractions {
@Override
public Platform platform() {
return Platform.FABRIC;
}
@Override
public boolean isPhysicalClient() {
return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT;
}
}

View file

@ -1,12 +1,13 @@
buildscript {
ext.kotlin_version = '1.6.21'
repositories {
maven { url = 'https://maven.minecraftforge.net' }
mavenCentral()
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
// OPTIONAL Kotlin Serialization plugin
classpath 'org.jetbrains.kotlin:kotlin-serialization:1.6.10'
}
}
apply plugin: 'java'
@ -24,6 +25,7 @@ buildscript {
classpath 'org.jetbrains.kotlin:kotlin-serialization:1.6.10'
}
}
apply plugin: 'kotlin'
// OPTIONAL Kotlin Serialization plugin
apply plugin: 'kotlinx-serialization'
@ -120,6 +122,7 @@ dependencies {
// that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
minecraft "net.minecraftforge:forge:${minecraftVersion}-${forgeVersion}"
compileOnly project(":Common")
annotationProcessor 'org.spongepowered:mixin:0.8.5:processor'

View file

@ -1,5 +1,6 @@
package at.petrak.hexcasting
import at.petrak.hexcasting.api.HexAPI
import at.petrak.hexcasting.api.PatternRegistry
import at.petrak.hexcasting.api.advancements.HexAdvancementTriggers
import at.petrak.hexcasting.api.mod.HexConfig
@ -11,7 +12,6 @@ import at.petrak.hexcasting.common.blocks.HexBlocks
import at.petrak.hexcasting.common.casting.RegisterPatterns
import at.petrak.hexcasting.common.casting.operators.spells.great.OpFlight
import at.petrak.hexcasting.common.command.HexCommands
import at.petrak.hexcasting.common.command.PatternResLocArgument
import at.petrak.hexcasting.common.entities.HexEntities
import at.petrak.hexcasting.common.items.HexItems
import at.petrak.hexcasting.common.lib.HexCapabilityHandler
@ -24,9 +24,9 @@ import at.petrak.hexcasting.common.recipe.HexCustomRecipes
import at.petrak.hexcasting.common.recipe.HexRecipeSerializers
import at.petrak.hexcasting.datagen.HexDataGenerators
import at.petrak.hexcasting.datagen.lootmods.HexLootModifiers
import at.petrak.hexcasting.forge.ForgeHexConfig
import at.petrak.hexcasting.server.TickScheduler
import net.minecraft.commands.synchronization.ArgumentTypes
import net.minecraft.commands.synchronization.EmptyArgumentSerializer
import at.petrak.hexcasting.xplat.IXplatAbstractions
import net.minecraftforge.api.distmarker.Dist
import net.minecraftforge.common.ForgeConfigSpec
import net.minecraftforge.eventbus.api.SubscribeEvent
@ -36,29 +36,26 @@ import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.config.ModConfig
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent
import org.apache.logging.log4j.Logger
@Mod(HexMod.MOD_ID)
object HexMod {
val CONFIG_SPEC: ForgeConfigSpec
val SERVER_CONFIG_SPEC: ForgeConfigSpec
val CLIENT_CONFIG_SPEC: ForgeConfigSpec
// mumblemumble thanks shy mumble mumble
const val MOD_ID = "hexcasting"
init {
CONFIG_SPEC = ForgeConfigSpec.Builder()
.configure { builder: ForgeConfigSpec.Builder? -> HexConfig(builder) }.right
SERVER_CONFIG_SPEC = ForgeConfigSpec.Builder()
.configure { builder: ForgeConfigSpec.Builder? -> HexConfig.Server(builder) }.right
CLIENT_CONFIG_SPEC = ForgeConfigSpec.Builder()
.configure { builder: ForgeConfigSpec.Builder? -> HexConfig.Client(builder) }.right
IXplatAbstractions.INSTANCE.init()
ArgumentTypes.register(
"hexcasting:pattern",
PatternResLocArgument::class.java,
EmptyArgumentSerializer(PatternResLocArgument::id)
)
val config = ForgeConfigSpec.Builder()
.configure { builder: ForgeConfigSpec.Builder? -> ForgeHexConfig(builder) }
val serverConfig = ForgeConfigSpec.Builder()
.configure { builder: ForgeConfigSpec.Builder? -> ForgeHexConfig.Server(builder) }
val clientConfig = ForgeConfigSpec.Builder()
.configure { builder: ForgeConfigSpec.Builder? -> ForgeHexConfig.Client(builder) }
HexConfig.setCommon(config.left)
HexConfig.setClient(clientConfig.left)
HexConfig.setServer(serverConfig.left)
// mod lifecycle
val modBus = thedarkcolour.kotlinforforge.forge.MOD_BUS
@ -104,9 +101,9 @@ object HexMod {
// and then things that don't require busses
HexMessages.register()
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, CONFIG_SPEC)
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, SERVER_CONFIG_SPEC)
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, CLIENT_CONFIG_SPEC)
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, config.right)
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, serverConfig.right)
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, clientConfig.right)
}
@SubscribeEvent
@ -115,7 +112,7 @@ object HexMod {
}
@JvmStatic
fun getLogger() = this.LOGGER
fun getLogger(): Logger = HexAPI.LOGGER
@SubscribeEvent
fun printPatternCount(evt: FMLLoadCompleteEvent) {

View file

@ -0,0 +1,122 @@
package at.petrak.hexcasting.forge;
import at.petrak.hexcasting.api.mod.HexConfig;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.common.ForgeConfigSpec;
import java.util.List;
public class ForgeHexConfig implements HexConfig.CommonConfigAccess {
private static ForgeConfigSpec.IntValue dustManaAmount;
private static ForgeConfigSpec.IntValue shardManaAmount;
private static ForgeConfigSpec.IntValue chargedCrystalManaAmount;
private static ForgeConfigSpec.DoubleValue manaToHealthRate;
public ForgeHexConfig(ForgeConfigSpec.Builder builder) {
builder.push("Mana Amounts");
dustManaAmount = builder.comment("How much mana a single Amethyst Dust item is worth")
.defineInRange("dustManaAmount", DEFAULT_DUST_MANA_AMOUNT, 0, Integer.MAX_VALUE);
shardManaAmount = builder.comment("How much mana a single Amethyst Shard item is worth")
.defineInRange("shardManaAmount", DEFAULT_SHARD_MANA_AMOUNT, 0, Integer.MAX_VALUE);
chargedCrystalManaAmount = builder.comment("How much mana a single Charged Amethyst Crystal item is worth")
.defineInRange("chargedCrystalManaAmount", DEFAULT_CHARGED_MANA_AMOUNT, 0, Integer.MAX_VALUE);
manaToHealthRate = builder.comment("How many points of mana a half-heart is worth when casting from HP")
.defineInRange("manaToHealthRate", DEFAULT_MANA_TO_HEALTH_RATE, 0.0, Double.POSITIVE_INFINITY);
builder.pop();
}
@Override
public int dustManaAmount() {
return dustManaAmount.get();
}
@Override
public int shardManaAmount() {
return shardManaAmount.get();
}
@Override
public int chargedCrystalManaAmount() {
return chargedCrystalManaAmount.get();
}
@Override
public double manaToHealthRate() {
return manaToHealthRate.get();
}
public static class Client implements HexConfig.ClientConfigAccess {
private static ForgeConfigSpec.DoubleValue patternPointSpeedMultiplier;
private static ForgeConfigSpec.BooleanValue ctrlTogglesOffStrokeOrder;
public Client(ForgeConfigSpec.Builder builder) {
patternPointSpeedMultiplier = builder.comment(
"How fast the point showing you the stroke order on patterns moves")
.defineInRange("manaToHealthRate", 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);
}
@Override
public double patternPointSpeedMultiplier() {
return patternPointSpeedMultiplier.get();
}
@Override
public boolean ctrlTogglesOffStrokeOrder() {
return ctrlTogglesOffStrokeOrder.get();
}
}
public static class Server implements HexConfig.ServerConfigAccess {
private static ForgeConfigSpec.IntValue opBreakHarvestLevel;
private static ForgeConfigSpec.IntValue maxRecurseDepth;
private static ForgeConfigSpec.IntValue maxSpellCircleLength;
private static ForgeConfigSpec.ConfigValue<List<? extends String>> actionDenyList;
public Server(ForgeConfigSpec.Builder builder) {
builder.push("Spells");
maxRecurseDepth = builder.comment("How many times a spell can recursively cast other spells")
.defineInRange("maxRecurseDepth", DEFAULT_MAX_RECURSE_DEPTH, 0, Integer.MAX_VALUE);
opBreakHarvestLevel = builder.comment(
"The harvest level of the Break Block spell.",
"0 = wood, 1 = stone, 2 = iron, 3 = diamond, 4 = netherite."
).defineInRange("opBreakHarvestLevel", DEFAULT_OP_BREAK_HARVEST_LEVEL, 0, 4);
builder.pop();
builder.push("Spell Circles");
maxSpellCircleLength = builder.comment("The maximum number of slates in a spell circle")
.defineInRange("maxSpellCircleLength", DEFAULT_MAX_SPELL_CIRCLE_LENGTH, 4, Integer.MAX_VALUE);
builder.pop();
actionDenyList = builder.comment(
"Resource locations of disallowed actions. Trying to cast one of these will result in a mishap.")
.defineList("actionDenyList", List.of(),
obj -> obj instanceof String s && ResourceLocation.isValidResourceLocation(s));
}
@Override
public int opBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort() {
return opBreakHarvestLevel.get();
}
@Override
public int maxRecurseDepth() {
return maxRecurseDepth.get();
}
@Override
public int maxSpellCircleLength() {
return maxSpellCircleLength.get();
}
@Override
public boolean isActionAllowed(ResourceLocation actionID) {
return !actionDenyList.get().contains(actionID.toString());
}
}
}

View file

@ -2,10 +2,17 @@ package at.petrak.hexcasting.forge.xplat;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import at.petrak.hexcasting.xplat.Platform;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.loading.FMLLoader;
public class ForgeXplatImpl implements IXplatAbstractions {
@Override
public Platform platform() {
return Platform.FORGE;
}
@Override
public boolean isPhysicalClient() {
return FMLLoader.getDist() == Dist.CLIENT;
}
}