修复粒子类型错误

This commit is contained in:
17146 2025-06-28 18:14:47 +08:00 committed by Light_Quanta
parent 68890a3b40
commit ca6e687b78
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
4 changed files with 47 additions and 17 deletions

View file

@ -1,10 +1,10 @@
package com.atsuishio.superbwarfare.client.particle; package com.atsuishio.superbwarfare.client.particle;
import com.atsuishio.superbwarfare.init.ModParticleTypes;
import com.mojang.brigadier.StringReader; import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.tacz.guns.init.ModParticles;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleOptions;
@ -13,8 +13,10 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
public class BulletDecalOption implements ParticleOptions { public class BulletDecalOption implements ParticleOptions {
public static final Codec<BulletDecalOption> CODEC = RecordCodecBuilder.create(builder -> public static final Codec<BulletDecalOption> 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()) Codec.LONG.fieldOf("pos").forGetter(option -> option.pos.asLong())
).apply(builder, BulletDecalOption::new)); ).apply(builder, BulletDecalOption::new));
@ -41,7 +43,6 @@ public class BulletDecalOption implements ParticleOptions {
public BulletDecalOption(int dir, long pos) { public BulletDecalOption(int dir, long pos) {
this.direction = Direction.values()[dir]; this.direction = Direction.values()[dir];
this.pos = BlockPos.of(pos); this.pos = BlockPos.of(pos);
} }
public BulletDecalOption(Direction dir, BlockPos pos) { public BulletDecalOption(Direction dir, BlockPos pos) {
@ -59,7 +60,7 @@ public class BulletDecalOption implements ParticleOptions {
@Override @Override
public ParticleType<?> getType() { public ParticleType<?> getType() {
return ModParticles.BULLET_HOLE.get(); return ModParticleTypes.BULLET_DECAL.get();
} }
@Override @Override

View file

@ -16,7 +16,9 @@ import net.minecraft.util.Mth;
import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState; 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.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -24,9 +26,11 @@ import org.joml.Quaternionf;
import org.joml.Vector3f; 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 { public class BulletDecalParticle extends TextureSheetParticle {
private final Direction direction; private final Direction direction;
private final BlockPos pos; private final BlockPos pos;
private int uOffset; private int uOffset;
@ -43,8 +47,7 @@ public class BulletDecalParticle extends TextureSheetParticle {
this.gravity = 0.0F; this.gravity = 0.0F;
this.quadSize = 0.05F; this.quadSize = 0.05F;
// 如果方块是空气则立即移除粒子 if (shouldRemove()) {
if (world.getBlockState(pos).isAir()) {
this.remove(); this.remove();
} }
@ -60,16 +63,15 @@ public class BulletDecalParticle extends TextureSheetParticle {
super.setSprite(sprite); super.setSprite(sprite);
this.uOffset = this.random.nextInt(16); this.uOffset = this.random.nextInt(16);
this.vOffset = this.random.nextInt(16); this.vOffset = this.random.nextInt(16);
// 材质应该都是方形
this.textureDensity = (sprite.getU1() - sprite.getU0()) / 16.0F; this.textureDensity = (sprite.getU1() - sprite.getU0()) / 16.0F;
} }
private TextureAtlasSprite getSprite(BlockPos pos) { private TextureAtlasSprite getSprite(BlockPos pos) {
Minecraft minecraft = Minecraft.getInstance(); Minecraft minecraft = Minecraft.getInstance();
Level world = minecraft.level; Level clientLevel = minecraft.level;
if (world != null) { if (clientLevel != null) {
BlockState state = world.getBlockState(pos); BlockState state = clientLevel.getBlockState(pos);
return Minecraft.getInstance().getBlockRenderer().getBlockModelShaper().getTexture(state, world, pos); return Minecraft.getInstance().getBlockRenderer().getBlockModelShaper().getTexture(state, clientLevel, pos);
} }
return Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(MissingTextureAtlasSprite.getLocation()); return Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(MissingTextureAtlasSprite.getLocation());
} }
@ -97,7 +99,7 @@ public class BulletDecalParticle extends TextureSheetParticle {
@Override @Override
public void tick() { public void tick() {
super.tick(); super.tick();
if (this.level.getBlockState(this.pos).isAir()) { if (shouldRemove()) {
this.remove(); 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); 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 @Override
public @NotNull ParticleRenderType getRenderType() { public @NotNull ParticleRenderType getRenderType() {
return ParticleRenderType.TERRAIN_SHEET; return ParticleRenderType.TERRAIN_SHEET;

View file

@ -6,9 +6,11 @@ import com.mojang.serialization.Codec;
import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType; import net.minecraft.core.particles.ParticleType;
import net.minecraft.core.particles.SimpleParticleType; import net.minecraft.core.particles.SimpleParticleType;
import net.minecraftforge.registries.DeferredRegister; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraftforge.registries.RegistryObject; import net.minecraft.network.codec.StreamCodec;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ModParticleTypes { public class ModParticleTypes {
@ -16,7 +18,8 @@ public class ModParticleTypes {
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> FIRE_STAR = REGISTRY.register("fire_star", () -> new SimpleParticleType(false)); public static final DeferredHolder<ParticleType<?>, SimpleParticleType> FIRE_STAR = REGISTRY.register("fire_star", () -> new SimpleParticleType(false));
public static final DeferredHolder<ParticleType<?>, ModParticleType<? extends ParticleOptions>> BULLET_DECAL = REGISTRY.register("bullet_decal", () -> new ModParticleType<>(false, BulletDecalOption.DESERIALIZER, BulletDecalOption.CODEC)); public static final DeferredHolder<ParticleType<?>, ModParticleType<? extends ParticleOptions>> BULLET_DECAL = REGISTRY.register("bullet_decal",
() -> new ModParticleType<>(false, BulletDecalOption.DESERIALIZER, BulletDecalOption.CODEC));
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> CUSTOM_CLOUD = REGISTRY.register("custom_cloud", () -> new SimpleParticleType(false)); public static final DeferredHolder<ParticleType<?>, SimpleParticleType> CUSTOM_CLOUD = REGISTRY.register("custom_cloud", () -> new SimpleParticleType(false));
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> CUSTOM_SMOKE = REGISTRY.register("custom_smoke", () -> new SimpleParticleType(false)); public static final DeferredHolder<ParticleType<?>, SimpleParticleType> CUSTOM_SMOKE = REGISTRY.register("custom_smoke", () -> new SimpleParticleType(false));
@ -33,6 +36,11 @@ public class ModParticleTypes {
public @NotNull Codec<T> codec() { public @NotNull Codec<T> codec() {
return this.codec; return this.codec;
} }
@Override
public StreamCodec<? super RegistryFriendlyByteBuf, T> streamCodec() {
return this.codec;
}
} }
} }

View file

@ -11,6 +11,7 @@ import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) @EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
public class ModParticles { public class ModParticles {
@SubscribeEvent @SubscribeEvent
public static void registerParticles(RegisterParticleProvidersEvent event) { public static void registerParticles(RegisterParticleProvidersEvent event) {
event.registerSpriteSet(ModParticleTypes.FIRE_STAR.get(), FireStarParticle::provider); event.registerSpriteSet(ModParticleTypes.FIRE_STAR.get(), FireStarParticle::provider);