diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000..0a438461c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,68 @@ +name: Bug Report +description: Report an issue with Hex Casting +labels: + - bug + - unconfirmed + +body: + - type: dropdown + attributes: + label: Modloader + options: + - Forge + - Fabric + - Quilt + validations: + required: true + + - type: input + attributes: + label: Minecraft version + placeholder: eg. 1.19.2 + validations: + required: true + + - type: input + attributes: + label: Hex Casting version + placeholder: eg. 0.11.1-7-pre-609 + validations: + required: true + + - type: input + attributes: + label: Modloader version + description: | + List the version of the mod loader you are using. + If on Fabric, post the versions of both Fabric Loader and Fabric API. + placeholder: "eg. Forge: 36.2.9 / Fabric: Loader 0.10.6 + API 0.42.1" + + - type: input + attributes: + label: Modpack info + description: If playing a modpack, post the link to it! + + - type: input + attributes: + label: The latest.log file + description: Please use https://mclo.gs/ if possible. Sites like https://gist.github.com/ or https://pastebin.com/ are also acceptable. + + - type: textarea + attributes: + label: Issue description + placeholder: A description of the issue. + validations: + required: true + + - type: textarea + attributes: + label: Steps to reproduce + placeholder: | + 1. First step + 2. Second step + 3. etc... + + - type: textarea + attributes: + label: Other information + description: Any other relevant information that is related to this issue, such as other mods and their versions. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000..b8e5e9904 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,17 @@ +name: Feature Request +description: Suggest an improvement or a new feature +labels: + - enhancement + - unconfirmed + +body: + - type: textarea + attributes: + label: Describe the feature + validations: + required: true + + - type: textarea + attributes: + label: Additional context + description: Any other relevant information (eg. use cases, alternative solutions) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 000000000..160146297 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,37 @@ +# mirror of the Jenkins pipeline, used for requiring PRs to build successfully before merging +# this uses Actions because it's easier to integrate with GitHub PRs, and to allow running the build on forks + +name: Build pull request + +on: + pull_request: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "17.0.1" + - uses: gradle/actions/setup-gradle@v3 + + - name: Clean + run: | + chmod +x gradlew + ./gradlew clean + + - name: Build + run: ./gradlew build + + - name: Run Datagen + run: ./gradlew runAllDatagen + + - name: Check Datagen + run: | + git add --intent-to-add . + git diff --name-only --exit-code -- ":!:*/src/generated/resources/.cache/*" diff --git a/Common/build.gradle b/Common/build.gradle index 2c84ea11f..d5e6128c8 100644 --- a/Common/build.gradle +++ b/Common/build.gradle @@ -28,17 +28,13 @@ repositories { url = "https://modmaven.dev" } - // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: - flatDir { - dir 'libs' - } } dependencies { compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5' implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1' - compileOnly "${modID}:paucal-common-$minecraftVersion:$paucalVersion" + compileOnly "at.petra-k.paucal:paucal-common-$minecraftVersion:$paucalVersion" compileOnly "vazkii.patchouli:Patchouli-xplat:$minecraftVersion-$patchouliVersion-SNAPSHOT" compileOnly "org.jetbrains:annotations:$jetbrainsAnnotationsVersion" diff --git a/Common/libs/paucal-common-1.20.1-0.6.0.jar b/Common/libs/paucal-common-1.20.1-0.6.0.jar deleted file mode 100644 index 5d6e2c0ad..000000000 Binary files a/Common/libs/paucal-common-1.20.1-0.6.0.jar and /dev/null differ diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java index 00789ac46..d1f447cf8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java @@ -66,7 +66,9 @@ public final void triggerCreateEvent() { protected Map, @NotNull CastingEnvironmentComponent> componentMap = new HashMap<>(); private final List postExecutions = new ArrayList<>(); - private final List extractMedias = new ArrayList<>(); + private final List preMediaExtract = new ArrayList<>(); + private final List postMediaExtract = new ArrayList<>(); + private final List isVecInRanges = new ArrayList<>(); private final List hasEditPermissionsAts = new ArrayList<>(); @@ -112,7 +114,11 @@ public void addExtension(@NotNull T exte if (extension instanceof PostExecution postExecution) postExecutions.add(postExecution); if (extension instanceof ExtractMedia extractMedia) - extractMedias.add(extractMedia); + if (extension instanceof ExtractMedia.Pre pre) { + preMediaExtract.add(pre); + } else if (extension instanceof ExtractMedia.Post post) { + postMediaExtract.add(post); + } if (extension instanceof IsVecInRange isVecInRange) isVecInRanges.add(isVecInRange); if (extension instanceof HasEditPermissionsAt hasEditPermissionsAt) @@ -127,7 +133,11 @@ public void removeExtension(@NotNull CastingEnvironmentComponent.Key key) { if (extension instanceof PostExecution postExecution) postExecutions.remove(postExecution); if (extension instanceof ExtractMedia extractMedia) - extractMedias.remove(extractMedia); + if (extension instanceof ExtractMedia.Pre pre) { + preMediaExtract.remove(pre); + } else if (extension instanceof ExtractMedia.Post post) { + postMediaExtract.remove(post); + } if (extension instanceof IsVecInRange isVecInRange) isVecInRanges.remove(isVecInRange); if (extension instanceof HasEditPermissionsAt hasEditPermissionsAt) @@ -202,9 +212,12 @@ public boolean isEnlightened() { * positive. */ public long extractMedia(long cost) { - for (var extractMediaComponent : extractMedias) + for (var extractMediaComponent : preMediaExtract) cost = extractMediaComponent.onExtractMedia(cost); - return extractMediaEnvironment(cost); + cost = extractMediaEnvironment(cost); + for (var extractMediaComponent : postMediaExtract) + cost = extractMediaComponent.onExtractMedia(cost); + return cost; } /** @@ -259,7 +272,7 @@ public final boolean isVecInAmbit(Vec3 vec) { } public final boolean isEntityInRange(Entity e) { - return e instanceof Player || this.isVecInRange(e.position()); + return (e instanceof Player && HexConfig.server().trueNameHasAmbit()) || (this.isVecInWorld(e.position()) && this.isVecInRange(e.position())); } /** @@ -290,6 +303,9 @@ public final boolean canEditBlockAt(BlockPos vec) { * Convenience function to throw if the entity is out of the caster's range or the world */ public final void assertEntityInRange(Entity e) throws MishapEntityTooFarAway { + if (e instanceof ServerPlayer && HexConfig.server().trueNameHasAmbit()) { + return; + } if (!this.isVecInWorld(e.position())) { throw new MishapEntityTooFarAway(e); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java index fd8de3da7..c5aac3eac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java @@ -19,10 +19,20 @@ interface ExtractMedia extends CastingEnvironmentComponent { /** * Receives the cost that is being extracted, should return the * remaining cost after deducting whatever cost source this component - * is responsible for (should be >= 0). All Components are executed - * before the CastingEnvironment's extractMedia is executed. + * is responsible for (should be >= 0) */ long onExtractMedia(long cost); + + /** + * ExtractMedia component that extracts media BEFORE the call to {@link CastingEnvironment#extractMediaEnvironment(long)} + */ + interface Pre extends ExtractMedia {} + + /** + * ExtractMedia component that extracts media AFTER the call to {@link CastingEnvironment#extractMediaEnvironment(long)} + * if the input is <= 0 you should also probably return 0 (since media cost was already paid off) + */ + interface Post extends ExtractMedia {} } interface IsVecInRange extends CastingEnvironmentComponent { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt index d2cdfbdb0..04c34d774 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt @@ -59,7 +59,12 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { continuation = image2.continuation lastResolutionType = image2.resolutionType - performSideEffects(info, image2.sideEffects) + try { + performSideEffects(info, image2.sideEffects) + } catch (e: Exception) { + e.printStackTrace() + performSideEffects(info, listOf(OperatorSideEffect.DoMishap(MishapInternalException(e), Mishap.Context(null, null)))) + } info.earlyExit = info.earlyExit || !lastResolutionType.success } 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 be86acef1..105994f61 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 @@ -69,6 +69,8 @@ public interface ServerConfigAccess { // fun fact, although dimension keys are a RegistryHolder, they aren't a registry, so i can't do tags boolean canTeleportInThisDimension(ResourceKey dimension); + boolean trueNameHasAmbit(); + int DEFAULT_MAX_OP_COUNT = 1_000_000; int DEFAULT_MAX_SPELL_CIRCLE_LENGTH = 1024; int DEFAULT_OP_BREAK_HARVEST_LEVEL = 3; @@ -77,6 +79,8 @@ public interface ServerConfigAccess { List DEFAULT_DIM_TP_DENYLIST = List.of("twilightforest:twilight_forest"); + boolean DEFAULT_TRUE_NAME_HAS_AMBIT = true; + default Tier opBreakHarvestLevel() { return switch (this.opBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort()) { case 0 -> Tiers.WOOD; diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntitiesBy.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntitiesBy.kt index 17eabc187..c3366c9ac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntitiesBy.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntitiesBy.kt @@ -11,6 +11,7 @@ import net.minecraft.world.entity.Entity import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.animal.Animal import net.minecraft.world.entity.animal.WaterAnimal +import net.minecraft.world.entity.boss.EnderDragonPart import net.minecraft.world.entity.item.ItemEntity import net.minecraft.world.entity.monster.Enemy import net.minecraft.world.entity.player.Player @@ -51,6 +52,6 @@ class OpGetEntitiesBy(val checker: Predicate, val negate: Boolean) : Con fun isPlayer(e: Entity): Boolean = e is Player @JvmStatic - fun isLiving(e: Entity): Boolean = e is LivingEntity + fun isLiving(e: Entity): Boolean = (e is LivingEntity) || (e is EnderDragonPart) } } diff --git a/Fabric/build.gradle b/Fabric/build.gradle index 484dead70..1687865a8 100644 --- a/Fabric/build.gradle +++ b/Fabric/build.gradle @@ -81,7 +81,7 @@ dependencies { implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1' compileOnly project(":Common") - modImplementation "${modID}:paucal-fabric-$minecraftVersion:$paucalVersion" + modImplementation "at.petra-k.paucal:paucal-fabric-$minecraftVersion:$paucalVersion" modImplementation "vazkii.patchouli:Patchouli:$minecraftVersion-$patchouliVersion-FABRIC-SNAPSHOT" modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-base:$cardinalComponentsVersion" diff --git a/Fabric/libs/paucal-fabric-1.20.1-0.6.0.jar b/Fabric/libs/paucal-fabric-1.20.1-0.6.0.jar deleted file mode 100644 index b6a777b86..000000000 Binary files a/Fabric/libs/paucal-fabric-1.20.1-0.6.0.jar and /dev/null differ 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 960ab4205..7622e7cf8 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java @@ -174,6 +174,9 @@ public static final class Server implements HexConfig.ServerConfigAccess, Config private List circleActionDenyList = List.of(); @ConfigEntry.Gui.Tooltip private boolean villagersOffendedByMindMurder = DEFAULT_VILLAGERS_DISLIKE_MIND_MURDER; + @ConfigEntry.Gui.Tooltip + private boolean doesTrueNameHaveAmbit = DEFAULT_TRUE_NAME_HAS_AMBIT; + @ConfigEntry.Gui.Tooltip private List tpDimDenylist = DEFAULT_DIM_TP_DENYLIST; @@ -250,6 +253,11 @@ public boolean canTeleportInThisDimension(ResourceKey dimension) { return noneMatch(tpDimDenylist, dimension.location()); } + @Override + public boolean trueNameHasAmbit() { + return doesTrueNameHaveAmbit; + } + /** * Returns -1 if none is found */ diff --git a/Forge/build.gradle b/Forge/build.gradle index 9cd4e8e1d..05f0f9aff 100644 --- a/Forge/build.gradle +++ b/Forge/build.gradle @@ -69,8 +69,8 @@ dependencies { annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' - compileOnly fg.deobf("${modID}:paucal-forge-$minecraftVersion:$paucalVersion") - runtimeOnly fg.deobf("${modID}:paucal-forge-$minecraftVersion:$paucalVersion") + compileOnly fg.deobf("at.petra-k.paucal:paucal-forge-$minecraftVersion:$paucalVersion") + runtimeOnly fg.deobf("at.petra-k.paucal:paucal-forge-$minecraftVersion:$paucalVersion") compileOnly fg.deobf("vazkii.patchouli:Patchouli:$minecraftVersion-$patchouliVersion-FORGE-SNAPSHOT") runtimeOnly fg.deobf("vazkii.patchouli:Patchouli:$minecraftVersion-$patchouliVersion-FORGE-SNAPSHOT") diff --git a/Forge/libs/paucal-forge-1.20.1-0.6.0.jar b/Forge/libs/paucal-forge-1.20.1-0.6.0.jar deleted file mode 100644 index 63b42b412..000000000 Binary files a/Forge/libs/paucal-forge-1.20.1-0.6.0.jar and /dev/null differ 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 c9d904ff8..507d1fece 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java @@ -134,6 +134,8 @@ public static class Server implements HexConfig.ServerConfigAccess { private static ForgeConfigSpec.ConfigValue> tpDimDenyList; + private static ForgeConfigSpec.BooleanValue doesTrueNameHaveAmbit; + private static ForgeConfigSpec.ConfigValue> fewScrollTables; private static ForgeConfigSpec.ConfigValue> someScrollTables; private static ForgeConfigSpec.ConfigValue> manyScrollTables; @@ -170,6 +172,10 @@ public Server(ForgeConfigSpec.Builder builder) { tpDimDenyList = builder.comment("Resource locations of dimensions you can't Blink or Greater Teleport in.") .defineList("tpDimDenyList", DEFAULT_DIM_TP_DENYLIST, Server::isValidReslocArg); + + doesTrueNameHaveAmbit = builder.comment( + "when false makes player reference iotas behave as normal entity reference iotas") + .define("doesTrueNameHaveAmbit", DEFAULT_TRUE_NAME_HAS_AMBIT); } @Override @@ -207,6 +213,11 @@ public boolean canTeleportInThisDimension(ResourceKey dimension) { return noneMatch(tpDimDenyList.get(), dimension.location()); } + @Override + public boolean trueNameHasAmbit() { + return doesTrueNameHaveAmbit.get(); + } + private static boolean isValidReslocArg(Object o) { return o instanceof String s && ResourceLocation.isValidResourceLocation(s); } diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapClientCastingStack.java b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapClientCastingStack.java index 5263011a8..bdba8678c 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapClientCastingStack.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapClientCastingStack.java @@ -19,6 +19,6 @@ public ClientCastingStack get() { public static void tickClientPlayer(TickEvent.PlayerTickEvent evt) { if (evt.side == LogicalSide.CLIENT && !evt.player.isDeadOrDying()) evt.player.getCapability(HexCapabilities.CLIENT_CASTING_STACK).resolve() - .get().get().tick(); + .ifPresent(CastingStack -> CastingStack.get().tick()); } } diff --git a/Jenkinsfile b/Jenkinsfile index 5c470c0fd..a2da4ee85 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -42,8 +42,9 @@ pipeline { } stage('Publish') { when { - anyOf { + allOf { branch 'main' + not { changeRequest() } } } stages { diff --git a/build.gradle b/build.gradle index 4c93acbdc..63c66cd3a 100644 --- a/build.gradle +++ b/build.gradle @@ -74,7 +74,16 @@ subprojects { } } -allprojects { gradle.projectsEvaluated { tasks.withType(JavaCompile) { options.compilerArgs << "-Xmaxerrs" << "1000" } } } +allprojects { + gradle.projectsEvaluated { + tasks.withType(JavaCompile) { + options.compilerArgs << "-Xmaxerrs" << "1000" + } + } + + // disable most javadoc warnings + javadoc.options.addStringOption('Xdoclint:none', '-quiet') +} compileKotlin { kotlinOptions { diff --git a/gradle.properties b/gradle.properties index d8828e7c1..88d13e374 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ minecraftVersion=1.20.1 kotlinVersion=1.7.20 modVersion=0.11.1-7 -paucalVersion=0.6.0 +paucalVersion=0.6.0-pre-118 patchouliVersion=83 jeiVersion=15.0.0.12