From 88416c5833181209cc4212175228c82e0f75cd50 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Sun, 4 May 2025 19:55:42 -0400 Subject: [PATCH 01/18] typo: `condition` field (previously `conditions`) in `PredicateBarrierBlock` --- .../net/modgarden/barricade/block/PredicateBarrierBlock.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java index 5b5bf5e..7c13c78 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java @@ -41,7 +41,7 @@ public class PredicateBarrierBlock extends BarrierBlock { .fieldOf("icon") .forGetter(PredicateBarrierBlock::icon), GameCondition.CODEC - .fieldOf("conditions") + .fieldOf("condition") .forGetter(PredicateBarrierBlock::rawCondition) ).apply(instance, PredicateBarrierBlock::new)); public static final ContextParamSet PARAM_SET = ContextParamSet.Builder From efac0218b17ffc002c7ae2f8c238de758906863a Mon Sep 17 00:00:00 2001 From: sylv256 Date: Tue, 6 May 2025 22:21:24 -0400 Subject: [PATCH 02/18] feat: Creative-Only Lever --- CHANGELOG.md | 2 +- .../blockstates/creative_only_lever.json | 110 ++++++++++ .../models/item/creative_only_lever.json | 6 + .../data/barricade/tags/block/barriers.json | 12 +- .../tags/block/directional_barriers.json | 24 +-- .../barricade/tags/block/entity_barriers.json | 16 +- .../tags/block/predicate_barriers.json | 10 +- .../blocked_by_hostile_barrier.json | 72 +++---- .../entity_type/blocked_by_mob_barrier.json | 10 +- .../blocked_by_passive_barrier.json | 92 ++++----- .../data/barricade/tags/item/barriers.json | 36 ++-- .../block/blocks_wind_charge_explosions.json | 10 +- .../minecraft/tags/block/dragon_immune.json | 10 +- .../block/snow_layer_cannot_survive_on.json | 10 +- .../minecraft/tags/block/wither_immune.json | 10 +- .../barricade/block/PredicateBlock.java | 163 +++++++++++++++ .../barricade/block/PredicateLeverBlock.java | 190 ++++++++++++++++++ .../barricade/item/PredicateBlockItem.java | 40 ++++ .../barricade/mixin/BlockAccessor.java | 21 ++ ...hedHorizontalDirectionalBlockAccessor.java | 15 ++ .../HorizontalDirectionalBlockAccessor.java | 17 ++ .../barricade/mixin/LeverBlockAccessor.java | 59 ++++++ .../mixin/PredicateBlockAccessor.java | 12 ++ .../barricade/registry/BarricadeBlocks.java | 32 ++- .../barricade/registry/BarricadeItems.java | 17 +- .../assets/barricade/lang/en_us.json | 3 +- .../src/main/resources/barricade.mixins.json | 7 +- .../barricade/datagen/BarricadeDataGen.java | 89 ++++++++ .../barricade/fabric/BarricadeFabric.java | 3 +- .../barricade/neoforge/BarricadeNeoForge.java | 3 +- 30 files changed, 936 insertions(+), 165 deletions(-) create mode 100644 common/src/generated/resources/assets/barricade/blockstates/creative_only_lever.json create mode 100644 common/src/generated/resources/assets/barricade/models/item/creative_only_lever.json create mode 100644 common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java create mode 100644 common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java create mode 100644 common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java create mode 100644 common/src/main/java/net/modgarden/barricade/mixin/BlockAccessor.java create mode 100644 common/src/main/java/net/modgarden/barricade/mixin/FaceAttachedHorizontalDirectionalBlockAccessor.java create mode 100644 common/src/main/java/net/modgarden/barricade/mixin/HorizontalDirectionalBlockAccessor.java create mode 100644 common/src/main/java/net/modgarden/barricade/mixin/LeverBlockAccessor.java create mode 100644 common/src/main/java/net/modgarden/barricade/mixin/PredicateBlockAccessor.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 59767ae..5d25591 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,2 @@ ## Bugfixes -- Rectify buggy implementation of Advanced Barriers. +- typo: `condition` field (previously `conditions`) in `PredicateBarrierBlock` diff --git a/common/src/generated/resources/assets/barricade/blockstates/creative_only_lever.json b/common/src/generated/resources/assets/barricade/blockstates/creative_only_lever.json new file mode 100644 index 0000000..f5892ec --- /dev/null +++ b/common/src/generated/resources/assets/barricade/blockstates/creative_only_lever.json @@ -0,0 +1,110 @@ +{ + "variants": { + "face=ceiling,facing=east,powered=false": { + "model": "minecraft:block/lever_on", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=east,powered=true": { + "model": "minecraft:block/lever", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=north,powered=false": { + "model": "minecraft:block/lever_on", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=north,powered=true": { + "model": "minecraft:block/lever", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=south,powered=false": { + "model": "minecraft:block/lever_on", + "x": 180 + }, + "face=ceiling,facing=south,powered=true": { + "model": "minecraft:block/lever", + "x": 180 + }, + "face=ceiling,facing=west,powered=false": { + "model": "minecraft:block/lever_on", + "x": 180, + "y": 90 + }, + "face=ceiling,facing=west,powered=true": { + "model": "minecraft:block/lever", + "x": 180, + "y": 90 + }, + "face=floor,facing=east,powered=false": { + "model": "minecraft:block/lever_on", + "y": 90 + }, + "face=floor,facing=east,powered=true": { + "model": "minecraft:block/lever", + "y": 90 + }, + "face=floor,facing=north,powered=false": { + "model": "minecraft:block/lever_on" + }, + "face=floor,facing=north,powered=true": { + "model": "minecraft:block/lever" + }, + "face=floor,facing=south,powered=false": { + "model": "minecraft:block/lever_on", + "y": 180 + }, + "face=floor,facing=south,powered=true": { + "model": "minecraft:block/lever", + "y": 180 + }, + "face=floor,facing=west,powered=false": { + "model": "minecraft:block/lever_on", + "y": 270 + }, + "face=floor,facing=west,powered=true": { + "model": "minecraft:block/lever", + "y": 270 + }, + "face=wall,facing=east,powered=false": { + "model": "minecraft:block/lever_on", + "x": 90, + "y": 90 + }, + "face=wall,facing=east,powered=true": { + "model": "minecraft:block/lever", + "x": 90, + "y": 90 + }, + "face=wall,facing=north,powered=false": { + "model": "minecraft:block/lever_on", + "x": 90 + }, + "face=wall,facing=north,powered=true": { + "model": "minecraft:block/lever", + "x": 90 + }, + "face=wall,facing=south,powered=false": { + "model": "minecraft:block/lever_on", + "x": 90, + "y": 180 + }, + "face=wall,facing=south,powered=true": { + "model": "minecraft:block/lever", + "x": 90, + "y": 180 + }, + "face=wall,facing=west,powered=false": { + "model": "minecraft:block/lever_on", + "x": 90, + "y": 270 + }, + "face=wall,facing=west,powered=true": { + "model": "minecraft:block/lever", + "x": 90, + "y": 270 + } + } +} \ No newline at end of file diff --git a/common/src/generated/resources/assets/barricade/models/item/creative_only_lever.json b/common/src/generated/resources/assets/barricade/models/item/creative_only_lever.json new file mode 100644 index 0000000..d5a62d4 --- /dev/null +++ b/common/src/generated/resources/assets/barricade/models/item/creative_only_lever.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "minecraft:block/lever" + } +} \ No newline at end of file diff --git a/common/src/generated/resources/data/barricade/tags/block/barriers.json b/common/src/generated/resources/data/barricade/tags/block/barriers.json index 0aea222..a362f4b 100644 --- a/common/src/generated/resources/data/barricade/tags/block/barriers.json +++ b/common/src/generated/resources/data/barricade/tags/block/barriers.json @@ -1,7 +1,7 @@ { - "values": [ - "minecraft:barrier", - "#barricade:directional_barriers", - "#barricade:predicate_barriers" - ] -} + "values": [ + "minecraft:barrier", + "#barricade:directional_barriers", + "#barricade:predicate_barriers" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/barricade/tags/block/directional_barriers.json b/common/src/generated/resources/data/barricade/tags/block/directional_barriers.json index 2de5dab..46d3f0a 100644 --- a/common/src/generated/resources/data/barricade/tags/block/directional_barriers.json +++ b/common/src/generated/resources/data/barricade/tags/block/directional_barriers.json @@ -1,13 +1,13 @@ { - "values": [ - "barricade:advanced_barrier", - "barricade:down_barrier", - "barricade:up_barrier", - "barricade:north_barrier", - "barricade:south_barrier", - "barricade:east_barrier", - "barricade:west_barrier", - "barricade:horizontal_barrier", - "barricade:vertical_barrier" - ] -} + "values": [ + "barricade:advanced_barrier", + "barricade:down_barrier", + "barricade:up_barrier", + "barricade:north_barrier", + "barricade:south_barrier", + "barricade:east_barrier", + "barricade:west_barrier", + "barricade:horizontal_barrier", + "barricade:vertical_barrier" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/barricade/tags/block/entity_barriers.json b/common/src/generated/resources/data/barricade/tags/block/entity_barriers.json index b37f51d..d20f437 100644 --- a/common/src/generated/resources/data/barricade/tags/block/entity_barriers.json +++ b/common/src/generated/resources/data/barricade/tags/block/entity_barriers.json @@ -1,9 +1,9 @@ { - "values": [ - "barricade:advanced_barrier", - "barricade:player_barrier", - "barricade:mob_barrier", - "barricade:passive_barrier", - "barricade:hostile_barrier" - ] -} + "values": [ + "barricade:advanced_barrier", + "barricade:player_barrier", + "barricade:mob_barrier", + "barricade:passive_barrier", + "barricade:hostile_barrier" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/barricade/tags/block/predicate_barriers.json b/common/src/generated/resources/data/barricade/tags/block/predicate_barriers.json index fb86b88..b0be017 100644 --- a/common/src/generated/resources/data/barricade/tags/block/predicate_barriers.json +++ b/common/src/generated/resources/data/barricade/tags/block/predicate_barriers.json @@ -1,6 +1,6 @@ { - "values": [ - "#barricade:entity_barriers", - "barricade:creative_only_barrier" - ] -} + "values": [ + "#barricade:entity_barriers", + "barricade:creative_only_barrier" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_hostile_barrier.json b/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_hostile_barrier.json index 77e0e87..17f0467 100644 --- a/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_hostile_barrier.json +++ b/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_hostile_barrier.json @@ -1,37 +1,37 @@ { - "values": [ - "minecraft:blaze", - "minecraft:bogged", - "minecraft:breeze", - "minecraft:cave_spider", - "minecraft:creeper", - "minecraft:drowned", - "minecraft:elder_guardian", - "minecraft:ender_dragon", - "minecraft:enderman", - "minecraft:endermite", - "minecraft:ghast", - "minecraft:giant", - "minecraft:guardian", - "minecraft:hoglin", - "minecraft:husk", - "minecraft:magma_cube", - "minecraft:phantom", - "minecraft:piglin", - "minecraft:piglin_brute", - "minecraft:shulker", - "minecraft:skeleton", - "minecraft:slime", - "minecraft:spider", - "minecraft:stray", - "minecraft:vex", - "minecraft:warden", - "minecraft:witch", - "minecraft:wither", - "minecraft:wither_skeleton", - "minecraft:zoglin", - "minecraft:zombie", - "minecraft:zombie_villager", - "#minecraft:raiders" - ] -} + "values": [ + "minecraft:blaze", + "minecraft:bogged", + "minecraft:breeze", + "minecraft:cave_spider", + "minecraft:creeper", + "minecraft:drowned", + "minecraft:elder_guardian", + "minecraft:ender_dragon", + "minecraft:enderman", + "minecraft:endermite", + "minecraft:ghast", + "minecraft:giant", + "minecraft:guardian", + "minecraft:hoglin", + "minecraft:husk", + "minecraft:magma_cube", + "minecraft:phantom", + "minecraft:piglin", + "minecraft:piglin_brute", + "minecraft:shulker", + "minecraft:skeleton", + "minecraft:slime", + "minecraft:spider", + "minecraft:stray", + "minecraft:vex", + "minecraft:warden", + "minecraft:witch", + "minecraft:wither", + "minecraft:wither_skeleton", + "minecraft:zoglin", + "minecraft:zombie", + "minecraft:zombie_villager", + "#minecraft:raiders" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_mob_barrier.json b/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_mob_barrier.json index c93d41c..8ffff39 100644 --- a/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_mob_barrier.json +++ b/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_mob_barrier.json @@ -1,6 +1,6 @@ { - "values": [ - "#barricade:blocked_by_hostile_barrier", - "#barricade:blocked_by_passive_barrier" - ] -} + "values": [ + "#barricade:blocked_by_hostile_barrier", + "#barricade:blocked_by_passive_barrier" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_passive_barrier.json b/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_passive_barrier.json index 4ea82fe..6339328 100644 --- a/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_passive_barrier.json +++ b/common/src/generated/resources/data/barricade/tags/entity_type/blocked_by_passive_barrier.json @@ -1,47 +1,47 @@ { - "values": [ - "minecraft:allay", - "minecraft:armadillo", - "minecraft:axolotl", - "minecraft:bat", - "minecraft:bee", - "minecraft:camel", - "minecraft:cat", - "minecraft:chicken", - "minecraft:cod", - "minecraft:cow", - "minecraft:dolphin", - "minecraft:donkey", - "minecraft:fox", - "minecraft:frog", - "minecraft:glow_squid", - "minecraft:goat", - "minecraft:horse", - "minecraft:iron_golem", - "minecraft:llama", - "minecraft:mooshroom", - "minecraft:mule", - "minecraft:ocelot", - "minecraft:panda", - "minecraft:parrot", - "minecraft:pig", - "minecraft:polar_bear", - "minecraft:pufferfish", - "minecraft:rabbit", - "minecraft:salmon", - "minecraft:sheep", - "minecraft:skeleton_horse", - "minecraft:sniffer", - "minecraft:snow_golem", - "minecraft:squid", - "minecraft:strider", - "minecraft:tadpole", - "minecraft:trader_llama", - "minecraft:tropical_fish", - "minecraft:turtle", - "minecraft:villager", - "minecraft:wandering_trader", - "minecraft:wolf", - "minecraft:zombie_horse" - ] -} + "values": [ + "minecraft:allay", + "minecraft:armadillo", + "minecraft:axolotl", + "minecraft:bat", + "minecraft:bee", + "minecraft:camel", + "minecraft:cat", + "minecraft:chicken", + "minecraft:cod", + "minecraft:cow", + "minecraft:dolphin", + "minecraft:donkey", + "minecraft:fox", + "minecraft:frog", + "minecraft:glow_squid", + "minecraft:goat", + "minecraft:horse", + "minecraft:iron_golem", + "minecraft:llama", + "minecraft:mooshroom", + "minecraft:mule", + "minecraft:ocelot", + "minecraft:panda", + "minecraft:parrot", + "minecraft:pig", + "minecraft:polar_bear", + "minecraft:pufferfish", + "minecraft:rabbit", + "minecraft:salmon", + "minecraft:sheep", + "minecraft:skeleton_horse", + "minecraft:sniffer", + "minecraft:snow_golem", + "minecraft:squid", + "minecraft:strider", + "minecraft:tadpole", + "minecraft:trader_llama", + "minecraft:tropical_fish", + "minecraft:turtle", + "minecraft:villager", + "minecraft:wandering_trader", + "minecraft:wolf", + "minecraft:zombie_horse" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/barricade/tags/item/barriers.json b/common/src/generated/resources/data/barricade/tags/item/barriers.json index 397e90a..eb351ec 100644 --- a/common/src/generated/resources/data/barricade/tags/item/barriers.json +++ b/common/src/generated/resources/data/barricade/tags/item/barriers.json @@ -1,19 +1,19 @@ { - "values": [ - "minecraft:barrier", - "barricade:advanced_barrier", - "barricade:down_barrier", - "barricade:up_barrier", - "barricade:north_barrier", - "barricade:south_barrier", - "barricade:east_barrier", - "barricade:west_barrier", - "barricade:horizontal_barrier", - "barricade:vertical_barrier", - "barricade:advanced_barrier", - "barricade:player_barrier", - "barricade:mob_barrier", - "barricade:passive_barrier", - "barricade:hostile_barrier" - ] -} + "values": [ + "minecraft:barrier", + "barricade:advanced_barrier", + "barricade:down_barrier", + "barricade:up_barrier", + "barricade:north_barrier", + "barricade:south_barrier", + "barricade:east_barrier", + "barricade:west_barrier", + "barricade:horizontal_barrier", + "barricade:vertical_barrier", + "barricade:advanced_barrier", + "barricade:player_barrier", + "barricade:mob_barrier", + "barricade:passive_barrier", + "barricade:hostile_barrier" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/minecraft/tags/block/blocks_wind_charge_explosions.json b/common/src/generated/resources/data/minecraft/tags/block/blocks_wind_charge_explosions.json index 0cc5f8a..d7f4aaa 100644 --- a/common/src/generated/resources/data/minecraft/tags/block/blocks_wind_charge_explosions.json +++ b/common/src/generated/resources/data/minecraft/tags/block/blocks_wind_charge_explosions.json @@ -1,6 +1,6 @@ { - "values": [ - "#barricade:directional_barriers", - "#barricade:predicate_barriers" - ] -} + "values": [ + "#barricade:directional_barriers", + "#barricade:predicate_barriers" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/minecraft/tags/block/dragon_immune.json b/common/src/generated/resources/data/minecraft/tags/block/dragon_immune.json index 0cc5f8a..d7f4aaa 100644 --- a/common/src/generated/resources/data/minecraft/tags/block/dragon_immune.json +++ b/common/src/generated/resources/data/minecraft/tags/block/dragon_immune.json @@ -1,6 +1,6 @@ { - "values": [ - "#barricade:directional_barriers", - "#barricade:predicate_barriers" - ] -} + "values": [ + "#barricade:directional_barriers", + "#barricade:predicate_barriers" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/minecraft/tags/block/snow_layer_cannot_survive_on.json b/common/src/generated/resources/data/minecraft/tags/block/snow_layer_cannot_survive_on.json index 0cc5f8a..d7f4aaa 100644 --- a/common/src/generated/resources/data/minecraft/tags/block/snow_layer_cannot_survive_on.json +++ b/common/src/generated/resources/data/minecraft/tags/block/snow_layer_cannot_survive_on.json @@ -1,6 +1,6 @@ { - "values": [ - "#barricade:directional_barriers", - "#barricade:predicate_barriers" - ] -} + "values": [ + "#barricade:directional_barriers", + "#barricade:predicate_barriers" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/data/minecraft/tags/block/wither_immune.json b/common/src/generated/resources/data/minecraft/tags/block/wither_immune.json index 0cc5f8a..d7f4aaa 100644 --- a/common/src/generated/resources/data/minecraft/tags/block/wither_immune.json +++ b/common/src/generated/resources/data/minecraft/tags/block/wither_immune.json @@ -1,6 +1,6 @@ { - "values": [ - "#barricade:directional_barriers", - "#barricade:predicate_barriers" - ] -} + "values": [ + "#barricade:directional_barriers", + "#barricade:predicate_barriers" + ] +} \ No newline at end of file diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java new file mode 100644 index 0000000..0403fc0 --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java @@ -0,0 +1,163 @@ +package net.modgarden.barricade.block; + +import com.mojang.datafixers.util.Function3; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.EntityCollisionContext; +import net.modgarden.barricade.Barricade; +import net.modgarden.silicate.api.SilicateRegistries; +import net.modgarden.silicate.api.condition.GameCondition; +import net.modgarden.silicate.api.context.GameContext; +import net.modgarden.silicate.api.context.param.ContextParamMap; +import net.modgarden.silicate.api.context.param.ContextParamSet; +import net.modgarden.silicate.api.context.param.ContextParamTypes; +import net.modgarden.silicate.api.exception.InvalidContextParameterException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Function; + +/** + *

