Particles. Intentionally omitted the blockcrack particle customization, i think it looks fine

This commit is contained in:
quat1024 2023-07-03 20:39:48 -04:00
parent 2646ce2df9
commit 2d319a8e50
8 changed files with 109 additions and 7 deletions

View File

@ -0,0 +1,7 @@
package io.github.cottonmc.templates.api;
import net.minecraft.block.BlockState;
public interface ThemeableBlockEntity {
BlockState getThemeState();
}

View File

@ -5,7 +5,6 @@ import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
@ -79,7 +78,7 @@ public abstract class TemplateBlock extends Block implements BlockEntityProvider
} }
//Changing the theme //Changing the theme
if(held.getItem() instanceof BlockItem bi && be.getRenderedState().getBlock() == Blocks.AIR) { if(held.getItem() instanceof BlockItem bi && be.getThemeState().getBlock() == Blocks.AIR) {
Block block = bi.getBlock(); Block block = bi.getBlock();
ItemPlacementContext ctx = new ItemPlacementContext(new ItemUsageContext(player, hand, hit)); ItemPlacementContext ctx = new ItemPlacementContext(new ItemUsageContext(player, hand, hit));
BlockState placementState = block.getPlacementState(ctx); BlockState placementState = block.getPlacementState(ctx);
@ -104,8 +103,10 @@ public abstract class TemplateBlock extends Block implements BlockEntityProvider
if(!state.isOf(newState.getBlock()) && world.getBlockEntity(pos) instanceof TemplateEntity template) { if(!state.isOf(newState.getBlock()) && world.getBlockEntity(pos) instanceof TemplateEntity template) {
DefaultedList<ItemStack> drops = DefaultedList.of(); DefaultedList<ItemStack> drops = DefaultedList.of();
Block theme = template.getRenderedState().getBlock(); //TODO: remember the specific ItemStack
Block theme = template.getThemeState().getBlock();
if(theme != Blocks.AIR) drops.add(new ItemStack(theme)); if(theme != Blocks.AIR) drops.add(new ItemStack(theme));
if(template.hasSpentRedstoneTorch()) drops.add(new ItemStack(Items.REDSTONE_TORCH)); if(template.hasSpentRedstoneTorch()) drops.add(new ItemStack(Items.REDSTONE_TORCH));
if(template.hasSpentGlowstoneDust()) drops.add(new ItemStack(Items.GLOWSTONE_DUST)); if(template.hasSpentGlowstoneDust()) drops.add(new ItemStack(Items.GLOWSTONE_DUST));

View File

@ -1,6 +1,7 @@
package io.github.cottonmc.templates.block.entity; package io.github.cottonmc.templates.block.entity;
import io.github.cottonmc.templates.Templates; import io.github.cottonmc.templates.Templates;
import io.github.cottonmc.templates.api.ThemeableBlockEntity;
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachmentBlockEntity; import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachmentBlockEntity;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
@ -18,7 +19,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Objects; import java.util.Objects;
public class TemplateEntity extends BlockEntity implements RenderAttachmentBlockEntity { public class TemplateEntity extends BlockEntity implements RenderAttachmentBlockEntity, ThemeableBlockEntity {
protected BlockState renderedState = Blocks.AIR.getDefaultState(); protected BlockState renderedState = Blocks.AIR.getDefaultState();
//Whether the player has manually spent a redstone/glowstone item to upgrade the template. //Whether the player has manually spent a redstone/glowstone item to upgrade the template.
@ -74,7 +75,8 @@ public class TemplateEntity extends BlockEntity implements RenderAttachmentBlock
return renderedState; return renderedState;
} }
public BlockState getRenderedState() { @Override
public BlockState getThemeState() {
return renderedState; return renderedState;
} }

View File

@ -0,0 +1,33 @@
package io.github.cottonmc.templates.mixin.particles;
import io.github.cottonmc.templates.api.ThemeableBlockEntity;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
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.ModifyArg;
@Mixin(Entity.class)
public abstract class MixinEntity {
@Shadow @Deprecated public abstract BlockPos getLandingPos(); //TODO, somewhat expensive method
@ModifyArg(
method = "spawnSprintingParticles",
at = @At(value = "INVOKE", target = "Lnet/minecraft/particle/BlockStateParticleEffect;<init>(Lnet/minecraft/particle/ParticleType;Lnet/minecraft/block/BlockState;)V"),
require = 0
)
private BlockState templates$spawnSprintingParticles$modifyParticleState(BlockState origState) {
World world = ((Entity) (Object) this).getWorld();
if(world.getBlockEntity(getLandingPos()) instanceof ThemeableBlockEntity themeable) {
BlockState theme = themeable.getThemeState();
if(theme.getBlock() != Blocks.AIR) return theme;
}
return origState;
}
}

View File

@ -0,0 +1,41 @@
package io.github.cottonmc.templates.mixin.particles;
import io.github.cottonmc.templates.api.ThemeableBlockEntity;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
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.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LivingEntity.class)
public class MixinLivingEntity {
@Unique private BlockPos lastFallCheckPos;
@Inject(method = "fall", at = @At("HEAD"))
private void templates$onFall(double d, boolean bl, BlockState blockState, BlockPos blockPos, CallbackInfo ci) {
lastFallCheckPos = blockPos;
}
@ModifyArg(
method = "fall",
at = @At(value = "INVOKE", target = "Lnet/minecraft/particle/BlockStateParticleEffect;<init>(Lnet/minecraft/particle/ParticleType;Lnet/minecraft/block/BlockState;)V"),
require = 0
)
private BlockState templates$fall$modifyParticleState(BlockState origState) {
World world = ((Entity) (Object) this).getWorld();
if(lastFallCheckPos != null && world.getBlockEntity(lastFallCheckPos) instanceof ThemeableBlockEntity themeable) {
BlockState theme = themeable.getThemeState();
if(theme.getBlock() != Blocks.AIR) return theme;
}
return origState;
}
}

View File

@ -1,6 +1,9 @@
{ {
"parent": "block/block", "parent": "block/block",
"gui_light": "front", "gui_light": "front",
"textures": {
"particle": "block/scaffolding_top"
},
"display": { "display": {
"firstperson_righthand": { "firstperson_righthand": {
"rotation": [ 0, 135, 0 ], "rotation": [ 0, 135, 0 ],

View File

@ -9,6 +9,9 @@
"contact": { "contact": {
"sources": "https://github.com/CottonMC/Templates" "sources": "https://github.com/CottonMC/Templates"
}, },
"mixins": [
"templates.mixins.json"
],
"environment": "*", "environment": "*",
"entrypoints": { "entrypoints": {
"main": [ "main": [
@ -21,7 +24,6 @@
"depends": { "depends": {
"minecraft": ">=1.20.1", "minecraft": ">=1.20.1",
"fabricloader": "*", "fabricloader": "*",
"fabric-api": "*", "fabric-api": "*"
"fabric-renderer-indigo": "*"
} }
} }

View File

@ -0,0 +1,13 @@
{
"required": true,
"package": "io.github.cottonmc.templates.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
"particles.MixinEntity",
"particles.MixinLivingEntity"
],
"injectors": {
"defaultRequire": 1
},
"refmap": "packages.refmap.json"
}