diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7f4b154..7bf9c2a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,12 +2,6 @@ name: Publish mod on Modrinth on: [ push, workflow_dispatch ] -env: - MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} - -permissions: - contents: write - jobs: build: runs-on: ubuntu-latest @@ -15,7 +9,7 @@ jobs: - name: checkout repository uses: actions/checkout@v3 - name: validate gradle wrapper - uses: https://github.com/gradle/wrapper-validation-action@v1 + uses: gradle/wrapper-validation-action@v2 - name: setup jdk uses: actions/setup-java@v3 with: @@ -31,4 +25,4 @@ jobs: - name: Publish Modrinth run: ./gradlew modrinth env: - MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} \ No newline at end of file + MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} diff --git a/gradle.properties b/gradle.properties index 23f23bf..6661c01 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ loader_version=0.15.6 # Mod Properties modrinth_id = jCpoCBpn -mod_version = 1.3.1 +mod_version = 1.3.5 maven_group = fr.adrien1106 archives_base_name = ReFramed mod_id = reframed diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index 87c90c5..e80034a 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -25,7 +25,7 @@ import java.util.function.BiConsumer; import java.util.stream.Collectors; /** - * TODO self culling, fix other models, better connected textures, preload items, walking sound, state replacement + * TODO self culling, fix other models, better connected textures, preload items */ public class ReFramed implements ModInitializer { public static final String MODID = "reframed"; diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java index 5d537db..f8b3809 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java @@ -35,7 +35,7 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity protected static final byte REDSTONE_MASK = 0b010; protected static final byte SOLIDITY_MASK = 0b100; - protected static final String BLOCKSTATE_KEY = "s"; + public static final String BLOCKSTATE_KEY = "s"; protected static final String BITFIELD_KEY = "b"; public ReFramedEntity(BlockEntityType type, BlockPos pos, BlockState state) { diff --git a/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java new file mode 100644 index 0000000..6db8bd1 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java @@ -0,0 +1,48 @@ +package fr.adrien1106.reframed.mixin; + +import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; +import net.minecraft.block.Block; +import net.minecraft.block.BlockEntityProvider; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtHelper; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import static fr.adrien1106.reframed.block.ReFramedEntity.BLOCKSTATE_KEY; + +@Mixin(BlockItem.class) +public class BlockItemMixin { + + @Shadow @Final @Deprecated private Block block; + + @Inject( + method = "writeNbtToBlockEntity", + at = @At( + value = "INVOKE_ASSIGN", + target = "Lnet/minecraft/item/BlockItem;getBlockEntityNbt(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/nbt/NbtCompound;", + shift = At.Shift.AFTER + ) + ) + private static void placeBlockWithOffHandCamo(World world, PlayerEntity player, BlockPos pos, ItemStack stack, CallbackInfoReturnable cir, @Local LocalRef compound) { + if (compound.get() != null + || player.getOffHandStack().isEmpty() + || !(player.getOffHandStack().getItem() instanceof BlockItem block) + || block.getBlock() instanceof BlockEntityProvider + || !Block.isShapeFullCube(block.getBlock().getDefaultState().getCollisionShape(world, pos)) + ) return; + NbtCompound new_comp = new NbtCompound(); + new_comp.put(BLOCKSTATE_KEY + 1, NbtHelper.fromBlockState(block.getBlock().getDefaultState())); + compound.set(new_comp); + } + +} diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java new file mode 100644 index 0000000..2ee7502 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java @@ -0,0 +1,48 @@ +package fr.adrien1106.reframed.mixin.sound; + +import com.llamalad7.mixinextras.sugar.Local; +import fr.adrien1106.reframed.block.ReFramedBlock; +import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.item.BlockItem; +import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(BlockItem.class) +public class BlockItemMixin { + + @Redirect( + method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/BlockState;getSoundGroup()Lnet/minecraft/sound/BlockSoundGroup;" + ) + ) + public BlockSoundGroup getCamoPlaceSound(BlockState state, @Local World world, @Local BlockPos pos) { + if (state.getBlock() instanceof ReFramedBlock frame_block + && world.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity + ) { + BlockState camo_state = frame_entity.getTheme(frame_block.getTopThemeIndex(state)); + state = camo_state.getBlock() != Blocks.AIR ? camo_state : state; + } + return state.getSoundGroup(); + } + + @Redirect( + method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/BlockItem;getPlaceSound(Lnet/minecraft/block/BlockState;)Lnet/minecraft/sound/SoundEvent;" + ) + ) + private SoundEvent getCamoSoundEvent(BlockItem item, BlockState state, @Local BlockSoundGroup group) { + // I don't know why it wasn't doing that by default + return group.getPlaceSound(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java new file mode 100644 index 0000000..d00f353 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java @@ -0,0 +1,38 @@ +package fr.adrien1106.reframed.mixin.sound; + +import com.llamalad7.mixinextras.sugar.Local; +import fr.adrien1106.reframed.block.ReFramedBlock; +import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(Entity.class) +public abstract class EntityMixin { + + @Shadow public abstract World getWorld(); + + @Redirect( + method = "playStepSound", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/BlockState;getSoundGroup()Lnet/minecraft/sound/BlockSoundGroup;" + ) + ) + private BlockSoundGroup playStepCamoSound(BlockState state, @Local(argsOnly = true) BlockPos pos) { + if (state.getBlock() instanceof ReFramedBlock frame_block + && getWorld().getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity + ) { + BlockState camo_state = frame_entity.getTheme(frame_block.getTopThemeIndex(state)); + state = camo_state.getBlock() != Blocks.AIR ? camo_state : state; + } + return state.getSoundGroup(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java new file mode 100644 index 0000000..b7ce6e1 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java @@ -0,0 +1,34 @@ +package fr.adrien1106.reframed.mixin.sound; + +import fr.adrien1106.reframed.block.ReFramedBlock; +import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(LivingEntity.class) +public class LivingEntityMixin { + + @Redirect( + method = "playBlockFallSound", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/World;getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;" + ), remap = false + ) + private BlockState playCamoFallSound(World world, BlockPos pos) { + BlockState state = world.getBlockState(pos); + if (state.getBlock() instanceof ReFramedBlock frame_block + && world.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity + ) { + BlockState camo_state = frame_entity.getTheme(frame_block.getTopThemeIndex(state)); + state = camo_state.getBlock() != Blocks.AIR ? camo_state : state; + } + return state; + } +} diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java new file mode 100644 index 0000000..8d2b11d --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java @@ -0,0 +1,39 @@ +package fr.adrien1106.reframed.mixin.sound; + +import com.llamalad7.mixinextras.sugar.Local; +import fr.adrien1106.reframed.block.ReFramedBlock; +import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.client.render.WorldRenderer; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.util.math.BlockPos; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(WorldRenderer.class) +public class WorldRendererMixin { + + @Shadow @Nullable private ClientWorld world; + + @Redirect( + method = "processWorldEvent", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/BlockState;getSoundGroup()Lnet/minecraft/sound/BlockSoundGroup;" + ) + ) + private BlockSoundGroup getCamoBreakSound(BlockState state, @Local(argsOnly = true) BlockPos pos) { + if (state.getBlock() instanceof ReFramedBlock frame_block + && world.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity + ) { + BlockState camo_state = frame_entity.getTheme(frame_block.getTopThemeIndex(state)); + state = camo_state.getBlock() != Blocks.AIR ? camo_state : state; + } + return state.getSoundGroup(); + } +} diff --git a/src/main/resources/reframed.mixins.json b/src/main/resources/reframed.mixins.json index 48c8ec5..b0280b4 100644 --- a/src/main/resources/reframed.mixins.json +++ b/src/main/resources/reframed.mixins.json @@ -4,10 +4,10 @@ "compatibilityLevel": "JAVA_17", "plugin": "fr.adrien1106.reframed.mixin.CompatMixinPlugin", "mixins": [ + "BlockItemMixin", "WallBlockAccessor", "particles.MixinEntity", - "particles.MixinLivingEntity", - "sound.LivingEntityMixin" + "particles.MixinLivingEntity" ], "client": [ "MinecraftAccessor", @@ -24,7 +24,11 @@ "render.BlockRenderInfoMixin", "render.MultipartBakedModelMixin", "render.TerrainRenderContextMixin", - "render.WorldRendererMixin" + "render.WorldRendererMixin", + "sound.BlockItemMixin", + "sound.EntityMixin", + "sound.LivingEntityMixin", + "sound.WorldRendererMixin" ], "injectors": { "defaultRequire": 1