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 b6ba088a..f4556c01 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 @@ -42,6 +42,8 @@ public class HexConfig { boolean isActionAllowed(ResourceLocation actionID); + boolean isActionAllowedInCircles(ResourceLocation actionID); + int DEFAULT_MAX_RECURSE_DEPTH = 64; int DEFAULT_MAX_SPELL_CIRCLE_LENGTH = 1024; int DEFAULT_OP_BREAK_HARVEST_LEVEL = 3; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/spell/casting/CastingHarness.kt b/Common/src/main/java/at/petrak/hexcasting/api/spell/casting/CastingHarness.kt index 07f684de..f386da90 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/spell/casting/CastingHarness.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/spell/casting/CastingHarness.kt @@ -132,9 +132,6 @@ class CastingHarness private constructor( * handle it functionally. */ fun updateWithPattern(newPat: HexPattern, world: ServerLevel, continuation: SpellContinuation): CastResult { - if (this.ctx.spellCircle == null) - this.ctx.caster.awardStat(HexStatistics.PATTERNS_DRAWN) - var operatorIdPair: Pair? = null try { @@ -142,7 +139,10 @@ class CastingHarness private constructor( operatorIdPair = PatternRegistry.matchPatternAndID(newPat, world) if (!HexConfig.server().isActionAllowed(operatorIdPair.second)) { throw MishapDisallowedSpell() + } else if (this.ctx.spellCircle != null && !HexConfig.server().isActionAllowedInCircles(operatorIdPair.second)) { + throw MishapDisallowedSpell("disallowed_circle") } + val pattern = operatorIdPair.first val unenlightened = pattern.isGreat && !ctx.isCasterEnlightened diff --git a/Common/src/main/java/at/petrak/hexcasting/api/spell/mishaps/MishapDisallowedSpell.kt b/Common/src/main/java/at/petrak/hexcasting/api/spell/mishaps/MishapDisallowedSpell.kt index 4ff6edc4..81123a87 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/spell/mishaps/MishapDisallowedSpell.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/spell/mishaps/MishapDisallowedSpell.kt @@ -6,7 +6,7 @@ import at.petrak.hexcasting.api.spell.casting.CastingContext import at.petrak.hexcasting.api.spell.casting.ResolvedPatternType import net.minecraft.world.item.DyeColor -class MishapDisallowedSpell : Mishap() { +class MishapDisallowedSpell(val type: String = "disallowed") : Mishap() { override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer = dyeColor(DyeColor.BLACK) @@ -17,5 +17,5 @@ class MishapDisallowedSpell : Mishap() { } override fun errorMessage(ctx: CastingContext, errorCtx: Context) = - error("disallowed", actionName(errorCtx.action)) + error(type, actionName(errorCtx.action)) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternSyn.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternSyn.java index d7d49065..71b11539 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternSyn.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternSyn.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.common.network; import at.petrak.hexcasting.api.mod.HexItemTags; +import at.petrak.hexcasting.api.mod.HexStatistics; import at.petrak.hexcasting.api.spell.SpellDatum; import at.petrak.hexcasting.api.spell.casting.ControllerInfo; import at.petrak.hexcasting.api.spell.casting.ResolvedPattern; @@ -78,6 +79,8 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern } } + sender.awardStat(HexStatistics.PATTERNS_DRAWN); + var harness = IXplatAbstractions.INSTANCE.getHarness(sender, this.handUsed); ControllerInfo clientInfo; 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 4a4fda90..d0b57eda 100644 --- a/Common/src/main/resources/assets/hexcasting/lang/en_us.json +++ b/Common/src/main/resources/assets/hexcasting/lang/en_us.json @@ -409,6 +409,7 @@ "hexcasting.mishap.divide_by_zero.cos": "the cosine of %s", "hexcasting.mishap.no_akashic_record": "No Akashic Record at %s", "hexcasting.mishap.disallowed": "%s has been disallowed by the server admins", + "hexcasting.mishap.disallowed_circle": "%s has been disallowed in spell circles by the server admins", "hexcasting.mishap.invalid_spell_datum_type": "Tried to use a value of invalid type as a SpellDatum: %s (class %s). This is a bug in the mod.", "hexcasting.mishap.unknown": "%s threw an exception (%s). This is a bug in the mod.", 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 10dde32c..2eac6b3d 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java @@ -157,6 +157,8 @@ public class FabricHexConfig { ConfigTypes.INTEGER.withMinimum(4)); private final PropertyMirror> actionDenyList = PropertyMirror.create( ConfigTypes.makeList(ConfigTypes.STRING)); + private final PropertyMirror> circleActionDenyList = PropertyMirror.create( + ConfigTypes.makeList(ConfigTypes.STRING)); public ConfigTree configure(ConfigTreeBuilder bob) { bob.fork("Spells") @@ -174,10 +176,14 @@ public class FabricHexConfig { .beginValue("maxSpellCircleLength", ConfigTypes.NATURAL, DEFAULT_MAX_SPELL_CIRCLE_LENGTH) .withComment("The maximum number of slates in a spell circle") .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("The maximum number of slates in a spell circle") + .withComment("Resource locations of disallowed actions. Trying to cast one of these will result in a mishap.") .finishValue(actionDenyList::mirror); return bob.build(); @@ -202,5 +208,10 @@ public class FabricHexConfig { public boolean isActionAllowed(ResourceLocation actionID) { return !actionDenyList.getValue().contains(actionID.toString()); } + + @Override + public boolean isActionAllowedInCircles(ResourceLocation actionID) { + return false; + } } } 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 2d70178a..c8fbe170 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java @@ -77,6 +77,7 @@ public class ForgeHexConfig implements HexConfig.CommonConfigAccess { private static ForgeConfigSpec.IntValue maxSpellCircleLength; private static ForgeConfigSpec.ConfigValue> actionDenyList; + private static ForgeConfigSpec.ConfigValue> circleActionDenyList; public Server(ForgeConfigSpec.Builder builder) { builder.push("Spells"); @@ -91,6 +92,11 @@ public class ForgeHexConfig implements HexConfig.CommonConfigAccess { 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); + + circleActionDenyList = builder.comment( + "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(); actionDenyList = builder.comment( @@ -118,5 +124,10 @@ public class ForgeHexConfig implements HexConfig.CommonConfigAccess { public boolean isActionAllowed(ResourceLocation actionID) { return !actionDenyList.get().contains(actionID.toString()); } + + @Override + public boolean isActionAllowedInCircles(ResourceLocation actionID) { + return !circleActionDenyList.get().contains(actionID.toString()); + } } }