How to make a PredicateBlock

+ *
    + *
  1. Extend the PredicateBlock class and set T to the simulated block.
  2. + *
  3. Create constructors as shown in PredicateLeverBlock.
  4. + *
  5. Override all methods that your block and its superclasses override, then call those methods using accessors.
  6. + *
  7. Set up a method called registerState and call the methods as shown in PredicateLeverBlock
  8. + *
+ * @param The type of the block to simulate. + */ +public abstract class PredicateBlock extends Block { + public static final ContextParamSet PARAM_SET = ContextParamSet.Builder + .of() + .required(ContextParamTypes.THIS_ENTITY) + .required(ContextParamTypes.BLOCK_STATE) + .required(ContextParamTypes.ORIGIN) + .build(); + + private final T simulated; + private final ResourceLocation icon; + private final Function>> registryToCondition; + private Holder> condition; + + public PredicateBlock(T simulated, Properties properties, ResourceLocation icon, ResourceKey> conditionTemplate) { + super(properties); + this.simulated = simulated; + this.icon = icon; + this.registryToCondition = registryAccess -> registryAccess.registryOrThrow(SilicateRegistries.CONDITION_TEMPLATE).getHolderOrThrow(conditionTemplate); + } + + protected PredicateBlock(T simulated, Properties properties, ResourceLocation icon, Holder> condition) { + super(properties); + this.simulated = simulated; + this.icon = icon; + this.registryToCondition = null; + this.condition = condition; + } + + public ResourceLocation icon() { + return icon; + } + + public Holder> condition(RegistryAccess registries) { + if (condition == null && registryToCondition != null) + condition = registryToCondition.apply(registries); + return condition; + } + + public static GameContext newContext( + @Nullable Level level, + @NotNull Entity entity, + BlockState state, + BlockPos pos + ) throws InvalidContextParameterException { + ContextParamMap paramMap = ContextParamMap.Builder + .of(PARAM_SET) + .withParameter(ContextParamTypes.THIS_ENTITY, entity) + .withParameter(ContextParamTypes.BLOCK_STATE, state) + .withParameter(ContextParamTypes.ORIGIN, pos.getCenter()) + .build(); + return GameContext.of(level, paramMap); + } + + /** + * @return Whether to let the entity interact (true) or block the entity's interaction (false). + */ + public boolean test( + @Nullable Level level, + @NotNull Entity entity, + BlockState state, + BlockPos pos + ) throws InvalidContextParameterException { + // Inverted for compatibility with the old Predicate Barrier Block system + return !test(newContext(level, entity, state, pos)); + } + + public final boolean test(GameContext context) { + if (context.getLevel() == null) + return rawCondition() != null && rawCondition().value().test(context); + return this.condition(context.getLevel().registryAccess()).value().test(context); + } + + protected @NotNull MapCodec> mapCodec(Constructor constructor) { + return RecordCodecBuilder.mapCodec(instance -> instance.group( + BlockBehaviour.propertiesCodec(), + ResourceLocation.CODEC + .fieldOf("icon") + .forGetter(PredicateBlock::icon), + GameCondition.CODEC + .fieldOf("condition") + .forGetter(PredicateBlock::rawCondition) + ).apply(instance, constructor)); + } + + protected Holder> rawCondition() { + return condition; + } + + protected T simulated() { + return simulated; + } + + protected boolean isShaped( + @NotNull BlockState state, + @NotNull BlockGetter blockGetter, + @NotNull BlockPos pos, + @NotNull CollisionContext context + ) { + if (context instanceof EntityCollisionContext entityContext && entityContext.getEntity() != null) { + Level level = null; + if (blockGetter instanceof Level) { + level = (Level) blockGetter; + } + + try { + if (!test(level, entityContext.getEntity(), state, pos)) { + return false; + } + } catch (InvalidContextParameterException e) { + Barricade.LOG.error("Failed to test shape", e); + } + } + return true; + } + + // super mario in real life + @FunctionalInterface + public interface Constructor extends Function3>, PredicateBlock> { + @Override + PredicateBlock apply(Properties properties, ResourceLocation icon, Holder> condition); + } +} diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java new file mode 100644 index 0000000..1d1fbed --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java @@ -0,0 +1,190 @@ +package net.modgarden.barricade.block; + +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.AttachFace; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import net.modgarden.barricade.mixin.BlockAccessor; +import net.modgarden.barricade.mixin.FaceAttachedHorizontalDirectionalBlockAccessor; +import net.modgarden.barricade.mixin.HorizontalDirectionalBlockAccessor; +import net.modgarden.barricade.mixin.LeverBlockAccessor; +import net.modgarden.silicate.api.condition.GameCondition; +import net.modgarden.silicate.api.exception.InvalidContextParameterException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.BiConsumer; + +public class PredicateLeverBlock extends PredicateBlock { + private static final LeverBlock DEFAULT_SIMULATED = (LeverBlock) Blocks.LEVER; + public static final Properties PROPERTIES = Properties.ofFullCopy(Blocks.LEVER); + + public PredicateLeverBlock(ResourceLocation icon, ResourceKey> conditionTemplate) { + super(LeverBlockAccessor.init(PROPERTIES), PROPERTIES, icon, conditionTemplate); + registerState(); + } + + protected PredicateLeverBlock(Properties properties, ResourceLocation icon, Holder> condition) { + super(LeverBlockAccessor.init(properties), properties, icon, condition); + registerState(); + } + + private void registerState() { + this.registerDefaultState( + this.stateDefinition.any().setValue(HorizontalDirectionalBlock.FACING, Direction.NORTH).setValue(LeverBlock.POWERED, Boolean.FALSE).setValue(LeverBlock.FACE, AttachFace.WALL) + ); + ((BlockAccessor) simulated()).setDefaultBlockState(this.defaultBlockState()); + ((BlockAccessor) simulated()).setBuiltInRegistryHolder(((BlockAccessor) this).getBuiltInRegistryHolder()); + } + + @Override + protected @NotNull MapCodec codec() { + return mapCodec(PredicateLeverBlock::new); + } + + @SuppressWarnings("deprecation") + @Override + protected @NotNull BlockState rotate(@NotNull BlockState state, @NotNull Rotation rotation) { + return ((HorizontalDirectionalBlockAccessor) simulated()).invokeRotate(state, rotation); + } + + @SuppressWarnings("deprecation") + @Override + protected @NotNull BlockState mirror(@NotNull BlockState state, @NotNull Mirror mirror) { + return ((HorizontalDirectionalBlockAccessor) simulated()).invokeMirror(state, mirror); + } + + @Override + public @Nullable BlockState getStateForPlacement(@NotNull BlockPlaceContext context) { + return simulated().getStateForPlacement(context); + } + + @Override + protected @NotNull BlockState updateShape( + @NotNull BlockState state, + @NotNull Direction direction, + @NotNull BlockState neighborState, + @NotNull LevelAccessor level, + @NotNull BlockPos pos, + @NotNull BlockPos neighborPos + ) { + return ((FaceAttachedHorizontalDirectionalBlockAccessor) simulated()).invokeUpdateShape(state, direction, neighborState, level, pos, neighborPos); + } + + @Override + protected @NotNull VoxelShape getShape( + @NotNull BlockState state, + @NotNull BlockGetter blockGetter, + @NotNull BlockPos pos, + @NotNull CollisionContext context + ) { + if (this.isShaped(state, blockGetter, pos, context)) { + return ((LeverBlockAccessor) simulated()).invokeGetShape(state, blockGetter, pos, context); + } else { + return Shapes.empty(); + } + } + + @Override + protected @NotNull InteractionResult useWithoutItem( + @NotNull BlockState state, + @NotNull Level level, + @NotNull BlockPos pos, + @NotNull Player player, + @NotNull BlockHitResult hitResult + ) { + try { + if (level.isClientSide() || test(level, player, state, pos)) { + return ((LeverBlockAccessor) simulated()).invokeUseWithoutItem(state, level, pos, player, hitResult); + } else { + return InteractionResult.PASS; + } + } catch (InvalidContextParameterException e) { + throw new RuntimeException(e); + } + } + + @Override + protected void onExplosionHit( + @NotNull BlockState state, + @NotNull Level level, + @NotNull BlockPos pos, + @NotNull Explosion explosion, + @NotNull BiConsumer dropConsumer + ) { + ((LeverBlockAccessor) simulated()).invokeOnExplosionHit(state, level, pos, explosion, dropConsumer); + } + + @Override + public void animateTick( + @NotNull BlockState state, + @NotNull Level level, + @NotNull BlockPos pos, + @NotNull RandomSource random + ) { + ((LeverBlockAccessor) simulated()).invokeAnimateTick(state, level, pos, random); + } + + @Override + protected void onRemove( + @NotNull BlockState state, + @NotNull Level level, + @NotNull BlockPos pos, + @NotNull BlockState newState, + boolean movedByPiston + ) { + ((LeverBlockAccessor) simulated()).invokeOnRemove(state, level, pos, newState, movedByPiston); + } + + @SuppressWarnings("deprecation") + @Override + protected int getSignal( + @NotNull BlockState state, + @NotNull BlockGetter level, + @NotNull BlockPos pos, + @NotNull Direction direction + ) { + return ((LeverBlockAccessor) simulated()).invokeGetSignal(state, level, pos, direction); + } + + @SuppressWarnings("deprecation") + @Override + protected int getDirectSignal( + @NotNull BlockState state, + @NotNull BlockGetter level, + @NotNull BlockPos pos, + @NotNull Direction direction + ) { + return ((LeverBlockAccessor) simulated()).invokeGetDirectSignal(state, level, pos, direction); + } + + @SuppressWarnings("deprecation") + @Override + protected boolean isSignalSource(@NotNull BlockState state) { + return ((LeverBlockAccessor) simulated()).invokeIsSignalSource(state); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.@NotNull Builder builder) { + ((LeverBlockAccessor) DEFAULT_SIMULATED).invokeCreateBlockStateDefinition(builder); + } +} diff --git a/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java b/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java new file mode 100644 index 0000000..54025d5 --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java @@ -0,0 +1,40 @@ +package net.modgarden.barricade.item; + +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.modgarden.barricade.block.PredicateBlock; +import net.modgarden.silicate.api.exception.InvalidContextParameterException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class PredicateBlockItem> extends BlockItem { + public PredicateBlockItem(S block, Properties properties) { + super(block, properties); + } + + @Override + protected boolean canPlace(@NotNull BlockPlaceContext context, @NotNull BlockState state) { + if (super.canPlace(context, state) && context.getPlayer() != null) { + try { + return this.getBlock().test(context.getLevel(), context.getPlayer(), state, context.getClickedPos()); + } catch (InvalidContextParameterException e) { + throw new RuntimeException(e); + } + } else { + return false; + } + } + + @Override + protected @Nullable BlockState getPlacementState(@NotNull BlockPlaceContext context) { + return super.getPlacementState(context); + } + + @SuppressWarnings("unchecked") // It is illegal to have a this.block field not of type S + @Override + public @NotNull S getBlock() { + return (S) super.getBlock(); + } +} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/BlockAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/BlockAccessor.java new file mode 100644 index 0000000..5f81ff6 --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/mixin/BlockAccessor.java @@ -0,0 +1,21 @@ +package net.modgarden.barricade.mixin; + +import net.minecraft.core.Holder; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(Block.class) +public interface BlockAccessor { + @Accessor + void setDefaultBlockState(BlockState state); + + @Mutable + @Accessor + void setBuiltInRegistryHolder(Holder.Reference reference); + + @Accessor + Holder.Reference getBuiltInRegistryHolder(); +} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/FaceAttachedHorizontalDirectionalBlockAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/FaceAttachedHorizontalDirectionalBlockAccessor.java new file mode 100644 index 0000000..836c033 --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/mixin/FaceAttachedHorizontalDirectionalBlockAccessor.java @@ -0,0 +1,15 @@ +package net.modgarden.barricade.mixin; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.FaceAttachedHorizontalDirectionalBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(FaceAttachedHorizontalDirectionalBlock.class) +public interface FaceAttachedHorizontalDirectionalBlockAccessor { + @Invoker + BlockState invokeUpdateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor level, BlockPos currentPos, BlockPos facingPos); +} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/HorizontalDirectionalBlockAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/HorizontalDirectionalBlockAccessor.java new file mode 100644 index 0000000..81f994d --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/mixin/HorizontalDirectionalBlockAccessor.java @@ -0,0 +1,17 @@ +package net.modgarden.barricade.mixin; + +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(HorizontalDirectionalBlock.class) +public interface HorizontalDirectionalBlockAccessor { + @Invoker + BlockState invokeRotate(BlockState state, Rotation rot); + + @Invoker + BlockState invokeMirror(BlockState state, Mirror mirror); +} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/LeverBlockAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/LeverBlockAccessor.java new file mode 100644 index 0000000..03fa065 --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/mixin/LeverBlockAccessor.java @@ -0,0 +1,59 @@ +package net.modgarden.barricade.mixin; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LeverBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.function.BiConsumer; + +@Mixin(LeverBlock.class) +public interface LeverBlockAccessor { + @Invoker("") + static LeverBlock init(BlockBehaviour.Properties properties) { + throw new UnsupportedOperationException("Mixin not applied"); + } + + @Invoker + @NotNull VoxelShape invokeGetShape(@NotNull BlockState state, @NotNull BlockGetter blockGetter, @NotNull BlockPos pos, @NotNull CollisionContext context); + + @Invoker + InteractionResult invokeUseWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult); + + @Invoker + void invokeOnExplosionHit(BlockState state, Level level, BlockPos pos, Explosion explosion, BiConsumer dropConsumer); + + @Invoker + void invokeAnimateTick(BlockState state, Level level, BlockPos pos, RandomSource random); + + @Invoker + void invokeOnRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving); + + @Invoker + int invokeGetSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side); + + @Invoker + int invokeGetDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side); + + @Invoker + boolean invokeIsSignalSource(BlockState state); + + @Invoker + void invokeCreateBlockStateDefinition(StateDefinition.Builder builder); +} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/PredicateBlockAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/PredicateBlockAccessor.java new file mode 100644 index 0000000..bdf7c40 --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/mixin/PredicateBlockAccessor.java @@ -0,0 +1,12 @@ +package net.modgarden.barricade.mixin; + +import net.minecraft.world.level.block.Block; +import net.modgarden.barricade.block.PredicateBlock; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(PredicateBlock.class) +public interface PredicateBlockAccessor { + @Accessor + Block getSimulated(); +} diff --git a/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java b/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java index 22e6e45..a1723e3 100644 --- a/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java +++ b/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java @@ -4,14 +4,15 @@ import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockBehaviour; import net.modgarden.barricade.Barricade; -import net.modgarden.barricade.block.AdvancedBarrierBlock; -import net.modgarden.barricade.block.DirectionalBarrierBlock; -import net.modgarden.barricade.block.PredicateBarrierBlock; +import net.modgarden.barricade.block.*; import net.modgarden.barricade.data.BlockedDirections; +import net.modgarden.barricade.mixin.PredicateBlockAccessor; import net.modgarden.silicate.api.SilicateRegistries; +import net.modgarden.silicate.api.condition.GameCondition; public class BarricadeBlocks { public static final AdvancedBarrierBlock ADVANCED_BARRIER = new AdvancedBarrierBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); @@ -58,6 +59,12 @@ public class BarricadeBlocks { ResourceKey.create(SilicateRegistries.CONDITION_TEMPLATE, Barricade.asResource("hostile")) ); + // Predicate Levers + public static final PredicateLeverBlock CREATIVE_ONLY_LEVER = new PredicateLeverBlock( + Barricade.asResource("barricade/icon/iron_sword"), + conditionTemplate("creative_only") + ); + public static void registerAll() { Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("advanced_barrier"), ADVANCED_BARRIER); @@ -76,5 +83,24 @@ public static void registerAll() { Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("hostile_barrier"), HOSTILE_BARRIER); Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("creative_only_barrier"), CREATIVE_ONLY_BARRIER); + + registerPredicate("creative_only_lever", CREATIVE_ONLY_LEVER); + } + + private static > void registerPredicate(String name, S block) { + register(name, block); + // https://github.com/reactjs/react.dev/issues/3896 + register("zz__" + name + "_secret_block_do_not_use_or_you_will_be_fired", ((PredicateBlockAccessor) block).getSimulated()); + } + + private static void register(String name, Block block) { + Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource(name), block); + } + + private static ResourceKey> conditionTemplate(String name) { + return ResourceKey.create( + SilicateRegistries.CONDITION_TEMPLATE, + Barricade.asResource(name) + ); } } diff --git a/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java b/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java index 11a4b81..3965c68 100644 --- a/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java +++ b/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java @@ -5,10 +5,13 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.Rarity; +import net.minecraft.world.level.block.LeverBlock; import net.modgarden.barricade.Barricade; +import net.modgarden.barricade.block.PredicateLeverBlock; import net.modgarden.barricade.item.AdvancedBarrierBlockItem; import net.modgarden.barricade.item.DirectionalBarrierBlockItem; import net.modgarden.barricade.item.EntityCheckBarrierBlockItem; +import net.modgarden.barricade.item.PredicateBlockItem; import org.jetbrains.annotations.NotNull; public class BarricadeItems { @@ -34,6 +37,12 @@ public class BarricadeItems { barrierProps() ); + // Predicate Levers + public static final PredicateBlockItem CREATIVE_ONLY_LEVER = new PredicateBlockItem<>( + BarricadeBlocks.CREATIVE_ONLY_LEVER, + barrierProps() + ); + public static void registerAll() { Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("advanced_barrier"), ADVANCED_BARRIER); @@ -52,9 +61,15 @@ public static void registerAll() { Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("hostile_barrier"), HOSTILE_BARRIER); Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("creative_only_barrier"), CREATIVE_ONLY_BARRIER); + + register("creative_only_lever", CREATIVE_ONLY_LEVER); + } + + private static void register(String name, BlockItem blockItem) { + Registry.register(BuiltInRegistries.ITEM, Barricade.asResource(name), blockItem); } private static Item.@NotNull Properties barrierProps() { return new Item.Properties().rarity(Rarity.EPIC); } -} \ No newline at end of file +} diff --git a/common/src/main/resources/assets/barricade/lang/en_us.json b/common/src/main/resources/assets/barricade/lang/en_us.json index 1607870..4f35f95 100644 --- a/common/src/main/resources/assets/barricade/lang/en_us.json +++ b/common/src/main/resources/assets/barricade/lang/en_us.json @@ -13,6 +13,7 @@ "block.barricade.passive_barrier": "Passive Barrier", "block.barricade.hostile_barrier": "Hostile Barrier", "block.barricade.creative_only_barrier": "Creative-Only Barrier", + "block.barricade.creative_only_lever": "Creative-Only Lever", "tag.item.barricade.barriers": "Barriers", "resourcePack.barricade.modded_rendering.name": "Barricade Rendering", "resourcePack.barricade.modded_rendering.description": "Enables Barricade's alternative block rendering.", @@ -27,4 +28,4 @@ "command.barricade.visibility.disable.blocks.error.already_disabled": "Operator blocks %s are already invisible", "command.barricade.visibility.disable.all.success": "Made all operator blocks invisible", "command.barricade.visibility.disable.blocks.success": "Made all instances of %s invisible" -} \ No newline at end of file +} diff --git a/common/src/main/resources/barricade.mixins.json b/common/src/main/resources/barricade.mixins.json index ff5c32f..98efb8d 100644 --- a/common/src/main/resources/barricade.mixins.json +++ b/common/src/main/resources/barricade.mixins.json @@ -6,9 +6,14 @@ "compatibilityLevel": "JAVA_21", "mixins": [ "AbstractArrowMixin", + "BlockAccessor", "BlockBehaviourBlockStateBaseMixin", "BlockBehaviourMixin", - "BlockMixin" + "BlockMixin", + "FaceAttachedHorizontalDirectionalBlockAccessor", + "HorizontalDirectionalBlockAccessor", + "LeverBlockAccessor", + "PredicateBlockAccessor" ], "client": [ "client.ClientChunkCacheAccessor", diff --git a/fabric/src/datagen/java/net/modgarden/barricade/datagen/BarricadeDataGen.java b/fabric/src/datagen/java/net/modgarden/barricade/datagen/BarricadeDataGen.java index e8151a8..dec636d 100644 --- a/fabric/src/datagen/java/net/modgarden/barricade/datagen/BarricadeDataGen.java +++ b/fabric/src/datagen/java/net/modgarden/barricade/datagen/BarricadeDataGen.java @@ -3,13 +3,29 @@ import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; +import net.minecraft.core.Direction; import net.minecraft.core.HolderLookup; +import net.minecraft.data.models.BlockModelGenerators; +import net.minecraft.data.models.ItemModelGenerators; +import net.minecraft.data.models.blockstates.MultiVariantGenerator; +import net.minecraft.data.models.blockstates.PropertyDispatch; +import net.minecraft.data.models.blockstates.Variant; +import net.minecraft.data.models.blockstates.VariantProperties; +import net.minecraft.data.models.model.ModelLocationUtils; +import net.minecraft.data.models.model.ModelTemplates; +import net.minecraft.data.models.model.TextureMapping; +import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.BlockTags; import net.minecraft.tags.EntityTypeTags; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.properties.AttachFace; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.modgarden.barricade.registry.BarricadeBlocks; import net.modgarden.barricade.registry.BarricadeTags; import org.jetbrains.annotations.Nullable; @@ -23,6 +39,79 @@ public void onInitializeDataGenerator(FabricDataGenerator generator) { BlockTagProvider blockTagProvider = pack.addProvider(BlockTagProvider::new); pack.addProvider(EntityTypeTagProvider::new); pack.addProvider((output, registries) -> new ItemTagProvider(output, registries, blockTagProvider)); + pack.addProvider(ModelProvider::new); + } + + private static class ModelProvider extends FabricModelProvider { + public ModelProvider(FabricDataOutput output) { + super(output); + } + + @Override + public void generateBlockStateModels(BlockModelGenerators generators) { + createLever(generators, BarricadeBlocks.CREATIVE_ONLY_LEVER); + } + + @Override + public void generateItemModels(ItemModelGenerators generators) { + } + + private static void createLever(BlockModelGenerators generators, Block block) { + ResourceLocation resourceLocation = ModelLocationUtils.getModelLocation(Blocks.LEVER); + ResourceLocation resourceLocation2 = ModelLocationUtils.getModelLocation(Blocks.LEVER, "_on"); + createSimpleFlatItemModel(generators, block, Blocks.LEVER); + generators.blockStateOutput + .accept( + MultiVariantGenerator.multiVariant(block) + .with(BlockModelGenerators.createBooleanModelDispatch(BlockStateProperties.POWERED, resourceLocation, resourceLocation2)) + .with( + PropertyDispatch.properties(BlockStateProperties.ATTACH_FACE, BlockStateProperties.HORIZONTAL_FACING) + .select( + AttachFace.CEILING, + Direction.NORTH, + Variant.variant().with(VariantProperties.X_ROT, VariantProperties.Rotation.R180).with(VariantProperties.Y_ROT, VariantProperties.Rotation.R180) + ) + .select( + AttachFace.CEILING, + Direction.EAST, + Variant.variant().with(VariantProperties.X_ROT, VariantProperties.Rotation.R180).with(VariantProperties.Y_ROT, VariantProperties.Rotation.R270) + ) + .select(AttachFace.CEILING, Direction.SOUTH, Variant.variant().with(VariantProperties.X_ROT, VariantProperties.Rotation.R180)) + .select( + AttachFace.CEILING, + Direction.WEST, + Variant.variant().with(VariantProperties.X_ROT, VariantProperties.Rotation.R180).with(VariantProperties.Y_ROT, VariantProperties.Rotation.R90) + ) + .select(AttachFace.FLOOR, Direction.NORTH, Variant.variant()) + .select(AttachFace.FLOOR, Direction.EAST, Variant.variant().with(VariantProperties.Y_ROT, VariantProperties.Rotation.R90)) + .select(AttachFace.FLOOR, Direction.SOUTH, Variant.variant().with(VariantProperties.Y_ROT, VariantProperties.Rotation.R180)) + .select(AttachFace.FLOOR, Direction.WEST, Variant.variant().with(VariantProperties.Y_ROT, VariantProperties.Rotation.R270)) + .select(AttachFace.WALL, Direction.NORTH, Variant.variant().with(VariantProperties.X_ROT, VariantProperties.Rotation.R90)) + .select( + AttachFace.WALL, + Direction.EAST, + Variant.variant().with(VariantProperties.X_ROT, VariantProperties.Rotation.R90).with(VariantProperties.Y_ROT, VariantProperties.Rotation.R90) + ) + .select( + AttachFace.WALL, + Direction.SOUTH, + Variant.variant().with(VariantProperties.X_ROT, VariantProperties.Rotation.R90).with(VariantProperties.Y_ROT, VariantProperties.Rotation.R180) + ) + .select( + AttachFace.WALL, + Direction.WEST, + Variant.variant().with(VariantProperties.X_ROT, VariantProperties.Rotation.R90).with(VariantProperties.Y_ROT, VariantProperties.Rotation.R270) + ) + ) + ); + } + + private static void createSimpleFlatItemModel(BlockModelGenerators generators, Block flatBlock, Block textureBlock) { + Item item = flatBlock.asItem(); + if (item != Items.AIR) { + ModelTemplates.FLAT_ITEM.create(ModelLocationUtils.getModelLocation(item), TextureMapping.layer0(textureBlock), generators.modelOutput); + } + } } private static class BlockTagProvider extends FabricTagProvider.BlockTagProvider { diff --git a/fabric/src/main/java/net/modgarden/barricade/fabric/BarricadeFabric.java b/fabric/src/main/java/net/modgarden/barricade/fabric/BarricadeFabric.java index fe810ef..69ae150 100644 --- a/fabric/src/main/java/net/modgarden/barricade/fabric/BarricadeFabric.java +++ b/fabric/src/main/java/net/modgarden/barricade/fabric/BarricadeFabric.java @@ -59,7 +59,8 @@ public void onInitialize() { BarricadeItems.MOB_BARRIER, BarricadeItems.PASSIVE_BARRIER, BarricadeItems.HOSTILE_BARRIER, - BarricadeItems.CREATIVE_ONLY_BARRIER); + BarricadeItems.CREATIVE_ONLY_BARRIER, + BarricadeItems.CREATIVE_ONLY_LEVER); }); } } diff --git a/neoforge/src/main/java/net/modgarden/barricade/neoforge/BarricadeNeoForge.java b/neoforge/src/main/java/net/modgarden/barricade/neoforge/BarricadeNeoForge.java index bed670e..06f09d3 100644 --- a/neoforge/src/main/java/net/modgarden/barricade/neoforge/BarricadeNeoForge.java +++ b/neoforge/src/main/java/net/modgarden/barricade/neoforge/BarricadeNeoForge.java @@ -91,7 +91,8 @@ public static void buildCreativeModeTabs(BuildCreativeModeTabContentsEvent event BarricadeItems.MOB_BARRIER, BarricadeItems.PASSIVE_BARRIER, BarricadeItems.HOSTILE_BARRIER, - BarricadeItems.CREATIVE_ONLY_BARRIER + BarricadeItems.CREATIVE_ONLY_BARRIER, + BarricadeItems.CREATIVE_ONLY_LEVER ); for (Item item : items) { From ddf40f798ad24b19862aefe81bc9181e21e0debc Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 17:40:14 -0400 Subject: [PATCH 03/18] chore: bump version --- .../src/main/kotlin/net/modgarden/barricade/gradle/Versions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/net/modgarden/barricade/gradle/Versions.kt b/buildSrc/src/main/kotlin/net/modgarden/barricade/gradle/Versions.kt index d1427d4..3553118 100644 --- a/buildSrc/src/main/kotlin/net/modgarden/barricade/gradle/Versions.kt +++ b/buildSrc/src/main/kotlin/net/modgarden/barricade/gradle/Versions.kt @@ -1,7 +1,7 @@ package net.modgarden.barricade.gradle object Versions { - const val MOD = "2.0.7" + const val MOD = "2.1.0" const val MINECRAFT = "1.21.1" const val PARCHMENT_MINECRAFT = "1.21" From ffb7520b23ae438fc3cb7cfab2a61f854fdbb52b Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 17:54:14 -0400 Subject: [PATCH 04/18] refactor: Use a self-Mixin to DRY --- .../net/modgarden/barricade/Barricade.java | 3 +- .../barricade/block/PredicateBlock.java | 129 +++++++--------- .../barricade/block/PredicateLeverBlock.java | 141 ++---------------- .../barricade/item/PredicateBlockItem.java | 10 +- .../barricade/mixin/BlockAccessor.java | 21 --- .../mixin/BlockBehaviourAccessor.java | 17 +++ ...hedHorizontalDirectionalBlockAccessor.java | 15 -- .../HorizontalDirectionalBlockAccessor.java | 17 --- .../barricade/mixin/LeverBlockAccessor.java | 59 -------- .../mixin/PredicateBlockAccessor.java | 12 -- .../mixin/self/PredicateBlocksMixin.java | 90 +++++++++++ .../barricade/registry/BarricadeBlocks.java | 15 +- .../barricade/registry/BarricadeItems.java | 3 +- .../src/main/resources/barricade.mixins.json | 7 +- 14 files changed, 191 insertions(+), 348 deletions(-) delete mode 100644 common/src/main/java/net/modgarden/barricade/mixin/BlockAccessor.java create mode 100644 common/src/main/java/net/modgarden/barricade/mixin/BlockBehaviourAccessor.java delete mode 100644 common/src/main/java/net/modgarden/barricade/mixin/FaceAttachedHorizontalDirectionalBlockAccessor.java delete mode 100644 common/src/main/java/net/modgarden/barricade/mixin/HorizontalDirectionalBlockAccessor.java delete mode 100644 common/src/main/java/net/modgarden/barricade/mixin/LeverBlockAccessor.java delete mode 100644 common/src/main/java/net/modgarden/barricade/mixin/PredicateBlockAccessor.java create mode 100644 common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java diff --git a/common/src/main/java/net/modgarden/barricade/Barricade.java b/common/src/main/java/net/modgarden/barricade/Barricade.java index 0ef64d9..fe3e3f2 100644 --- a/common/src/main/java/net/modgarden/barricade/Barricade.java +++ b/common/src/main/java/net/modgarden/barricade/Barricade.java @@ -15,6 +15,7 @@ public class Barricade { public static final String MOD_ID = "barricade"; public static final String MOD_NAME = "Barricade"; public static final Logger LOG = LoggerFactory.getLogger(MOD_NAME); + public static final String MIXIN_NOT_APPLIED = "Mixin not applied"; private static BarricadePlatformHelper helper; public static boolean serverContext; @@ -36,4 +37,4 @@ public static BarricadePlatformHelper getHelper() { public static void setHelper(BarricadePlatformHelper helper) { Barricade.helper = helper; } -} \ No newline at end of file +} diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java index 0403fc0..ee40ffb 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java @@ -6,7 +6,6 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.RegistryAccess; -import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.BlockGetter; @@ -17,7 +16,8 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.EntityCollisionContext; import net.modgarden.barricade.Barricade; -import net.modgarden.silicate.api.SilicateRegistries; +import net.modgarden.barricade.mixin.BlockBehaviourAccessor; +import net.modgarden.barricade.mixin.self.PredicateBlocksMixin; import net.modgarden.silicate.api.condition.GameCondition; import net.modgarden.silicate.api.context.GameContext; import net.modgarden.silicate.api.context.param.ContextParamMap; @@ -27,57 +27,28 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.function.Function; +import static net.modgarden.barricade.Barricade.MIXIN_NOT_APPLIED; /** *

How to make a PredicateBlock

*
    - *
  1. Extend the PredicateBlock class and set T to the simulated block.
  2. - *
  3. Create constructors as shown in PredicateLeverBlock.
  4. - *
  5. Override all methods that your block and its superclasses override, then call those methods using accessors.
  6. - *
  7. Set up a method called registerState and call the methods as shown in PredicateLeverBlock
  8. + *
  9. Create a class extending the target block and implementing {@link PredicateBlock}.
  10. + *
  11. Create dummy constructors as shown in {@link PredicateLeverBlock}.
  12. + *
  13. Override the {@code codec} method and return a call to {@link PredicateBlock#mapCodec(Constructor)}, passing a reference to the second constructor.
  14. + *
  15. Add the class to the mixin targets in {@link PredicateBlocksMixin}.
  16. + *
  17. Override the server-authoritative methods and the client-side behavior methods.
  18. + *
  19. Add your logic by calling methods in {@link PredicateBlock}.
  20. *
- * @param The type of the block to simulate. */ -public abstract class PredicateBlock extends Block { - public static final ContextParamSet PARAM_SET = ContextParamSet.Builder +public interface PredicateBlock { + ContextParamSet PARAM_SET = ContextParamSet.Builder .of() .required(ContextParamTypes.THIS_ENTITY) .required(ContextParamTypes.BLOCK_STATE) .required(ContextParamTypes.ORIGIN) .build(); - private final T simulated; - private final ResourceLocation icon; - private final Function>> registryToCondition; - private Holder> condition; - - public PredicateBlock(T simulated, Properties properties, ResourceLocation icon, ResourceKey> conditionTemplate) { - super(properties); - this.simulated = simulated; - this.icon = icon; - this.registryToCondition = registryAccess -> registryAccess.registryOrThrow(SilicateRegistries.CONDITION_TEMPLATE).getHolderOrThrow(conditionTemplate); - } - - protected PredicateBlock(T simulated, Properties properties, ResourceLocation icon, Holder> condition) { - super(properties); - this.simulated = simulated; - this.icon = icon; - this.registryToCondition = null; - this.condition = condition; - } - - public ResourceLocation icon() { - return icon; - } - - public Holder> condition(RegistryAccess registries) { - if (condition == null && registryToCondition != null) - condition = registryToCondition.apply(registries); - return condition; - } - - public static GameContext newContext( + static GameContext newContext( @Nullable Level level, @NotNull Entity entity, BlockState state, @@ -92,46 +63,60 @@ public static GameContext newContext( return GameContext.of(level, paramMap); } + static @NotNull MapCodec mapCodec(PredicateBlock.Constructor constructor) { + return RecordCodecBuilder.mapCodec(instance -> instance.group( + BlockBehaviourAccessor.invokePropertiesCodec(), + ResourceLocation.CODEC + .fieldOf("icon") + .forGetter(PredicateBlock::barricade$icon), + GameCondition.CODEC + .fieldOf("condition") + .forGetter(PredicateBlock::barricade$rawCondition) + ).apply(instance, constructor)) + .xmap( + t -> { + // This is a downcast, so it's always safe. + //noinspection unchecked + return (S) t; + }, + s -> { + // This upcast is always safe because the object being deserialized + // would be of type T if using this codec. + //noinspection unchecked + return (T) s; + } + ); + } + + default ResourceLocation barricade$icon() { + throw new IllegalStateException(MIXIN_NOT_APPLIED); + } + + default Holder> barricade$condition(RegistryAccess registries) { + throw new IllegalStateException(MIXIN_NOT_APPLIED); + } + + default Holder> barricade$rawCondition() { + throw new IllegalStateException(MIXIN_NOT_APPLIED); + } + /** * @return Whether to let the entity interact (true) or block the entity's interaction (false). */ - public boolean test( + default boolean barricade$test( @Nullable Level level, @NotNull Entity entity, BlockState state, BlockPos pos ) throws InvalidContextParameterException { - // Inverted for compatibility with the old Predicate Barrier Block system - return !test(newContext(level, entity, state, pos)); - } - - public final boolean test(GameContext context) { - if (context.getLevel() == null) - return rawCondition() != null && rawCondition().value().test(context); - return this.condition(context.getLevel().registryAccess()).value().test(context); - } - - protected @NotNull MapCodec> mapCodec(Constructor constructor) { - return RecordCodecBuilder.mapCodec(instance -> instance.group( - BlockBehaviour.propertiesCodec(), - ResourceLocation.CODEC - .fieldOf("icon") - .forGetter(PredicateBlock::icon), - GameCondition.CODEC - .fieldOf("condition") - .forGetter(PredicateBlock::rawCondition) - ).apply(instance, constructor)); - } - - protected Holder> rawCondition() { - return condition; + throw new IllegalStateException(MIXIN_NOT_APPLIED); } - protected T simulated() { - return simulated; + default boolean barricade$test(GameContext context) { + throw new IllegalStateException(MIXIN_NOT_APPLIED); } - protected boolean isShaped( + default boolean isShaped( @NotNull BlockState state, @NotNull BlockGetter blockGetter, @NotNull BlockPos pos, @@ -144,7 +129,7 @@ protected boolean isShaped( } try { - if (!test(level, entityContext.getEntity(), state, pos)) { + if (!barricade$test(level, entityContext.getEntity(), state, pos)) { return false; } } catch (InvalidContextParameterException e) { @@ -156,8 +141,8 @@ protected boolean isShaped( // super mario in real life @FunctionalInterface - public interface Constructor extends Function3>, PredicateBlock> { + interface Constructor extends Function3>, T> { @Override - PredicateBlock apply(Properties properties, ResourceLocation icon, Holder> condition); + T apply(BlockBehaviour.Properties properties, ResourceLocation icon, Holder> condition); } } diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java index 1d1fbed..991e1df 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java @@ -2,92 +2,36 @@ import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.core.Holder; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.AttachFace; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import net.modgarden.barricade.mixin.BlockAccessor; -import net.modgarden.barricade.mixin.FaceAttachedHorizontalDirectionalBlockAccessor; -import net.modgarden.barricade.mixin.HorizontalDirectionalBlockAccessor; -import net.modgarden.barricade.mixin.LeverBlockAccessor; import net.modgarden.silicate.api.condition.GameCondition; import net.modgarden.silicate.api.exception.InvalidContextParameterException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.function.BiConsumer; - -public class PredicateLeverBlock extends PredicateBlock { - private static final LeverBlock DEFAULT_SIMULATED = (LeverBlock) Blocks.LEVER; - public static final Properties PROPERTIES = Properties.ofFullCopy(Blocks.LEVER); - - public PredicateLeverBlock(ResourceLocation icon, ResourceKey> conditionTemplate) { - super(LeverBlockAccessor.init(PROPERTIES), PROPERTIES, icon, conditionTemplate); - registerState(); +public class PredicateLeverBlock extends LeverBlock implements PredicateBlock { + @SuppressWarnings("unused") + public PredicateLeverBlock(Properties properties, ResourceLocation icon, ResourceKey> conditionTemplate) { + super(properties); } protected PredicateLeverBlock(Properties properties, ResourceLocation icon, Holder> condition) { - super(LeverBlockAccessor.init(properties), properties, icon, condition); - registerState(); - } - - private void registerState() { - this.registerDefaultState( - this.stateDefinition.any().setValue(HorizontalDirectionalBlock.FACING, Direction.NORTH).setValue(LeverBlock.POWERED, Boolean.FALSE).setValue(LeverBlock.FACE, AttachFace.WALL) - ); - ((BlockAccessor) simulated()).setDefaultBlockState(this.defaultBlockState()); - ((BlockAccessor) simulated()).setBuiltInRegistryHolder(((BlockAccessor) this).getBuiltInRegistryHolder()); + super(properties); } @Override - protected @NotNull MapCodec codec() { - return mapCodec(PredicateLeverBlock::new); - } - - @SuppressWarnings("deprecation") - @Override - protected @NotNull BlockState rotate(@NotNull BlockState state, @NotNull Rotation rotation) { - return ((HorizontalDirectionalBlockAccessor) simulated()).invokeRotate(state, rotation); - } - - @SuppressWarnings("deprecation") - @Override - protected @NotNull BlockState mirror(@NotNull BlockState state, @NotNull Mirror mirror) { - return ((HorizontalDirectionalBlockAccessor) simulated()).invokeMirror(state, mirror); - } - - @Override - public @Nullable BlockState getStateForPlacement(@NotNull BlockPlaceContext context) { - return simulated().getStateForPlacement(context); - } - - @Override - protected @NotNull BlockState updateShape( - @NotNull BlockState state, - @NotNull Direction direction, - @NotNull BlockState neighborState, - @NotNull LevelAccessor level, - @NotNull BlockPos pos, - @NotNull BlockPos neighborPos - ) { - return ((FaceAttachedHorizontalDirectionalBlockAccessor) simulated()).invokeUpdateShape(state, direction, neighborState, level, pos, neighborPos); + public @NotNull MapCodec codec() { + return PredicateBlock.mapCodec(PredicateLeverBlock::new); } @Override @@ -98,7 +42,7 @@ private void registerState() { @NotNull CollisionContext context ) { if (this.isShaped(state, blockGetter, pos, context)) { - return ((LeverBlockAccessor) simulated()).invokeGetShape(state, blockGetter, pos, context); + return super.getShape(state, blockGetter, pos, context); } else { return Shapes.empty(); } @@ -113,8 +57,8 @@ private void registerState() { @NotNull BlockHitResult hitResult ) { try { - if (level.isClientSide() || test(level, player, state, pos)) { - return ((LeverBlockAccessor) simulated()).invokeUseWithoutItem(state, level, pos, player, hitResult); + if (level.isClientSide() || this.barricade$test(level, player, state, pos)) { + return super.useWithoutItem(state, level, pos, player, hitResult); } else { return InteractionResult.PASS; } @@ -122,69 +66,4 @@ private void registerState() { throw new RuntimeException(e); } } - - @Override - protected void onExplosionHit( - @NotNull BlockState state, - @NotNull Level level, - @NotNull BlockPos pos, - @NotNull Explosion explosion, - @NotNull BiConsumer dropConsumer - ) { - ((LeverBlockAccessor) simulated()).invokeOnExplosionHit(state, level, pos, explosion, dropConsumer); - } - - @Override - public void animateTick( - @NotNull BlockState state, - @NotNull Level level, - @NotNull BlockPos pos, - @NotNull RandomSource random - ) { - ((LeverBlockAccessor) simulated()).invokeAnimateTick(state, level, pos, random); - } - - @Override - protected void onRemove( - @NotNull BlockState state, - @NotNull Level level, - @NotNull BlockPos pos, - @NotNull BlockState newState, - boolean movedByPiston - ) { - ((LeverBlockAccessor) simulated()).invokeOnRemove(state, level, pos, newState, movedByPiston); - } - - @SuppressWarnings("deprecation") - @Override - protected int getSignal( - @NotNull BlockState state, - @NotNull BlockGetter level, - @NotNull BlockPos pos, - @NotNull Direction direction - ) { - return ((LeverBlockAccessor) simulated()).invokeGetSignal(state, level, pos, direction); - } - - @SuppressWarnings("deprecation") - @Override - protected int getDirectSignal( - @NotNull BlockState state, - @NotNull BlockGetter level, - @NotNull BlockPos pos, - @NotNull Direction direction - ) { - return ((LeverBlockAccessor) simulated()).invokeGetDirectSignal(state, level, pos, direction); - } - - @SuppressWarnings("deprecation") - @Override - protected boolean isSignalSource(@NotNull BlockState state) { - return ((LeverBlockAccessor) simulated()).invokeIsSignalSource(state); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.@NotNull Builder builder) { - ((LeverBlockAccessor) DEFAULT_SIMULATED).invokeCreateBlockStateDefinition(builder); - } } diff --git a/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java b/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java index 54025d5..96cb5c8 100644 --- a/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java +++ b/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java @@ -9,8 +9,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class PredicateBlockItem> extends BlockItem { - public PredicateBlockItem(S block, Properties properties) { +public class PredicateBlockItem extends BlockItem { + public PredicateBlockItem(T block, Properties properties) { super(block, properties); } @@ -18,7 +18,7 @@ public PredicateBlockItem(S block, Properties properties) { protected boolean canPlace(@NotNull BlockPlaceContext context, @NotNull BlockState state) { if (super.canPlace(context, state) && context.getPlayer() != null) { try { - return this.getBlock().test(context.getLevel(), context.getPlayer(), state, context.getClickedPos()); + return this.getBlock().barricade$test(context.getLevel(), context.getPlayer(), state, context.getClickedPos()); } catch (InvalidContextParameterException e) { throw new RuntimeException(e); } @@ -34,7 +34,7 @@ protected boolean canPlace(@NotNull BlockPlaceContext context, @NotNull BlockSta @SuppressWarnings("unchecked") // It is illegal to have a this.block field not of type S @Override - public @NotNull S getBlock() { - return (S) super.getBlock(); + public @NotNull T getBlock() { + return (T) super.getBlock(); } } diff --git a/common/src/main/java/net/modgarden/barricade/mixin/BlockAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/BlockAccessor.java deleted file mode 100644 index 5f81ff6..0000000 --- a/common/src/main/java/net/modgarden/barricade/mixin/BlockAccessor.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.modgarden.barricade.mixin; - -import net.minecraft.core.Holder; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(Block.class) -public interface BlockAccessor { - @Accessor - void setDefaultBlockState(BlockState state); - - @Mutable - @Accessor - void setBuiltInRegistryHolder(Holder.Reference reference); - - @Accessor - Holder.Reference getBuiltInRegistryHolder(); -} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/BlockBehaviourAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/BlockBehaviourAccessor.java new file mode 100644 index 0000000..d2ec519 --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/mixin/BlockBehaviourAccessor.java @@ -0,0 +1,17 @@ +package net.modgarden.barricade.mixin; + +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import static net.modgarden.barricade.Barricade.MIXIN_NOT_APPLIED; + +@Mixin(BlockBehaviour.class) +public interface BlockBehaviourAccessor { + @Invoker + static RecordCodecBuilder invokePropertiesCodec() { + throw new IllegalStateException(MIXIN_NOT_APPLIED); + } +} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/FaceAttachedHorizontalDirectionalBlockAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/FaceAttachedHorizontalDirectionalBlockAccessor.java deleted file mode 100644 index 836c033..0000000 --- a/common/src/main/java/net/modgarden/barricade/mixin/FaceAttachedHorizontalDirectionalBlockAccessor.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.modgarden.barricade.mixin; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.FaceAttachedHorizontalDirectionalBlock; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(FaceAttachedHorizontalDirectionalBlock.class) -public interface FaceAttachedHorizontalDirectionalBlockAccessor { - @Invoker - BlockState invokeUpdateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor level, BlockPos currentPos, BlockPos facingPos); -} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/HorizontalDirectionalBlockAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/HorizontalDirectionalBlockAccessor.java deleted file mode 100644 index 81f994d..0000000 --- a/common/src/main/java/net/modgarden/barricade/mixin/HorizontalDirectionalBlockAccessor.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.modgarden.barricade.mixin; - -import net.minecraft.world.level.block.HorizontalDirectionalBlock; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(HorizontalDirectionalBlock.class) -public interface HorizontalDirectionalBlockAccessor { - @Invoker - BlockState invokeRotate(BlockState state, Rotation rot); - - @Invoker - BlockState invokeMirror(BlockState state, Mirror mirror); -} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/LeverBlockAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/LeverBlockAccessor.java deleted file mode 100644 index 03fa065..0000000 --- a/common/src/main/java/net/modgarden/barricade/mixin/LeverBlockAccessor.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.modgarden.barricade.mixin; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.util.RandomSource; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Explosion; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LeverBlock; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import org.jetbrains.annotations.NotNull; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -import java.util.function.BiConsumer; - -@Mixin(LeverBlock.class) -public interface LeverBlockAccessor { - @Invoker("") - static LeverBlock init(BlockBehaviour.Properties properties) { - throw new UnsupportedOperationException("Mixin not applied"); - } - - @Invoker - @NotNull VoxelShape invokeGetShape(@NotNull BlockState state, @NotNull BlockGetter blockGetter, @NotNull BlockPos pos, @NotNull CollisionContext context); - - @Invoker - InteractionResult invokeUseWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult); - - @Invoker - void invokeOnExplosionHit(BlockState state, Level level, BlockPos pos, Explosion explosion, BiConsumer dropConsumer); - - @Invoker - void invokeAnimateTick(BlockState state, Level level, BlockPos pos, RandomSource random); - - @Invoker - void invokeOnRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving); - - @Invoker - int invokeGetSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side); - - @Invoker - int invokeGetDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side); - - @Invoker - boolean invokeIsSignalSource(BlockState state); - - @Invoker - void invokeCreateBlockStateDefinition(StateDefinition.Builder builder); -} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/PredicateBlockAccessor.java b/common/src/main/java/net/modgarden/barricade/mixin/PredicateBlockAccessor.java deleted file mode 100644 index bdf7c40..0000000 --- a/common/src/main/java/net/modgarden/barricade/mixin/PredicateBlockAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.modgarden.barricade.mixin; - -import net.minecraft.world.level.block.Block; -import net.modgarden.barricade.block.PredicateBlock; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(PredicateBlock.class) -public interface PredicateBlockAccessor { - @Accessor - Block getSimulated(); -} diff --git a/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java b/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java new file mode 100644 index 0000000..7a4c05d --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java @@ -0,0 +1,90 @@ +package net.modgarden.barricade.mixin.self; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.modgarden.barricade.block.PredicateBlock; +import net.modgarden.barricade.block.PredicateLeverBlock; +import net.modgarden.silicate.api.SilicateRegistries; +import net.modgarden.silicate.api.condition.GameCondition; +import net.modgarden.silicate.api.context.GameContext; +import net.modgarden.silicate.api.exception.InvalidContextParameterException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.function.Function; + +@Mixin({PredicateLeverBlock.class}) +public class PredicateBlocksMixin implements PredicateBlock { + @Unique + private ResourceLocation barricade$icon; + @Unique + private Function>> barricade$registryToCondition; + @Unique + private Holder> barricade$condition; + + @Inject( + method = "(Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceKey;)V", + at = @At("CTOR_HEAD") + ) + private void init(BlockBehaviour.Properties properties, ResourceLocation icon, ResourceKey> conditionTemplate, CallbackInfo ci) { + this.barricade$icon = icon; + this.barricade$registryToCondition = registryAccess -> registryAccess.registryOrThrow(SilicateRegistries.CONDITION_TEMPLATE).getHolderOrThrow(conditionTemplate); + } + + @Inject( + method = "(Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/core/Holder;)V", + at = @At("CTOR_HEAD") + ) + private void init(BlockBehaviour.Properties properties, ResourceLocation icon, Holder> condition, CallbackInfo ci) { + this.barricade$icon = icon; + this.barricade$registryToCondition = null; + this.barricade$condition = condition; + } + + @Override + public ResourceLocation barricade$icon() { + return barricade$icon; + } + + @Override + public Holder> barricade$condition(RegistryAccess registries) { + if (barricade$condition == null && barricade$registryToCondition != null) + barricade$condition = barricade$registryToCondition.apply(registries); + return barricade$condition; + } + + @Override + public boolean barricade$test( + @Nullable Level level, + @NotNull Entity entity, + BlockState state, + BlockPos pos + ) throws InvalidContextParameterException { + // Inverted for compatibility with the old Predicate Barrier Block system + return !barricade$test(PredicateBlock.newContext(level, entity, state, pos)); + } + + @Override + public final boolean barricade$test(GameContext context) { + if (context.getLevel() == null) + return barricade$rawCondition() != null && barricade$rawCondition().value().test(context); + return this.barricade$condition(context.getLevel().registryAccess()).value().test(context); + } + + @Override + public Holder> barricade$rawCondition() { + return barricade$condition; + } +} diff --git a/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java b/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java index a1723e3..a4b6d34 100644 --- a/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java +++ b/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java @@ -10,9 +10,9 @@ import net.modgarden.barricade.Barricade; import net.modgarden.barricade.block.*; import net.modgarden.barricade.data.BlockedDirections; -import net.modgarden.barricade.mixin.PredicateBlockAccessor; import net.modgarden.silicate.api.SilicateRegistries; import net.modgarden.silicate.api.condition.GameCondition; +import org.jetbrains.annotations.NotNull; public class BarricadeBlocks { public static final AdvancedBarrierBlock ADVANCED_BARRIER = new AdvancedBarrierBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); @@ -61,6 +61,7 @@ public class BarricadeBlocks { // Predicate Levers public static final PredicateLeverBlock CREATIVE_ONLY_LEVER = new PredicateLeverBlock( + leverProps(), Barricade.asResource("barricade/icon/iron_sword"), conditionTemplate("creative_only") ); @@ -84,13 +85,7 @@ public static void registerAll() { Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("creative_only_barrier"), CREATIVE_ONLY_BARRIER); - registerPredicate("creative_only_lever", CREATIVE_ONLY_LEVER); - } - - private static > void registerPredicate(String name, S block) { - register(name, block); - // https://github.com/reactjs/react.dev/issues/3896 - register("zz__" + name + "_secret_block_do_not_use_or_you_will_be_fired", ((PredicateBlockAccessor) block).getSimulated()); + register("creative_only_lever", CREATIVE_ONLY_LEVER); } private static void register(String name, Block block) { @@ -103,4 +98,8 @@ private static ResourceKey> conditionTemplate(String name) { Barricade.asResource(name) ); } + + private static BlockBehaviour.@NotNull Properties leverProps() { + return BlockBehaviour.Properties.ofFullCopy(Blocks.LEVER); + } } diff --git a/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java b/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java index 3965c68..c0cf4b0 100644 --- a/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java +++ b/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java @@ -5,7 +5,6 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.Rarity; -import net.minecraft.world.level.block.LeverBlock; import net.modgarden.barricade.Barricade; import net.modgarden.barricade.block.PredicateLeverBlock; import net.modgarden.barricade.item.AdvancedBarrierBlockItem; @@ -38,7 +37,7 @@ public class BarricadeItems { ); // Predicate Levers - public static final PredicateBlockItem CREATIVE_ONLY_LEVER = new PredicateBlockItem<>( + public static final PredicateBlockItem CREATIVE_ONLY_LEVER = new PredicateBlockItem<>( BarricadeBlocks.CREATIVE_ONLY_LEVER, barrierProps() ); diff --git a/common/src/main/resources/barricade.mixins.json b/common/src/main/resources/barricade.mixins.json index 98efb8d..67ebbc5 100644 --- a/common/src/main/resources/barricade.mixins.json +++ b/common/src/main/resources/barricade.mixins.json @@ -6,14 +6,11 @@ "compatibilityLevel": "JAVA_21", "mixins": [ "AbstractArrowMixin", - "BlockAccessor", + "BlockBehaviourAccessor", "BlockBehaviourBlockStateBaseMixin", "BlockBehaviourMixin", "BlockMixin", - "FaceAttachedHorizontalDirectionalBlockAccessor", - "HorizontalDirectionalBlockAccessor", - "LeverBlockAccessor", - "PredicateBlockAccessor" + "self.PredicateBlocksMixin" ], "client": [ "client.ClientChunkCacheAccessor", From a5c6f25966fcfe5b023f1bbfb879923c3ba3d5af Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 18:31:40 -0400 Subject: [PATCH 05/18] build(gradle): Enable Mixin hotswapping + Enhanced Class Redefinition (for JBR/DCEVM) --- fabric/build.gradle.kts | 18 ++++++++++++++++++ neoforge/build.gradle.kts | 3 +++ 2 files changed, 21 insertions(+) diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index 429e93d..5a374f4 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -59,6 +59,24 @@ loom { } } runs { + afterEvaluate { + val mixinJarFile = configurations.runtimeClasspath.get().incoming.artifactView { + componentFilter { + it is ModuleComponentIdentifier && it.group == "net.fabricmc" && it.module == "sponge-mixin" + } + }.files.first() + + configureEach { + // Mixin hotswapping + vmArg("-javaagent:$mixinJarFile") + + property("mixin.hotSwap", "true") + property("mixin.debug.export", "true") + + // Class redefinition (for JBR/DCEVM) + vmArg("-XX:+AllowEnhancedClassRedefinition") + } + } named("client") { client() configName = "Fabric Client" diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index e470ee1..c1f0c2b 100644 --- a/neoforge/build.gradle.kts +++ b/neoforge/build.gradle.kts @@ -55,6 +55,9 @@ neoForge { systemProperty("forge.logging.markers", "REGISTRIES") systemProperty("forge.logging.console.level", "debug") systemProperty("neoforge.enabledGameTestNamespaces", Properties.MOD_ID) + + // Class redefinition (for JBR/DCEVM) + jvmArgument("-XX:+AllowEnhancedClassRedefinition") } create("client") { client() From 7294e30df7ef53d7d7a58ac0e3e4c20f9a5fc677 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 19:12:54 -0400 Subject: [PATCH 06/18] fix: Don't cache registry accesses --- .../block/PredicateBarrierBlock.java | 12 ++++---- .../barricade/block/PredicateBlock.java | 2 +- .../mixin/self/PredicateBlocksMixin.java | 29 ++++++++++++------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java index 7c13c78..e730d7f 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java @@ -57,13 +57,17 @@ public class PredicateBarrierBlock extends BarrierBlock { public PredicateBarrierBlock(Properties properties, ResourceLocation icon, ResourceKey> conditionTemplate) { super(properties); this.icon = icon; - this.function = registryAccess -> registryAccess.registryOrThrow(SilicateRegistries.CONDITION_TEMPLATE).getHolderOrThrow(conditionTemplate); + this.function = registryAccess -> { + Holder> condition = registryAccess.registryOrThrow(SilicateRegistries.CONDITION_TEMPLATE).getHolderOrThrow(conditionTemplate); + this.condition = condition; + return condition; + }; } private PredicateBarrierBlock(Properties properties, ResourceLocation icon, Holder> condition) { super(properties); this.icon = icon; - this.function = null; + this.function = registryAccess -> condition; this.condition = condition; } @@ -72,9 +76,7 @@ public ResourceLocation icon() { } public Holder> condition(RegistryAccess registries) { - if (condition == null && function != null) - condition = function.apply(registries); - return condition; + return function.apply(registries); } private Holder> rawCondition() { diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java index ee40ffb..fb75dcc 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java @@ -96,7 +96,7 @@ static GameContext newContext( throw new IllegalStateException(MIXIN_NOT_APPLIED); } - default Holder> barricade$rawCondition() { + default @Nullable Holder> barricade$rawCondition() { throw new IllegalStateException(MIXIN_NOT_APPLIED); } diff --git a/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java b/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java index 7a4c05d..c05f13e 100644 --- a/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java +++ b/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java @@ -40,7 +40,11 @@ public class PredicateBlocksMixin implements PredicateBlock { ) private void init(BlockBehaviour.Properties properties, ResourceLocation icon, ResourceKey> conditionTemplate, CallbackInfo ci) { this.barricade$icon = icon; - this.barricade$registryToCondition = registryAccess -> registryAccess.registryOrThrow(SilicateRegistries.CONDITION_TEMPLATE).getHolderOrThrow(conditionTemplate); + this.barricade$registryToCondition = registryAccess -> { + Holder> condition = registryAccess.registryOrThrow(SilicateRegistries.CONDITION_TEMPLATE).getHolderOrThrow(conditionTemplate); + barricade$condition = condition; + return condition; + }; } @Inject( @@ -49,7 +53,7 @@ private void init(BlockBehaviour.Properties properties, ResourceLocation icon, R ) private void init(BlockBehaviour.Properties properties, ResourceLocation icon, Holder> condition, CallbackInfo ci) { this.barricade$icon = icon; - this.barricade$registryToCondition = null; + this.barricade$registryToCondition = registryAccess -> condition; this.barricade$condition = condition; } @@ -60,8 +64,11 @@ private void init(BlockBehaviour.Properties properties, ResourceLocation icon, H @Override public Holder> barricade$condition(RegistryAccess registries) { - if (barricade$condition == null && barricade$registryToCondition != null) - barricade$condition = barricade$registryToCondition.apply(registries); + return barricade$registryToCondition.apply(registries); + } + + @Override + public @Nullable Holder> barricade$rawCondition() { return barricade$condition; } @@ -78,13 +85,13 @@ private void init(BlockBehaviour.Properties properties, ResourceLocation icon, H @Override public final boolean barricade$test(GameContext context) { - if (context.getLevel() == null) - return barricade$rawCondition() != null && barricade$rawCondition().value().test(context); - return this.barricade$condition(context.getLevel().registryAccess()).value().test(context); - } + if (context.getLevel() == null) { + // IntelliJ doesn't see the null check. + //noinspection DataFlowIssue + return this.barricade$rawCondition() != null && this.barricade$rawCondition().value().test(context); + } - @Override - public Holder> barricade$rawCondition() { - return barricade$condition; + Holder> condition = this.barricade$condition(context.getLevel().registryAccess()); + return condition.value().test(context); } } From d3f8032a8c78db524064dbb66213c5d64626f4e8 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 19:13:21 -0400 Subject: [PATCH 07/18] chore: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d25591..2684ec6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,3 @@ ## Bugfixes - typo: `condition` field (previously `conditions`) in `PredicateBarrierBlock` +- fix: Don't cache registry accesses From fdae015021a8c819a8171200bdc59718275c214a Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 19:27:55 -0400 Subject: [PATCH 08/18] fix: remove duplicate JVM parameter --- fabric/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index 5a374f4..ced274a 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -71,7 +71,6 @@ loom { vmArg("-javaagent:$mixinJarFile") property("mixin.hotSwap", "true") - property("mixin.debug.export", "true") // Class redefinition (for JBR/DCEVM) vmArg("-XX:+AllowEnhancedClassRedefinition") From d34da7461e76cd4328b16d47b1a4c55d7e545bdc Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 19:28:04 -0400 Subject: [PATCH 09/18] docs: Add requirement for DCEVM JDK. --- CONTRIBUTING.md | 6 ++++++ README.md | 3 +++ 2 files changed, 9 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..f1f6aee --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,6 @@ +# Contribution Guide +Hello, contributor! There are a few things you need to know before contributing to Barricade. + +## JDK +You will need the [JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime) or a JDK with DCEVM support. +If you use IntelliJ, you can download the JBR through the GUI. You can change the JDK in IntelliJ in File → Project Structure → Project → SDK. diff --git a/README.md b/README.md index 930e0e6..5f33169 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ This mod may also change barrier and light block rendering, to be friendlier to You can enable/disable the above by applying/removing the Barricade Rendering resource pack. +## Contribution +Please read the `CONTRIBUTING.md` document before contributing or if you have any issues building the mod. + ## Client-side Only This mod is able to run on clients without having it on the server. When run like this, the mod will only apply the From 664b50f4d33f8d1207bcb2f8836256d0aa754b65 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 19:41:30 -0400 Subject: [PATCH 10/18] refactor: Use helper methods in registration --- .../barricade/registry/BarricadeBlocks.java | 76 +++++++++---------- .../barricade/registry/BarricadeItems.java | 28 +++---- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java b/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java index a4b6d34..6826c4f 100644 --- a/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java +++ b/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java @@ -15,48 +15,43 @@ import org.jetbrains.annotations.NotNull; public class BarricadeBlocks { - public static final AdvancedBarrierBlock ADVANCED_BARRIER = new AdvancedBarrierBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); + public static final AdvancedBarrierBlock ADVANCED_BARRIER = new AdvancedBarrierBlock(barrierProps()); - public static final DirectionalBarrierBlock DOWN_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.DOWN), BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); - public static final DirectionalBarrierBlock UP_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.UP), BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); - public static final DirectionalBarrierBlock SOUTH_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.SOUTH), BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); - public static final DirectionalBarrierBlock NORTH_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.NORTH), BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); - public static final DirectionalBarrierBlock EAST_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.EAST), BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); - public static final DirectionalBarrierBlock WEST_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.WEST), BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); - public static final DirectionalBarrierBlock HORIZONTAL_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.WEST, Direction.EAST, Direction.NORTH, Direction.SOUTH), BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); - public static final DirectionalBarrierBlock VERTICAL_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.UP, Direction.DOWN), BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER).dynamicShape()); + public static final DirectionalBarrierBlock DOWN_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.DOWN), barrierProps()); + public static final DirectionalBarrierBlock UP_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.UP), barrierProps()); + public static final DirectionalBarrierBlock SOUTH_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.SOUTH), barrierProps()); + public static final DirectionalBarrierBlock NORTH_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.NORTH), barrierProps()); + public static final DirectionalBarrierBlock EAST_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.EAST), barrierProps()); + public static final DirectionalBarrierBlock WEST_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.WEST), barrierProps()); + public static final DirectionalBarrierBlock HORIZONTAL_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.WEST, Direction.EAST, Direction.NORTH, Direction.SOUTH), barrierProps()); + public static final DirectionalBarrierBlock VERTICAL_BARRIER = new DirectionalBarrierBlock(BlockedDirections.of(Direction.UP, Direction.DOWN), barrierProps()); // Predicate Barriers public static final PredicateBarrierBlock CREATIVE_ONLY_BARRIER = new PredicateBarrierBlock( - BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER) - .dynamicShape(), + barrierProps(), Barricade.asResource("barricade/icon/iron_sword"), - ResourceKey.create(SilicateRegistries.CONDITION_TEMPLATE, Barricade.asResource("creative_only")) + conditionTemplate("creative_only") ); public static final PredicateBarrierBlock PLAYER_BARRIER = new PredicateBarrierBlock( - BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER) - .dynamicShape(), + barrierProps(), Barricade.asResource("barricade/icon/steve"), - ResourceKey.create(SilicateRegistries.CONDITION_TEMPLATE, Barricade.asResource("player")) + conditionTemplate("player") ); public static final PredicateBarrierBlock MOB_BARRIER = new PredicateBarrierBlock( - BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER) - .dynamicShape(), + barrierProps(), Barricade.asResource("barricade/icon/pig"), - ResourceKey.create(SilicateRegistries.CONDITION_TEMPLATE, Barricade.asResource("mob")) + conditionTemplate("mob") ); public static final PredicateBarrierBlock PASSIVE_BARRIER = new PredicateBarrierBlock( - BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER) - .dynamicShape(), + barrierProps(), Barricade.asResource("barricade/icon/parrot"), - ResourceKey.create(SilicateRegistries.CONDITION_TEMPLATE, Barricade.asResource("passive")) + conditionTemplate("passive") ); public static final PredicateBarrierBlock HOSTILE_BARRIER = new PredicateBarrierBlock( - BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER) - .dynamicShape(), + barrierProps(), Barricade.asResource("barricade/icon/creeper"), - ResourceKey.create(SilicateRegistries.CONDITION_TEMPLATE, Barricade.asResource("hostile")) + conditionTemplate("hostile") ); // Predicate Levers @@ -67,23 +62,23 @@ public class BarricadeBlocks { ); public static void registerAll() { - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("advanced_barrier"), ADVANCED_BARRIER); + register("advanced_barrier", ADVANCED_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("down_barrier"), DOWN_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("up_barrier"), UP_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("south_barrier"), SOUTH_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("north_barrier"), NORTH_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("east_barrier"), EAST_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("west_barrier"), WEST_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("horizontal_barrier"), HORIZONTAL_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("vertical_barrier"), VERTICAL_BARRIER); + register("down_barrier", DOWN_BARRIER); + register("up_barrier", UP_BARRIER); + register("south_barrier", SOUTH_BARRIER); + register("north_barrier", NORTH_BARRIER); + register("east_barrier", EAST_BARRIER); + register("west_barrier", WEST_BARRIER); + register("horizontal_barrier", HORIZONTAL_BARRIER); + register("vertical_barrier", VERTICAL_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("player_barrier"), PLAYER_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("mob_barrier"), MOB_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("passive_barrier"), PASSIVE_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("hostile_barrier"), HOSTILE_BARRIER); + register("player_barrier", PLAYER_BARRIER); + register("mob_barrier", MOB_BARRIER); + register("passive_barrier", PASSIVE_BARRIER); + register("hostile_barrier", HOSTILE_BARRIER); - Registry.register(BuiltInRegistries.BLOCK, Barricade.asResource("creative_only_barrier"), CREATIVE_ONLY_BARRIER); + register("creative_only_barrier", CREATIVE_ONLY_BARRIER); register("creative_only_lever", CREATIVE_ONLY_LEVER); } @@ -99,6 +94,11 @@ private static ResourceKey> conditionTemplate(String name) { ); } + private static BlockBehaviour.@NotNull Properties barrierProps() { + return BlockBehaviour.Properties.ofFullCopy(Blocks.BARRIER) + .dynamicShape(); + } + private static BlockBehaviour.@NotNull Properties leverProps() { return BlockBehaviour.Properties.ofFullCopy(Blocks.LEVER); } diff --git a/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java b/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java index c0cf4b0..7527dfb 100644 --- a/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java +++ b/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java @@ -43,23 +43,23 @@ public class BarricadeItems { ); public static void registerAll() { - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("advanced_barrier"), ADVANCED_BARRIER); + register("advanced_barrier", ADVANCED_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("down_barrier"), DOWN_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("up_barrier"), UP_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("south_barrier"), SOUTH_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("north_barrier"), NORTH_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("east_barrier"), EAST_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("west_barrier"), WEST_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("horizontal_barrier"), HORIZONTAL_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("vertical_barrier"), VERTICAL_BARRIER); + register("down_barrier", DOWN_BARRIER); + register("up_barrier", UP_BARRIER); + register("south_barrier", SOUTH_BARRIER); + register("north_barrier", NORTH_BARRIER); + register("east_barrier", EAST_BARRIER); + register("west_barrier", WEST_BARRIER); + register("horizontal_barrier", HORIZONTAL_BARRIER); + register("vertical_barrier", VERTICAL_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("player_barrier"), PLAYER_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("mob_barrier"), MOB_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("passive_barrier"), PASSIVE_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("hostile_barrier"), HOSTILE_BARRIER); + register("player_barrier", PLAYER_BARRIER); + register("mob_barrier", MOB_BARRIER); + register("passive_barrier", PASSIVE_BARRIER); + register("hostile_barrier", HOSTILE_BARRIER); - Registry.register(BuiltInRegistries.ITEM, Barricade.asResource("creative_only_barrier"), CREATIVE_ONLY_BARRIER); + register("creative_only_barrier", CREATIVE_ONLY_BARRIER); register("creative_only_lever", CREATIVE_ONLY_LEVER); } From 90aade6ad63e5e71a9e5d0752cb587836b499b8f Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 20:09:56 -0400 Subject: [PATCH 11/18] refactor: Use new system with PredicateBarrierBlock --- .../block/PredicateBarrierBlock.java | 134 ++---------------- .../barricade/block/PredicateBlock.java | 4 + .../barricade/data/AdvancedBarrier.java | 4 +- .../mixin/client/ClientLevelMixin.java | 2 +- .../mixin/self/PredicateBlocksMixin.java | 3 +- 5 files changed, 22 insertions(+), 125 deletions(-) diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java index e730d7f..4cd6c58 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateBarrierBlock.java @@ -1,94 +1,38 @@ package net.modgarden.barricade.block; import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Holder; -import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BarrierBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.EntityCollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import net.modgarden.barricade.Barricade; -import net.modgarden.silicate.api.SilicateRegistries; import net.modgarden.silicate.api.condition.GameCondition; -import net.modgarden.silicate.api.context.GameContext; -import net.modgarden.silicate.api.context.param.ContextParamMap; -import net.modgarden.silicate.api.context.param.ContextParamSet; -import net.modgarden.silicate.api.context.param.ContextParamTypes; -import net.modgarden.silicate.api.exception.InvalidContextParameterException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.function.Function; /** * A type of {@link BarrierBlock} that uses {@link GameCondition} to determine if an entity collides. */ -public class PredicateBarrierBlock extends BarrierBlock { - private static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - propertiesCodec(), - ResourceLocation.CODEC - .fieldOf("icon") - .forGetter(PredicateBarrierBlock::icon), - GameCondition.CODEC - .fieldOf("condition") - .forGetter(PredicateBarrierBlock::rawCondition) - ).apply(instance, PredicateBarrierBlock::new)); - public static final ContextParamSet PARAM_SET = ContextParamSet.Builder - .of() - .required(ContextParamTypes.THIS_ENTITY) - .required(ContextParamTypes.BLOCK_STATE) - .required(ContextParamTypes.ORIGIN) - .build(); - private final ResourceLocation icon; - private final Function>> function; - private Holder> condition; - +public class PredicateBarrierBlock extends BarrierBlock implements PredicateBlock { + @SuppressWarnings("unused") public PredicateBarrierBlock(Properties properties, ResourceLocation icon, ResourceKey> conditionTemplate) { super(properties); - this.icon = icon; - this.function = registryAccess -> { - Holder> condition = registryAccess.registryOrThrow(SilicateRegistries.CONDITION_TEMPLATE).getHolderOrThrow(conditionTemplate); - this.condition = condition; - return condition; - }; } private PredicateBarrierBlock(Properties properties, ResourceLocation icon, Holder> condition) { super(properties); - this.icon = icon; - this.function = registryAccess -> condition; - this.condition = condition; - } - - public ResourceLocation icon() { - return icon; - } - - public Holder> condition(RegistryAccess registries) { - return function.apply(registries); - } - - private Holder> rawCondition() { - return condition; } @Override public @NotNull MapCodec codec() { - return CODEC.xmap( - properties -> properties, - block -> (PredicateBarrierBlock) block - ); + return PredicateBlock.mapCodec(PredicateBarrierBlock::new); } @Override @@ -96,39 +40,6 @@ protected boolean skipRendering(BlockState state, BlockState adjacentState, @Not return adjacentState.is(state.getBlock()); } - /** - * @return Whether to let the entity pass (true) or block the entity (false). - */ - public boolean test( - @Nullable Level level, - @NotNull Entity entity, - BlockState state, - BlockPos pos - ) throws InvalidContextParameterException { - return !test(newContext(level, entity, state, pos)); - } - - public boolean test(GameContext context) { - if (context.getLevel() == null) - return rawCondition() != null && rawCondition().value().test(context); - return this.condition(context.getLevel().registryAccess()).value().test(context); - } - - public static GameContext newContext( - @Nullable Level level, - @NotNull Entity entity, - BlockState state, - BlockPos pos - ) throws InvalidContextParameterException { - ContextParamMap paramMap = ContextParamMap.Builder - .of(PARAM_SET) - .withParameter(ContextParamTypes.THIS_ENTITY, entity) - .withParameter(ContextParamTypes.BLOCK_STATE, state) - .withParameter(ContextParamTypes.ORIGIN, pos.getCenter()) - .build(); - return GameContext.of(level, paramMap); - } - @Override protected @NotNull VoxelShape getCollisionShape( @NotNull BlockState state, @@ -136,21 +47,11 @@ public static GameContext newContext( @NotNull BlockPos pos, @NotNull CollisionContext context ) { - if (context instanceof EntityCollisionContext entityContext && entityContext.getEntity() != null) { - Level level = null; - if (blockGetter instanceof Level) { - level = (Level) blockGetter; - } - - try { - if (test(level, entityContext.getEntity(), state, pos)) { - return Shapes.empty(); - } - } catch (InvalidContextParameterException e) { - Barricade.LOG.error("Failed to test shape", e); - } + if (!this.isShaped(state, blockGetter, pos, context)) { + return Shapes.block(); + } else { + return Shapes.empty(); } - return Shapes.block(); } @Override @@ -160,21 +61,12 @@ public static GameContext newContext( @NotNull BlockPos pos, @NotNull CollisionContext context ) { - if (context instanceof EntityCollisionContext entityContext && entityContext.getEntity() != null) { - Level level = null; - if (blockGetter instanceof Level) { - level = (Level) blockGetter; - } - - try { - boolean isOperator = entityContext.getEntity() instanceof Player player && player.getAbilities().instabuild; - if (!isOperator && test(level, entityContext.getEntity(), state, pos)) { - return Shapes.empty(); - } - } catch (InvalidContextParameterException e) { - Barricade.LOG.error("Failed to test shape", e); - } + if (context instanceof EntityCollisionContext entityContext && + entityContext.getEntity() instanceof Player player && + player.getAbilities().instabuild) { + return super.getShape(state, blockGetter, pos, context); + } else { + return Shapes.empty(); } - return super.getShape(state, blockGetter, pos, context); } } diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java index fb75dcc..c653c46 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateBlock.java @@ -116,6 +116,10 @@ static GameContext newContext( throw new IllegalStateException(MIXIN_NOT_APPLIED); } + /** + * Checks if the entity in the collision context passes the condition. + * @return If the entity in the context passes the condition. + */ default boolean isShaped( @NotNull BlockState state, @NotNull BlockGetter blockGetter, diff --git a/common/src/main/java/net/modgarden/barricade/data/AdvancedBarrier.java b/common/src/main/java/net/modgarden/barricade/data/AdvancedBarrier.java index f47e28a..717d4fb 100644 --- a/common/src/main/java/net/modgarden/barricade/data/AdvancedBarrier.java +++ b/common/src/main/java/net/modgarden/barricade/data/AdvancedBarrier.java @@ -16,7 +16,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.modgarden.barricade.Barricade; -import net.modgarden.barricade.block.PredicateBarrierBlock; +import net.modgarden.barricade.block.PredicateBlock; import net.modgarden.barricade.registry.BarricadeRegistries; import net.modgarden.silicate.api.condition.GameCondition; import net.modgarden.silicate.api.exception.InvalidContextParameterException; @@ -69,7 +69,7 @@ public boolean test( BlockPos pos ) throws InvalidContextParameterException { return condition.isPresent() && condition.get().value().test( - PredicateBarrierBlock.newContext(level, entity, state, pos) + PredicateBlock.newContext(level, entity, state, pos) ); } diff --git a/common/src/main/java/net/modgarden/barricade/mixin/client/ClientLevelMixin.java b/common/src/main/java/net/modgarden/barricade/mixin/client/ClientLevelMixin.java index 32fd8f7..2d54e2e 100644 --- a/common/src/main/java/net/modgarden/barricade/mixin/client/ClientLevelMixin.java +++ b/common/src/main/java/net/modgarden/barricade/mixin/client/ClientLevelMixin.java @@ -95,7 +95,7 @@ public class ClientLevelMixin { BarrierRenderUtils.createAdvancedParticle(blockEntity.getData().directions(), blockEntity.getData().icon().orElse(null), particleOptions -> original.call(instance, particleOptions, x, y, z, xSpeed, ySpeed, zSpeed), blockPos.immutable()); return; } else if (blockState.getBlock() instanceof PredicateBarrierBlock predicateBarrierBlock) { - BarrierRenderUtils.createAdvancedParticle(new BlockedDirections(EnumSet.allOf(Direction.class)), predicateBarrierBlock.icon(), particleOptions -> original.call(instance, particleOptions, x, y, z, xSpeed, ySpeed, zSpeed), blockPos.immutable()); + BarrierRenderUtils.createAdvancedParticle(new BlockedDirections(EnumSet.allOf(Direction.class)), predicateBarrierBlock.barricade$icon(), particleOptions -> original.call(instance, particleOptions, x, y, z, xSpeed, ySpeed, zSpeed), blockPos.immutable()); return; } original.call(instance, particleData, x, y, z, xSpeed, ySpeed, zSpeed); diff --git a/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java b/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java index c05f13e..c672216 100644 --- a/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java +++ b/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java @@ -9,6 +9,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; +import net.modgarden.barricade.block.PredicateBarrierBlock; import net.modgarden.barricade.block.PredicateBlock; import net.modgarden.barricade.block.PredicateLeverBlock; import net.modgarden.silicate.api.SilicateRegistries; @@ -25,7 +26,7 @@ import java.util.function.Function; -@Mixin({PredicateLeverBlock.class}) +@Mixin({PredicateBarrierBlock.class, PredicateLeverBlock.class}) public class PredicateBlocksMixin implements PredicateBlock { @Unique private ResourceLocation barricade$icon; From fda2b9f75d96753947f2e0964162d1d066c4190c Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 20:19:56 -0400 Subject: [PATCH 12/18] fix: Don't throw a RuntimeException when condition testing fails --- .../net/modgarden/barricade/block/PredicateLeverBlock.java | 5 ++++- .../net/modgarden/barricade/item/PredicateBlockItem.java | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java index 991e1df..4179227 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java @@ -19,6 +19,8 @@ import net.modgarden.silicate.api.exception.InvalidContextParameterException; import org.jetbrains.annotations.NotNull; +import static net.modgarden.barricade.Barricade.LOG; + public class PredicateLeverBlock extends LeverBlock implements PredicateBlock { @SuppressWarnings("unused") public PredicateLeverBlock(Properties properties, ResourceLocation icon, ResourceKey> conditionTemplate) { @@ -63,7 +65,8 @@ protected PredicateLeverBlock(Properties properties, ResourceLocation icon, Hold return InteractionResult.PASS; } } catch (InvalidContextParameterException e) { - throw new RuntimeException(e); + LOG.error("Failed to test condition", e); + return InteractionResult.FAIL; } } } diff --git a/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java b/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java index 96cb5c8..6ea5056 100644 --- a/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java +++ b/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java @@ -9,6 +9,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static net.modgarden.barricade.Barricade.LOG; + public class PredicateBlockItem extends BlockItem { public PredicateBlockItem(T block, Properties properties) { super(block, properties); @@ -20,7 +22,8 @@ protected boolean canPlace(@NotNull BlockPlaceContext context, @NotNull BlockSta try { return this.getBlock().barricade$test(context.getLevel(), context.getPlayer(), state, context.getClickedPos()); } catch (InvalidContextParameterException e) { - throw new RuntimeException(e); + LOG.error("Failed to test condition", e); + return false; } } else { return false; From 27a91cc292d1dff7c2e9f47a74ec473b3a1bb650 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 21:22:25 -0400 Subject: [PATCH 13/18] feat: `PredicateButtonBlock` --- .../blockstates/creative_only_button.json | 118 ++++++++++++++++++ .../models/block/creative_only_button.json | 6 + .../block/creative_only_button_inventory.json | 6 + .../block/creative_only_button_pressed.json | 6 + .../models/item/creative_only_button.json | 3 + .../barricade/block/PredicateButtonBlock.java | 72 +++++++++++ .../barricade/block/PredicateLeverBlock.java | 13 +- .../mixin/self/PredicateBlocksMixin.java | 3 +- .../barricade/registry/BarricadeBlocks.java | 13 ++ .../barricade/registry/BarricadeItems.java | 9 ++ .../assets/barricade/lang/en_us.json | 1 + .../barricade/datagen/BarricadeDataGen.java | 10 ++ .../mixin/BlockFamilyProviderAccessor.java | 16 +++ .../mixin/BlockModelGeneratorsAccessor.java | 15 +++ .../resources/barricade.datagen.mixins.json | 17 +++ fabric/src/datagen/resources/fabric.mod.json | 3 + .../barricade/fabric/BarricadeFabric.java | 3 +- .../barricade/neoforge/BarricadeNeoForge.java | 3 +- 18 files changed, 307 insertions(+), 10 deletions(-) create mode 100644 common/src/generated/resources/assets/barricade/blockstates/creative_only_button.json create mode 100644 common/src/generated/resources/assets/barricade/models/block/creative_only_button.json create mode 100644 common/src/generated/resources/assets/barricade/models/block/creative_only_button_inventory.json create mode 100644 common/src/generated/resources/assets/barricade/models/block/creative_only_button_pressed.json create mode 100644 common/src/generated/resources/assets/barricade/models/item/creative_only_button.json create mode 100644 common/src/main/java/net/modgarden/barricade/block/PredicateButtonBlock.java create mode 100644 fabric/src/datagen/java/net/modgarden/barricade/datagen/mixin/BlockFamilyProviderAccessor.java create mode 100644 fabric/src/datagen/java/net/modgarden/barricade/datagen/mixin/BlockModelGeneratorsAccessor.java create mode 100644 fabric/src/datagen/resources/barricade.datagen.mixins.json diff --git a/common/src/generated/resources/assets/barricade/blockstates/creative_only_button.json b/common/src/generated/resources/assets/barricade/blockstates/creative_only_button.json new file mode 100644 index 0000000..293b4ee --- /dev/null +++ b/common/src/generated/resources/assets/barricade/blockstates/creative_only_button.json @@ -0,0 +1,118 @@ +{ + "variants": { + "face=ceiling,facing=east,powered=false": { + "model": "barricade:block/creative_only_button", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=east,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=north,powered=false": { + "model": "barricade:block/creative_only_button", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=north,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=south,powered=false": { + "model": "barricade:block/creative_only_button", + "x": 180 + }, + "face=ceiling,facing=south,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "x": 180 + }, + "face=ceiling,facing=west,powered=false": { + "model": "barricade:block/creative_only_button", + "x": 180, + "y": 90 + }, + "face=ceiling,facing=west,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "x": 180, + "y": 90 + }, + "face=floor,facing=east,powered=false": { + "model": "barricade:block/creative_only_button", + "y": 90 + }, + "face=floor,facing=east,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "y": 90 + }, + "face=floor,facing=north,powered=false": { + "model": "barricade:block/creative_only_button" + }, + "face=floor,facing=north,powered=true": { + "model": "barricade:block/creative_only_button_pressed" + }, + "face=floor,facing=south,powered=false": { + "model": "barricade:block/creative_only_button", + "y": 180 + }, + "face=floor,facing=south,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "y": 180 + }, + "face=floor,facing=west,powered=false": { + "model": "barricade:block/creative_only_button", + "y": 270 + }, + "face=floor,facing=west,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "y": 270 + }, + "face=wall,facing=east,powered=false": { + "model": "barricade:block/creative_only_button", + "uvlock": true, + "x": 90, + "y": 90 + }, + "face=wall,facing=east,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "uvlock": true, + "x": 90, + "y": 90 + }, + "face=wall,facing=north,powered=false": { + "model": "barricade:block/creative_only_button", + "uvlock": true, + "x": 90 + }, + "face=wall,facing=north,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "uvlock": true, + "x": 90 + }, + "face=wall,facing=south,powered=false": { + "model": "barricade:block/creative_only_button", + "uvlock": true, + "x": 90, + "y": 180 + }, + "face=wall,facing=south,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "uvlock": true, + "x": 90, + "y": 180 + }, + "face=wall,facing=west,powered=false": { + "model": "barricade:block/creative_only_button", + "uvlock": true, + "x": 90, + "y": 270 + }, + "face=wall,facing=west,powered=true": { + "model": "barricade:block/creative_only_button_pressed", + "uvlock": true, + "x": 90, + "y": 270 + } + } +} \ No newline at end of file diff --git a/common/src/generated/resources/assets/barricade/models/block/creative_only_button.json b/common/src/generated/resources/assets/barricade/models/block/creative_only_button.json new file mode 100644 index 0000000..42d1cc4 --- /dev/null +++ b/common/src/generated/resources/assets/barricade/models/block/creative_only_button.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button", + "textures": { + "texture": "minecraft:block/stone" + } +} \ No newline at end of file diff --git a/common/src/generated/resources/assets/barricade/models/block/creative_only_button_inventory.json b/common/src/generated/resources/assets/barricade/models/block/creative_only_button_inventory.json new file mode 100644 index 0000000..ffee63f --- /dev/null +++ b/common/src/generated/resources/assets/barricade/models/block/creative_only_button_inventory.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button_inventory", + "textures": { + "texture": "minecraft:block/stone" + } +} \ No newline at end of file diff --git a/common/src/generated/resources/assets/barricade/models/block/creative_only_button_pressed.json b/common/src/generated/resources/assets/barricade/models/block/creative_only_button_pressed.json new file mode 100644 index 0000000..4606dfa --- /dev/null +++ b/common/src/generated/resources/assets/barricade/models/block/creative_only_button_pressed.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button_pressed", + "textures": { + "texture": "minecraft:block/stone" + } +} \ No newline at end of file diff --git a/common/src/generated/resources/assets/barricade/models/item/creative_only_button.json b/common/src/generated/resources/assets/barricade/models/item/creative_only_button.json new file mode 100644 index 0000000..fb2ea8d --- /dev/null +++ b/common/src/generated/resources/assets/barricade/models/item/creative_only_button.json @@ -0,0 +1,3 @@ +{ + "parent": "barricade:block/creative_only_button_inventory" +} \ No newline at end of file diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateButtonBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateButtonBlock.java new file mode 100644 index 0000000..7bbb3ce --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateButtonBlock.java @@ -0,0 +1,72 @@ +package net.modgarden.barricade.block; + +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.ButtonBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockSetType; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import net.modgarden.silicate.api.condition.GameCondition; +import net.modgarden.silicate.api.exception.InvalidContextParameterException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import static net.modgarden.barricade.Barricade.LOG; + +public class PredicateButtonBlock extends ButtonBlock implements PredicateBlock { + @SuppressWarnings("unused") + public PredicateButtonBlock(Properties properties, ResourceLocation icon, ResourceKey> conditionTemplate) { + super(BlockSetType.STONE, 20, properties); + } + + protected PredicateButtonBlock(Properties properties, ResourceLocation icon, Holder> condition) { + super(BlockSetType.STONE, 20, properties); + } + + @Override + public @NotNull MapCodec codec() { + return PredicateBlock.mapCodec(PredicateButtonBlock::new); + } + + @Override + protected @NotNull VoxelShape getShape( + @NotNull BlockState state, + @NotNull BlockGetter level, + @NotNull BlockPos pos, + @NotNull CollisionContext context + ) { + if (this.isShaped(state, level, pos, context)) { + return super.getShape(state, level, pos, context); + } else { + return Shapes.empty(); + } + } + + @Override + public void press( + @NotNull BlockState state, + @NotNull Level level, + @NotNull BlockPos pos, + @Nullable Player player + ) { + if (player == null) return; + + try { + if (this.barricade$test(level, player, state, pos)) { + super.press(state, level, pos, player); + } + } catch (InvalidContextParameterException e) { + LOG.error("Failed to test condition", e); + } + } +} diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java index 4179227..ac6851a 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java @@ -18,6 +18,7 @@ import net.modgarden.silicate.api.condition.GameCondition; import net.modgarden.silicate.api.exception.InvalidContextParameterException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import static net.modgarden.barricade.Barricade.LOG; @@ -51,22 +52,20 @@ protected PredicateLeverBlock(Properties properties, ResourceLocation icon, Hold } @Override - protected @NotNull InteractionResult useWithoutItem( + public void pull( @NotNull BlockState state, @NotNull Level level, @NotNull BlockPos pos, - @NotNull Player player, - @NotNull BlockHitResult hitResult + @Nullable Player player ) { + if (player == null) return; + try { if (level.isClientSide() || this.barricade$test(level, player, state, pos)) { - return super.useWithoutItem(state, level, pos, player, hitResult); - } else { - return InteractionResult.PASS; + super.pull(state, level, pos, player); } } catch (InvalidContextParameterException e) { LOG.error("Failed to test condition", e); - return InteractionResult.FAIL; } } } diff --git a/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java b/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java index c672216..1257a06 100644 --- a/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java +++ b/common/src/main/java/net/modgarden/barricade/mixin/self/PredicateBlocksMixin.java @@ -11,6 +11,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.modgarden.barricade.block.PredicateBarrierBlock; import net.modgarden.barricade.block.PredicateBlock; +import net.modgarden.barricade.block.PredicateButtonBlock; import net.modgarden.barricade.block.PredicateLeverBlock; import net.modgarden.silicate.api.SilicateRegistries; import net.modgarden.silicate.api.condition.GameCondition; @@ -26,7 +27,7 @@ import java.util.function.Function; -@Mixin({PredicateBarrierBlock.class, PredicateLeverBlock.class}) +@Mixin({PredicateBarrierBlock.class, PredicateLeverBlock.class, PredicateButtonBlock.class}) public class PredicateBlocksMixin implements PredicateBlock { @Unique private ResourceLocation barricade$icon; diff --git a/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java b/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java index 6826c4f..9d6eea3 100644 --- a/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java +++ b/common/src/main/java/net/modgarden/barricade/registry/BarricadeBlocks.java @@ -61,6 +61,13 @@ public class BarricadeBlocks { conditionTemplate("creative_only") ); + // Predicate Buttons + public static final PredicateButtonBlock CREATIVE_ONLY_BUTTON = new PredicateButtonBlock( + buttonProps(), + Barricade.asResource("barricade/icon/iron_sword"), + conditionTemplate("creative_only") + ); + public static void registerAll() { register("advanced_barrier", ADVANCED_BARRIER); @@ -81,6 +88,8 @@ public static void registerAll() { register("creative_only_barrier", CREATIVE_ONLY_BARRIER); register("creative_only_lever", CREATIVE_ONLY_LEVER); + + register("creative_only_button", CREATIVE_ONLY_BUTTON); } private static void register(String name, Block block) { @@ -102,4 +111,8 @@ private static ResourceKey> conditionTemplate(String name) { private static BlockBehaviour.@NotNull Properties leverProps() { return BlockBehaviour.Properties.ofFullCopy(Blocks.LEVER); } + + private static BlockBehaviour.@NotNull Properties buttonProps() { + return BlockBehaviour.Properties.ofFullCopy(Blocks.STONE_BUTTON); + } } diff --git a/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java b/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java index 7527dfb..6820128 100644 --- a/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java +++ b/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java @@ -6,6 +6,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.Rarity; import net.modgarden.barricade.Barricade; +import net.modgarden.barricade.block.PredicateButtonBlock; import net.modgarden.barricade.block.PredicateLeverBlock; import net.modgarden.barricade.item.AdvancedBarrierBlockItem; import net.modgarden.barricade.item.DirectionalBarrierBlockItem; @@ -42,6 +43,12 @@ public class BarricadeItems { barrierProps() ); + // Predicate Buttons + public static final PredicateBlockItem CREATIVE_ONLY_BUTTON = new PredicateBlockItem<>( + BarricadeBlocks.CREATIVE_ONLY_BUTTON, + barrierProps() + ); + public static void registerAll() { register("advanced_barrier", ADVANCED_BARRIER); @@ -62,6 +69,8 @@ public static void registerAll() { register("creative_only_barrier", CREATIVE_ONLY_BARRIER); register("creative_only_lever", CREATIVE_ONLY_LEVER); + + register("creative_only_button", CREATIVE_ONLY_BUTTON); } private static void register(String name, BlockItem blockItem) { diff --git a/common/src/main/resources/assets/barricade/lang/en_us.json b/common/src/main/resources/assets/barricade/lang/en_us.json index 4f35f95..2ef1649 100644 --- a/common/src/main/resources/assets/barricade/lang/en_us.json +++ b/common/src/main/resources/assets/barricade/lang/en_us.json @@ -14,6 +14,7 @@ "block.barricade.hostile_barrier": "Hostile Barrier", "block.barricade.creative_only_barrier": "Creative-Only Barrier", "block.barricade.creative_only_lever": "Creative-Only Lever", + "block.barricade.creative_only_button": "Creative-Only Button", "tag.item.barricade.barriers": "Barriers", "resourcePack.barricade.modded_rendering.name": "Barricade Rendering", "resourcePack.barricade.modded_rendering.description": "Enables Barricade's alternative block rendering.", diff --git a/fabric/src/datagen/java/net/modgarden/barricade/datagen/BarricadeDataGen.java b/fabric/src/datagen/java/net/modgarden/barricade/datagen/BarricadeDataGen.java index dec636d..92c77c2 100644 --- a/fabric/src/datagen/java/net/modgarden/barricade/datagen/BarricadeDataGen.java +++ b/fabric/src/datagen/java/net/modgarden/barricade/datagen/BarricadeDataGen.java @@ -16,6 +16,7 @@ import net.minecraft.data.models.model.ModelLocationUtils; import net.minecraft.data.models.model.ModelTemplates; import net.minecraft.data.models.model.TextureMapping; +import net.minecraft.data.models.model.TexturedModel; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.BlockTags; import net.minecraft.tags.EntityTypeTags; @@ -26,6 +27,8 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.properties.AttachFace; import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.modgarden.barricade.datagen.mixin.BlockFamilyProviderAccessor; +import net.modgarden.barricade.datagen.mixin.BlockModelGeneratorsAccessor; import net.modgarden.barricade.registry.BarricadeBlocks; import net.modgarden.barricade.registry.BarricadeTags; import org.jetbrains.annotations.Nullable; @@ -50,6 +53,8 @@ public ModelProvider(FabricDataOutput output) { @Override public void generateBlockStateModels(BlockModelGenerators generators) { createLever(generators, BarricadeBlocks.CREATIVE_ONLY_LEVER); + family(generators, Blocks.STONE) + .button(BarricadeBlocks.CREATIVE_ONLY_BUTTON); } @Override @@ -106,6 +111,11 @@ private static void createLever(BlockModelGenerators generators, Block block) { ); } + private static BlockModelGenerators.BlockFamilyProvider family(BlockModelGenerators generators, Block block) { + TexturedModel texturedModel = ((BlockModelGeneratorsAccessor) generators).getTexturedModels().getOrDefault(block, TexturedModel.CUBE.get(block)); + return BlockFamilyProviderAccessor.init(generators, texturedModel.getMapping()); + } + private static void createSimpleFlatItemModel(BlockModelGenerators generators, Block flatBlock, Block textureBlock) { Item item = flatBlock.asItem(); if (item != Items.AIR) { diff --git a/fabric/src/datagen/java/net/modgarden/barricade/datagen/mixin/BlockFamilyProviderAccessor.java b/fabric/src/datagen/java/net/modgarden/barricade/datagen/mixin/BlockFamilyProviderAccessor.java new file mode 100644 index 0000000..0d73487 --- /dev/null +++ b/fabric/src/datagen/java/net/modgarden/barricade/datagen/mixin/BlockFamilyProviderAccessor.java @@ -0,0 +1,16 @@ +package net.modgarden.barricade.datagen.mixin; + +import net.minecraft.data.models.BlockModelGenerators; +import net.minecraft.data.models.model.TextureMapping; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import static net.modgarden.barricade.Barricade.MIXIN_NOT_APPLIED; + +@Mixin(BlockModelGenerators.BlockFamilyProvider.class) +public interface BlockFamilyProviderAccessor { + @Invoker("") + static BlockModelGenerators.BlockFamilyProvider init(final BlockModelGenerators this$0, final TextureMapping mapping) { + throw new IllegalStateException(MIXIN_NOT_APPLIED); + } +} diff --git a/fabric/src/datagen/java/net/modgarden/barricade/datagen/mixin/BlockModelGeneratorsAccessor.java b/fabric/src/datagen/java/net/modgarden/barricade/datagen/mixin/BlockModelGeneratorsAccessor.java new file mode 100644 index 0000000..7d031ba --- /dev/null +++ b/fabric/src/datagen/java/net/modgarden/barricade/datagen/mixin/BlockModelGeneratorsAccessor.java @@ -0,0 +1,15 @@ +package net.modgarden.barricade.datagen.mixin; + +import net.minecraft.data.models.BlockModelGenerators; +import net.minecraft.data.models.model.TexturedModel; +import net.minecraft.world.level.block.Block; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Map; + +@Mixin(BlockModelGenerators.class) +public interface BlockModelGeneratorsAccessor { + @Accessor + Map getTexturedModels(); +} diff --git a/fabric/src/datagen/resources/barricade.datagen.mixins.json b/fabric/src/datagen/resources/barricade.datagen.mixins.json new file mode 100644 index 0000000..cd503d4 --- /dev/null +++ b/fabric/src/datagen/resources/barricade.datagen.mixins.json @@ -0,0 +1,17 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.modgarden.barricade.datagen.mixin", + "refmap": "${mod_id}.refmap.json", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "BlockFamilyProviderAccessor", + "BlockModelGeneratorsAccessor" + ], + "client": [ + ], + "injectors": { + "defaultRequire": 1 + } +} + diff --git a/fabric/src/datagen/resources/fabric.mod.json b/fabric/src/datagen/resources/fabric.mod.json index 2bdf5d6..d6641a9 100644 --- a/fabric/src/datagen/resources/fabric.mod.json +++ b/fabric/src/datagen/resources/fabric.mod.json @@ -23,6 +23,9 @@ "net.modgarden.barricade.datagen.BarricadeDataGen" ] }, + "mixins": [ + "${mod_id}.datagen.mixins.json" + ], "depends": { "fabricloader": "${fabric_loader_range}", "fabric-api": "*", diff --git a/fabric/src/main/java/net/modgarden/barricade/fabric/BarricadeFabric.java b/fabric/src/main/java/net/modgarden/barricade/fabric/BarricadeFabric.java index 69ae150..a7499c1 100644 --- a/fabric/src/main/java/net/modgarden/barricade/fabric/BarricadeFabric.java +++ b/fabric/src/main/java/net/modgarden/barricade/fabric/BarricadeFabric.java @@ -60,7 +60,8 @@ public void onInitialize() { BarricadeItems.PASSIVE_BARRIER, BarricadeItems.HOSTILE_BARRIER, BarricadeItems.CREATIVE_ONLY_BARRIER, - BarricadeItems.CREATIVE_ONLY_LEVER); + BarricadeItems.CREATIVE_ONLY_LEVER, + BarricadeItems.CREATIVE_ONLY_BUTTON); }); } } diff --git a/neoforge/src/main/java/net/modgarden/barricade/neoforge/BarricadeNeoForge.java b/neoforge/src/main/java/net/modgarden/barricade/neoforge/BarricadeNeoForge.java index 06f09d3..a024df6 100644 --- a/neoforge/src/main/java/net/modgarden/barricade/neoforge/BarricadeNeoForge.java +++ b/neoforge/src/main/java/net/modgarden/barricade/neoforge/BarricadeNeoForge.java @@ -92,7 +92,8 @@ public static void buildCreativeModeTabs(BuildCreativeModeTabContentsEvent event BarricadeItems.PASSIVE_BARRIER, BarricadeItems.HOSTILE_BARRIER, BarricadeItems.CREATIVE_ONLY_BARRIER, - BarricadeItems.CREATIVE_ONLY_LEVER + BarricadeItems.CREATIVE_ONLY_LEVER, + BarricadeItems.CREATIVE_ONLY_BUTTON ); for (Item item : items) { From 132c3bc29855c409ccf43775cf9ffff245e91aa8 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 21:27:51 -0400 Subject: [PATCH 14/18] fix: Don't let non-op players place `PredicateBlock` --- .../barricade/block/PredicateButtonBlock.java | 2 -- .../barricade/block/PredicateLeverBlock.java | 2 -- .../barricade/item/PredicateBlockItem.java | 18 ++---------------- 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateButtonBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateButtonBlock.java index 7bbb3ce..c89469c 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateButtonBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateButtonBlock.java @@ -5,14 +5,12 @@ import net.minecraft.core.Holder; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.ButtonBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockSetType; -import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java index ac6851a..fa20772 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java @@ -5,13 +5,11 @@ import net.minecraft.core.Holder; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; diff --git a/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java b/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java index 6ea5056..f3e70e2 100644 --- a/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java +++ b/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java @@ -5,11 +5,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.modgarden.barricade.block.PredicateBlock; -import net.modgarden.silicate.api.exception.InvalidContextParameterException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import static net.modgarden.barricade.Barricade.LOG; public class PredicateBlockItem extends BlockItem { public PredicateBlockItem(T block, Properties properties) { @@ -19,23 +15,13 @@ public PredicateBlockItem(T block, Properties properties) { @Override protected boolean canPlace(@NotNull BlockPlaceContext context, @NotNull BlockState state) { if (super.canPlace(context, state) && context.getPlayer() != null) { - try { - return this.getBlock().barricade$test(context.getLevel(), context.getPlayer(), state, context.getClickedPos()); - } catch (InvalidContextParameterException e) { - LOG.error("Failed to test condition", e); - return false; - } + return context.getPlayer().getAbilities().instabuild; } else { return false; } } - @Override - protected @Nullable BlockState getPlacementState(@NotNull BlockPlaceContext context) { - return super.getPlacementState(context); - } - - @SuppressWarnings("unchecked") // It is illegal to have a this.block field not of type S + @SuppressWarnings("unchecked") // It is illegal to have a this.block field not of type T @Override public @NotNull T getBlock() { return (T) super.getBlock(); From 2365b56bbd7968c40e1bd1b1527a0b185164a34e Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 21:42:33 -0400 Subject: [PATCH 15/18] refactor: `OperatorBlockItem` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `PredicateBlockItem` → `OperatorBlockItem` - All `PredicateBarrierBlock` use `OperatorBlockItem` --- .../item/AdvancedBarrierBlockItem.java | 4 +- .../item/DirectionalBarrierBlockItem.java | 9 ++--- .../item/EntityCheckBarrierBlockItem.java | 7 ++-- ...eBlockItem.java => OperatorBlockItem.java} | 5 +-- .../barricade/registry/BarricadeItems.java | 39 ++++++++++--------- 5 files changed, 33 insertions(+), 31 deletions(-) rename common/src/main/java/net/modgarden/barricade/item/{PredicateBlockItem.java => OperatorBlockItem.java} (79%) diff --git a/common/src/main/java/net/modgarden/barricade/item/AdvancedBarrierBlockItem.java b/common/src/main/java/net/modgarden/barricade/item/AdvancedBarrierBlockItem.java index e657da1..31cb039 100644 --- a/common/src/main/java/net/modgarden/barricade/item/AdvancedBarrierBlockItem.java +++ b/common/src/main/java/net/modgarden/barricade/item/AdvancedBarrierBlockItem.java @@ -20,13 +20,15 @@ import java.util.HashSet; import java.util.Set; -public class AdvancedBarrierBlockItem extends EntityCheckBarrierBlockItem { +public class AdvancedBarrierBlockItem extends OperatorBlockItem { public AdvancedBarrierBlockItem(Block block, Properties properties) { super(block, properties); } @Override protected boolean canPlace(@NotNull BlockPlaceContext context, @NotNull BlockState state) { + if (!super.canPlace(context, state)) return false; + ItemStack stack = context.getItemInHand(); boolean collision; if (!stack.has(BarricadeComponents.ADVANCED_BARRIER)) { diff --git a/common/src/main/java/net/modgarden/barricade/item/DirectionalBarrierBlockItem.java b/common/src/main/java/net/modgarden/barricade/item/DirectionalBarrierBlockItem.java index 9a24cef..4400645 100644 --- a/common/src/main/java/net/modgarden/barricade/item/DirectionalBarrierBlockItem.java +++ b/common/src/main/java/net/modgarden/barricade/item/DirectionalBarrierBlockItem.java @@ -1,19 +1,18 @@ package net.modgarden.barricade.item; -import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import net.modgarden.barricade.block.DirectionalBarrierBlock; import org.jetbrains.annotations.NotNull; -public class DirectionalBarrierBlockItem extends BlockItem { - public DirectionalBarrierBlockItem(Block block, Properties properties) { +public class DirectionalBarrierBlockItem extends OperatorBlockItem { + public DirectionalBarrierBlockItem(DirectionalBarrierBlock block, Properties properties) { super(block, properties); } // Make sure that no matter the directional context, block placements are consistently declined if an entity is in the block. @Override protected boolean canPlace(@NotNull BlockPlaceContext context, @NotNull BlockState state) { - return (!mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())); + return super.canPlace(context, state) && (!mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())); } } diff --git a/common/src/main/java/net/modgarden/barricade/item/EntityCheckBarrierBlockItem.java b/common/src/main/java/net/modgarden/barricade/item/EntityCheckBarrierBlockItem.java index 7f1a1a2..ffd1908 100644 --- a/common/src/main/java/net/modgarden/barricade/item/EntityCheckBarrierBlockItem.java +++ b/common/src/main/java/net/modgarden/barricade/item/EntityCheckBarrierBlockItem.java @@ -1,6 +1,5 @@ package net.modgarden.barricade.item; -import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; @@ -8,14 +7,14 @@ import net.minecraft.world.phys.shapes.Shapes; import org.jetbrains.annotations.NotNull; -public class EntityCheckBarrierBlockItem extends BlockItem { - public EntityCheckBarrierBlockItem(Block block, Properties properties) { +public class EntityCheckBarrierBlockItem extends OperatorBlockItem { + public EntityCheckBarrierBlockItem(T block, Properties properties) { super(block, properties); } @Override protected boolean canPlace(@NotNull BlockPlaceContext context, @NotNull BlockState state) { - return (!mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && context.getLevel().getEntities(null, Shapes.block().move(context.getClickedPos().getX(), context.getClickedPos().getY(), context.getClickedPos().getZ()).bounds()).stream().allMatch(entity -> + return super.canPlace(context, state) && (!mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && context.getLevel().getEntities(null, Shapes.block().move(context.getClickedPos().getX(), context.getClickedPos().getY(), context.getClickedPos().getZ()).bounds()).stream().allMatch(entity -> state.getCollisionShape(context.getLevel(), context.getClickedPos(), CollisionContext.of(entity)).isEmpty()); } } diff --git a/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java b/common/src/main/java/net/modgarden/barricade/item/OperatorBlockItem.java similarity index 79% rename from common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java rename to common/src/main/java/net/modgarden/barricade/item/OperatorBlockItem.java index f3e70e2..4134913 100644 --- a/common/src/main/java/net/modgarden/barricade/item/PredicateBlockItem.java +++ b/common/src/main/java/net/modgarden/barricade/item/OperatorBlockItem.java @@ -4,11 +4,10 @@ import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -import net.modgarden.barricade.block.PredicateBlock; import org.jetbrains.annotations.NotNull; -public class PredicateBlockItem extends BlockItem { - public PredicateBlockItem(T block, Properties properties) { +public class OperatorBlockItem extends BlockItem { + public OperatorBlockItem(T block, Properties properties) { super(block, properties); } diff --git a/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java b/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java index 6820128..1bf9f73 100644 --- a/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java +++ b/common/src/main/java/net/modgarden/barricade/registry/BarricadeItems.java @@ -5,46 +5,49 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.Rarity; +import net.minecraft.world.level.block.Block; import net.modgarden.barricade.Barricade; +import net.modgarden.barricade.block.DirectionalBarrierBlock; +import net.modgarden.barricade.block.PredicateBarrierBlock; import net.modgarden.barricade.block.PredicateButtonBlock; import net.modgarden.barricade.block.PredicateLeverBlock; import net.modgarden.barricade.item.AdvancedBarrierBlockItem; import net.modgarden.barricade.item.DirectionalBarrierBlockItem; import net.modgarden.barricade.item.EntityCheckBarrierBlockItem; -import net.modgarden.barricade.item.PredicateBlockItem; +import net.modgarden.barricade.item.OperatorBlockItem; import org.jetbrains.annotations.NotNull; public class BarricadeItems { - public static final BlockItem ADVANCED_BARRIER = new AdvancedBarrierBlockItem(BarricadeBlocks.ADVANCED_BARRIER, barrierProps()); + public static final OperatorBlockItem ADVANCED_BARRIER = new AdvancedBarrierBlockItem(BarricadeBlocks.ADVANCED_BARRIER, barrierProps()); - public static final BlockItem HORIZONTAL_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.HORIZONTAL_BARRIER, barrierProps()); - public static final BlockItem VERTICAL_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.VERTICAL_BARRIER, barrierProps()); - public static final BlockItem DOWN_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.DOWN_BARRIER, barrierProps()); - public static final BlockItem UP_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.UP_BARRIER, barrierProps()); - public static final BlockItem SOUTH_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.SOUTH_BARRIER, barrierProps()); - public static final BlockItem NORTH_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.NORTH_BARRIER, barrierProps()); - public static final BlockItem EAST_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.EAST_BARRIER, barrierProps()); - public static final BlockItem WEST_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.WEST_BARRIER, barrierProps()); - - public static final BlockItem PLAYER_BARRIER = new EntityCheckBarrierBlockItem(BarricadeBlocks.PLAYER_BARRIER, barrierProps()); - public static final BlockItem MOB_BARRIER = new EntityCheckBarrierBlockItem(BarricadeBlocks.MOB_BARRIER, barrierProps()); - public static final BlockItem PASSIVE_BARRIER = new EntityCheckBarrierBlockItem(BarricadeBlocks.PASSIVE_BARRIER, barrierProps()); - public static final BlockItem HOSTILE_BARRIER = new EntityCheckBarrierBlockItem(BarricadeBlocks.HOSTILE_BARRIER, barrierProps()); + public static final OperatorBlockItem HORIZONTAL_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.HORIZONTAL_BARRIER, barrierProps()); + public static final OperatorBlockItem VERTICAL_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.VERTICAL_BARRIER, barrierProps()); + public static final OperatorBlockItem DOWN_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.DOWN_BARRIER, barrierProps()); + public static final OperatorBlockItem UP_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.UP_BARRIER, barrierProps()); + public static final OperatorBlockItem SOUTH_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.SOUTH_BARRIER, barrierProps()); + public static final OperatorBlockItem NORTH_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.NORTH_BARRIER, barrierProps()); + public static final OperatorBlockItem EAST_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.EAST_BARRIER, barrierProps()); + public static final OperatorBlockItem WEST_BARRIER = new DirectionalBarrierBlockItem(BarricadeBlocks.WEST_BARRIER, barrierProps()); // Predicate Barriers - public static final BlockItem CREATIVE_ONLY_BARRIER = new BlockItem( + public static final OperatorBlockItem PLAYER_BARRIER = new EntityCheckBarrierBlockItem<>(BarricadeBlocks.PLAYER_BARRIER, barrierProps()); + public static final OperatorBlockItem MOB_BARRIER = new EntityCheckBarrierBlockItem<>(BarricadeBlocks.MOB_BARRIER, barrierProps()); + public static final OperatorBlockItem PASSIVE_BARRIER = new EntityCheckBarrierBlockItem<>(BarricadeBlocks.PASSIVE_BARRIER, barrierProps()); + public static final OperatorBlockItem HOSTILE_BARRIER = new EntityCheckBarrierBlockItem<>(BarricadeBlocks.HOSTILE_BARRIER, barrierProps()); + + public static final OperatorBlockItem CREATIVE_ONLY_BARRIER = new OperatorBlockItem<>( BarricadeBlocks.CREATIVE_ONLY_BARRIER, barrierProps() ); // Predicate Levers - public static final PredicateBlockItem CREATIVE_ONLY_LEVER = new PredicateBlockItem<>( + public static final OperatorBlockItem CREATIVE_ONLY_LEVER = new OperatorBlockItem<>( BarricadeBlocks.CREATIVE_ONLY_LEVER, barrierProps() ); // Predicate Buttons - public static final PredicateBlockItem CREATIVE_ONLY_BUTTON = new PredicateBlockItem<>( + public static final OperatorBlockItem CREATIVE_ONLY_BUTTON = new OperatorBlockItem<>( BarricadeBlocks.CREATIVE_ONLY_BUTTON, barrierProps() ); From bfc9224e7443ef8621602981db384f21c6d28d87 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 21:43:22 -0400 Subject: [PATCH 16/18] chore: update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2684ec6..9b30ddc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ ## Bugfixes - typo: `condition` field (previously `conditions`) in `PredicateBarrierBlock` - fix: Don't cache registry accesses + +## Changes +- Operator items can now only be placed in creative mode From 7db66a48e2bf8e61c46b478169d8c1e8967a7f16 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 7 May 2025 22:22:23 -0400 Subject: [PATCH 17/18] fix: fix crashes when hotswapping + disable Mixin hotswapping --- .../barricade/mixin/self/BarricadeMixin.java | 22 +++++++++++++++++++ .../src/main/resources/barricade.mixins.json | 1 + fabric/build.gradle.kts | 11 ---------- 3 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 common/src/main/java/net/modgarden/barricade/mixin/self/BarricadeMixin.java diff --git a/common/src/main/java/net/modgarden/barricade/mixin/self/BarricadeMixin.java b/common/src/main/java/net/modgarden/barricade/mixin/self/BarricadeMixin.java new file mode 100644 index 0000000..1905205 --- /dev/null +++ b/common/src/main/java/net/modgarden/barricade/mixin/self/BarricadeMixin.java @@ -0,0 +1,22 @@ +package net.modgarden.barricade.mixin.self; + +import net.modgarden.barricade.Barricade; +import org.slf4j.Logger; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; + +/** + * Hacks for hotswapping. + */ +@Mixin(Barricade.class) +public class BarricadeMixin { + /** + * Fixes an {@link IllegalAccessError} when hotswapping. + */ + @Mutable + @Final + @Shadow + public static Logger LOG; +} diff --git a/common/src/main/resources/barricade.mixins.json b/common/src/main/resources/barricade.mixins.json index 67ebbc5..0e0b07f 100644 --- a/common/src/main/resources/barricade.mixins.json +++ b/common/src/main/resources/barricade.mixins.json @@ -10,6 +10,7 @@ "BlockBehaviourBlockStateBaseMixin", "BlockBehaviourMixin", "BlockMixin", + "self.BarricadeMixin", "self.PredicateBlocksMixin" ], "client": [ diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index ced274a..69ad3d9 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -60,18 +60,7 @@ loom { } runs { afterEvaluate { - val mixinJarFile = configurations.runtimeClasspath.get().incoming.artifactView { - componentFilter { - it is ModuleComponentIdentifier && it.group == "net.fabricmc" && it.module == "sponge-mixin" - } - }.files.first() - configureEach { - // Mixin hotswapping - vmArg("-javaagent:$mixinJarFile") - - property("mixin.hotSwap", "true") - // Class redefinition (for JBR/DCEVM) vmArg("-XX:+AllowEnhancedClassRedefinition") } From 8b08b95ef263696cf46211d8341f144789b312a0 Mon Sep 17 00:00:00 2001 From: Anastasia Calico Date: Thu, 15 May 2025 07:57:44 +1000 Subject: [PATCH 18/18] fix: Fix creative players not being able to pull levers. --- .../barricade/block/PredicateLeverBlock.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java index fa20772..fbf63b0 100644 --- a/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java +++ b/common/src/main/java/net/modgarden/barricade/block/PredicateLeverBlock.java @@ -5,11 +5,13 @@ import net.minecraft.core.Holder; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; @@ -49,6 +51,21 @@ protected PredicateLeverBlock(Properties properties, ResourceLocation icon, Hold } } + @Override + protected @NotNull InteractionResult useWithoutItem( + @NotNull BlockState state, + @NotNull Level level, + @NotNull BlockPos pos, + @NotNull Player player, + @NotNull BlockHitResult hitResult) { + if (level.isClientSide()) { + return super.useWithoutItem(state, level, pos, player, hitResult); + } else { + this.pull(state, level, pos, player); + return InteractionResult.CONSUME; + } + } + @Override public void pull( @NotNull BlockState state, @@ -60,7 +77,8 @@ public void pull( try { if (level.isClientSide() || this.barricade$test(level, player, state, pos)) { - super.pull(state, level, pos, player); + // Passing the player into pull will prevent them from hearing the sound event. + super.pull(state, level, pos, null); } } catch (InvalidContextParameterException e) { LOG.error("Failed to test condition", e);