diff --git a/src/main/java/com/atsuishio/superbwarfare/client/particle/BulletDecalOption.java b/src/main/java/com/atsuishio/superbwarfare/client/particle/BulletDecalOption.java index aa10150ca..a89b8881b 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/particle/BulletDecalOption.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/particle/BulletDecalOption.java @@ -1,10 +1,10 @@ package com.atsuishio.superbwarfare.client.particle; +import com.atsuishio.superbwarfare.init.ModParticleTypes; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import com.tacz.guns.init.ModParticles; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.particles.ParticleOptions; @@ -13,8 +13,10 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraftforge.registries.ForgeRegistries; public class BulletDecalOption implements ParticleOptions { + public static final Codec CODEC = RecordCodecBuilder.create(builder -> - builder.group(Codec.INT.fieldOf("dir").forGetter(option -> option.direction.ordinal()), + builder.group( + Codec.INT.fieldOf("dir").forGetter(option -> option.direction.ordinal()), Codec.LONG.fieldOf("pos").forGetter(option -> option.pos.asLong()) ).apply(builder, BulletDecalOption::new)); @@ -41,7 +43,6 @@ public class BulletDecalOption implements ParticleOptions { public BulletDecalOption(int dir, long pos) { this.direction = Direction.values()[dir]; this.pos = BlockPos.of(pos); - } public BulletDecalOption(Direction dir, BlockPos pos) { @@ -59,7 +60,7 @@ public class BulletDecalOption implements ParticleOptions { @Override public ParticleType getType() { - return ModParticles.BULLET_HOLE.get(); + return ModParticleTypes.BULLET_DECAL.get(); } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/client/particle/BulletDecalParticle.java b/src/main/java/com/atsuishio/superbwarfare/client/particle/BulletDecalParticle.java index 165d88a4f..6d1c94146 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/particle/BulletDecalParticle.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/particle/BulletDecalParticle.java @@ -16,7 +16,9 @@ import net.minecraft.util.Mth; import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.VoxelShape; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import org.jetbrains.annotations.NotNull; @@ -24,9 +26,11 @@ import org.joml.Quaternionf; import org.joml.Vector3f; /** - * Author: Forked from MrCrayfish, continued by Timeless devs + * @author Forked from MrCrayfish, continued by Timeless devs + * Code based on TaC-Z */ public class BulletDecalParticle extends TextureSheetParticle { + private final Direction direction; private final BlockPos pos; private int uOffset; @@ -43,8 +47,7 @@ public class BulletDecalParticle extends TextureSheetParticle { this.gravity = 0.0F; this.quadSize = 0.05F; - // 如果方块是空气,则立即移除粒子 - if (world.getBlockState(pos).isAir()) { + if (shouldRemove()) { this.remove(); } @@ -60,16 +63,15 @@ public class BulletDecalParticle extends TextureSheetParticle { super.setSprite(sprite); this.uOffset = this.random.nextInt(16); this.vOffset = this.random.nextInt(16); - // 材质应该都是方形 this.textureDensity = (sprite.getU1() - sprite.getU0()) / 16.0F; } private TextureAtlasSprite getSprite(BlockPos pos) { Minecraft minecraft = Minecraft.getInstance(); - Level world = minecraft.level; - if (world != null) { - BlockState state = world.getBlockState(pos); - return Minecraft.getInstance().getBlockRenderer().getBlockModelShaper().getTexture(state, world, pos); + Level clientLevel = minecraft.level; + if (clientLevel != null) { + BlockState state = clientLevel.getBlockState(pos); + return Minecraft.getInstance().getBlockRenderer().getBlockModelShaper().getTexture(state, clientLevel, pos); } return Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(MissingTextureAtlasSprite.getLocation()); } @@ -97,7 +99,7 @@ public class BulletDecalParticle extends TextureSheetParticle { @Override public void tick() { super.tick(); - if (this.level.getBlockState(this.pos).isAir()) { + if (shouldRemove()) { this.remove(); } } @@ -152,6 +154,24 @@ public class BulletDecalParticle extends TextureSheetParticle { buffer.addVertex(points[3].x(), points[3].y(), points[3].z()).setUv(u0, v1).setColor(red, green, blue, alphaFade).setLight(lightColor); } + private boolean shouldRemove() { + final BlockState blockState = this.level.getBlockState(this.pos); + if (blockState.isAir()) { + return true; + } else { + // 阻止弹孔在与方块不构成有效附着时继续渲染 + VoxelShape shape = blockState.getCollisionShape(this.level, this.pos); + if (shape.isEmpty()) { + return true; + } + AABB baseBlockBoundingBox = shape.bounds(); + AABB blockBoundingBox = baseBlockBoundingBox.move(this.pos); + return !blockBoundingBox.intersects( + this.x - 0.1, this.y - 0.1, this.z - 0.1, + this.x + 0.1, this.y + 0.1, this.z + 0.1); + } + } + @Override public @NotNull ParticleRenderType getRenderType() { return ParticleRenderType.TERRAIN_SHEET; diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModParticleTypes.java b/src/main/java/com/atsuishio/superbwarfare/init/ModParticleTypes.java index e043a1dcf..6665fb90d 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModParticleTypes.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModParticleTypes.java @@ -6,9 +6,11 @@ import com.mojang.serialization.Codec; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleType; import net.minecraft.core.particles.SimpleParticleType; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; import org.jetbrains.annotations.NotNull; public class ModParticleTypes { @@ -16,7 +18,8 @@ public class ModParticleTypes { public static final DeferredHolder, SimpleParticleType> FIRE_STAR = REGISTRY.register("fire_star", () -> new SimpleParticleType(false)); - public static final DeferredHolder, ModParticleType> BULLET_DECAL = REGISTRY.register("bullet_decal", () -> new ModParticleType<>(false, BulletDecalOption.DESERIALIZER, BulletDecalOption.CODEC)); + public static final DeferredHolder, ModParticleType> BULLET_DECAL = REGISTRY.register("bullet_decal", + () -> new ModParticleType<>(false, BulletDecalOption.DESERIALIZER, BulletDecalOption.CODEC)); public static final DeferredHolder, SimpleParticleType> CUSTOM_CLOUD = REGISTRY.register("custom_cloud", () -> new SimpleParticleType(false)); public static final DeferredHolder, SimpleParticleType> CUSTOM_SMOKE = REGISTRY.register("custom_smoke", () -> new SimpleParticleType(false)); @@ -33,6 +36,11 @@ public class ModParticleTypes { public @NotNull Codec codec() { return this.codec; } + + @Override + public StreamCodec streamCodec() { + return this.codec; + } } } diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModParticles.java b/src/main/java/com/atsuishio/superbwarfare/init/ModParticles.java index cdcd95d78..1935826f7 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModParticles.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModParticles.java @@ -11,6 +11,7 @@ import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent; @EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) public class ModParticles { + @SubscribeEvent public static void registerParticles(RegisterParticleProvidersEvent event) { event.registerSpriteSet(ModParticleTypes.FIRE_STAR.get(), FireStarParticle::provider);