尝试抄tacz的弹孔,但是不显示(恼
This commit is contained in:
parent
acbbc1bff4
commit
68890a3b40
9 changed files with 292 additions and 64 deletions
|
@ -0,0 +1,75 @@
|
|||
package com.atsuishio.superbwarfare.client.particle;
|
||||
|
||||
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;
|
||||
import net.minecraft.core.particles.ParticleType;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class BulletDecalOption implements ParticleOptions {
|
||||
public static final Codec<BulletDecalOption> CODEC = RecordCodecBuilder.create(builder ->
|
||||
builder.group(Codec.INT.fieldOf("dir").forGetter(option -> option.direction.ordinal()),
|
||||
Codec.LONG.fieldOf("pos").forGetter(option -> option.pos.asLong())
|
||||
).apply(builder, BulletDecalOption::new));
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static final ParticleOptions.Deserializer<BulletDecalOption> DESERIALIZER = new ParticleOptions.Deserializer<>() {
|
||||
@Override
|
||||
public BulletDecalOption fromCommand(ParticleType<BulletDecalOption> particleType, StringReader reader) throws CommandSyntaxException {
|
||||
reader.expect(' ');
|
||||
int dir = reader.readInt();
|
||||
reader.expect(' ');
|
||||
long pos = reader.readLong();
|
||||
return new BulletDecalOption(dir, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BulletDecalOption fromNetwork(ParticleType<BulletDecalOption> particleType, FriendlyByteBuf buffer) {
|
||||
return new BulletDecalOption(buffer.readVarInt(), buffer.readLong());
|
||||
}
|
||||
};
|
||||
|
||||
private final Direction direction;
|
||||
private final BlockPos pos;
|
||||
|
||||
public BulletDecalOption(int dir, long pos) {
|
||||
this.direction = Direction.values()[dir];
|
||||
this.pos = BlockPos.of(pos);
|
||||
|
||||
}
|
||||
|
||||
public BulletDecalOption(Direction dir, BlockPos pos) {
|
||||
this.direction = dir;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public Direction getDirection() {
|
||||
return this.direction;
|
||||
}
|
||||
|
||||
public BlockPos getPos() {
|
||||
return this.pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParticleType<?> getType() {
|
||||
return ModParticles.BULLET_HOLE.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNetwork(FriendlyByteBuf buffer) {
|
||||
buffer.writeEnum(this.direction);
|
||||
buffer.writeBlockPos(this.pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String writeToString() {
|
||||
return ForgeRegistries.PARTICLE_TYPES.getKey(this.getType()) + " " + this.direction.getName();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
package com.atsuishio.superbwarfare.client.particle;
|
||||
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.ParticleProvider;
|
||||
import net.minecraft.client.particle.ParticleRenderType;
|
||||
import net.minecraft.client.particle.TextureSheetParticle;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
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.Vec3;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
* Author: Forked from MrCrayfish, continued by Timeless devs
|
||||
*/
|
||||
public class BulletDecalParticle extends TextureSheetParticle {
|
||||
private final Direction direction;
|
||||
private final BlockPos pos;
|
||||
private int uOffset;
|
||||
private int vOffset;
|
||||
private float textureDensity;
|
||||
|
||||
public BulletDecalParticle(ClientLevel world, double x, double y, double z, Direction direction, BlockPos pos) {
|
||||
super(world, x, y, z);
|
||||
this.setSprite(this.getSprite(pos));
|
||||
this.direction = direction;
|
||||
this.pos = pos;
|
||||
this.lifetime = 200;
|
||||
this.hasPhysics = false;
|
||||
this.gravity = 0.0F;
|
||||
this.quadSize = 0.05F;
|
||||
|
||||
// 如果方块是空气,则立即移除粒子
|
||||
if (world.getBlockState(pos).isAir()) {
|
||||
this.remove();
|
||||
}
|
||||
|
||||
this.rCol = 0;
|
||||
this.gCol = 0;
|
||||
this.bCol = 0;
|
||||
|
||||
this.alpha = 0.9F;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSprite(@NotNull TextureAtlasSprite sprite) {
|
||||
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);
|
||||
}
|
||||
return Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(MissingTextureAtlasSprite.getLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getU0() {
|
||||
return this.sprite.getU0() + this.uOffset * this.textureDensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getV0() {
|
||||
return this.sprite.getV0() + this.vOffset * this.textureDensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getU1() {
|
||||
return this.getU0() + this.textureDensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getV1() {
|
||||
return this.getV0() + this.textureDensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (this.level.getBlockState(this.pos).isAir()) {
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(@NotNull VertexConsumer buffer, Camera renderInfo, float partialTicks) {
|
||||
Vec3 view = renderInfo.getPosition();
|
||||
float particleX = (float) (Mth.lerp(partialTicks, this.xo, this.x) - view.x());
|
||||
float particleY = (float) (Mth.lerp(partialTicks, this.yo, this.y) - view.y());
|
||||
float particleZ = (float) (Mth.lerp(partialTicks, this.zo, this.z) - view.z());
|
||||
Quaternionf quaternion = this.direction.getRotation();
|
||||
Vector3f[] points = new Vector3f[]{
|
||||
// Y 值稍微大一点点,防止 z-fight
|
||||
new Vector3f(-1.0F, 0.01F, -1.0F),
|
||||
new Vector3f(-1.0F, 0.01F, 1.0F),
|
||||
new Vector3f(1.0F, 0.01F, 1.0F),
|
||||
new Vector3f(1.0F, 0.01F, -1.0F)
|
||||
};
|
||||
float scale = this.getQuadSize(partialTicks);
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Vector3f vector3f = points[i];
|
||||
vector3f.rotate(quaternion);
|
||||
vector3f.mul(scale);
|
||||
vector3f.add(particleX, particleY, particleZ);
|
||||
}
|
||||
|
||||
// UV 坐标
|
||||
float u0 = this.getU0();
|
||||
float u1 = this.getU1();
|
||||
float v0 = this.getV0();
|
||||
float v1 = this.getV1();
|
||||
|
||||
// 0 - 30 tick 内,从 15 亮度到 0 亮度
|
||||
int light = Math.max(15 - this.age / 2, 0);
|
||||
int lightColor = LightTexture.pack(light, light);
|
||||
|
||||
// 颜色,逐渐渐变到 0 0 0,也就是黑色
|
||||
float colorPercent = light / 15.0f;
|
||||
float red = this.rCol * colorPercent;
|
||||
float green = this.gCol * colorPercent;
|
||||
float blue = this.bCol * colorPercent;
|
||||
|
||||
// 透明度,逐渐变成 0,也就是透明
|
||||
double threshold = 0.98 * this.lifetime;
|
||||
float fade = 1.0f - (float) (Math.max(this.age - threshold, 0) / (this.lifetime - threshold));
|
||||
float alphaFade = this.alpha * fade;
|
||||
|
||||
buffer.addVertex(points[0].x(), points[0].y(), points[0].z()).setUv(u1, v1).setColor(red, green, blue, alphaFade).setLight(lightColor);
|
||||
buffer.addVertex(points[1].x(), points[1].y(), points[1].z()).setUv(u1, v0).setColor(red, green, blue, alphaFade).setLight(lightColor);
|
||||
buffer.addVertex(points[2].x(), points[2].y(), points[2].z()).setUv(u0, v0).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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ParticleRenderType getRenderType() {
|
||||
return ParticleRenderType.TERRAIN_SHEET;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Provider implements ParticleProvider<BulletDecalOption> {
|
||||
public Provider() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BulletDecalParticle createParticle(@NotNull BulletDecalOption option, @NotNull ClientLevel world, double x, double y, double z, double pXSpeed, double pYSpeed, double pZSpeed) {
|
||||
return new BulletDecalParticle(world, x, y, z, option.getDirection(), option.getPos());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package com.atsuishio.superbwarfare.client.particle;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.*;
|
||||
import net.minecraft.core.particles.SimpleParticleType;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class BulletHoleParticle extends TextureSheetParticle {
|
||||
public static BulletholeParticleProvider provider(SpriteSet spriteSet) {
|
||||
return new BulletholeParticleProvider(spriteSet);
|
||||
}
|
||||
|
||||
public static class BulletholeParticleProvider implements ParticleProvider<SimpleParticleType> {
|
||||
private final SpriteSet spriteSet;
|
||||
|
||||
public BulletholeParticleProvider(SpriteSet spriteSet) {
|
||||
this.spriteSet = spriteSet;
|
||||
}
|
||||
|
||||
public Particle createParticle(@NotNull SimpleParticleType typeIn, @NotNull ClientLevel worldIn, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) {
|
||||
return new BulletHoleParticle(worldIn, x, y, z, xSpeed, ySpeed, zSpeed, this.spriteSet);
|
||||
}
|
||||
}
|
||||
|
||||
protected BulletHoleParticle(ClientLevel world, double x, double y, double z, double vx, double vy, double vz, SpriteSet spriteSet) {
|
||||
super(world, x, y, z);
|
||||
this.setSize(0f, 0f);
|
||||
this.lifetime = 100;
|
||||
this.gravity = 0f;
|
||||
this.hasPhysics = false;
|
||||
this.xd = vx * 0;
|
||||
this.yd = vy * 0;
|
||||
this.zd = vz * 0;
|
||||
this.pickSprite(spriteSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ParticleRenderType getRenderType() {
|
||||
return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.entity.projectile;
|
|||
|
||||
import com.atsuishio.superbwarfare.block.BarbedWireBlock;
|
||||
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||
import com.atsuishio.superbwarfare.client.particle.BulletDecalOption;
|
||||
import com.atsuishio.superbwarfare.config.server.ProjectileConfig;
|
||||
import com.atsuishio.superbwarfare.entity.DPSGeneratorEntity;
|
||||
import com.atsuishio.superbwarfare.entity.OBBEntity;
|
||||
|
@ -18,6 +19,7 @@ import com.mojang.datafixers.util.Pair;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.particles.BlockParticleOption;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
|
@ -413,7 +415,7 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
|
|||
recordHitScore(rings, dis);
|
||||
}
|
||||
|
||||
this.onHitBlock(hitVec);
|
||||
this.onHitBlock(hitVec, blockHitResult);
|
||||
if (heLevel > 0) {
|
||||
explosionBullet(this, this.damage, heLevel, monsterMultiplier + 1, hitVec);
|
||||
}
|
||||
|
@ -492,13 +494,27 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
|
|||
}
|
||||
}
|
||||
|
||||
protected void onHitBlock(Vec3 location) {
|
||||
protected void onHitBlock(Vec3 location, BlockHitResult result) {
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
BlockPos pos = result.getBlockPos();
|
||||
Direction face = result.getDirection();
|
||||
BlockState state = level().getBlockState(pos);
|
||||
|
||||
BlockParticleOption particleData = new BlockParticleOption(ParticleTypes.BLOCK, state);
|
||||
|
||||
double speed = 0.05;
|
||||
double vx = face.getStepX() * speed;
|
||||
double vy = face.getStepY() * speed;
|
||||
double vz = face.getStepZ() * speed;
|
||||
|
||||
if (this.beast) {
|
||||
ParticleTool.sendParticle(serverLevel, ParticleTypes.END_ROD, location.x, location.y, location.z, 15, 0.1, 0.1, 0.1, 0.05, true);
|
||||
} else {
|
||||
ParticleTool.sendParticle(serverLevel, ModParticleTypes.BULLET_HOLE.get(), location.x, location.y, location.z, 1, 0, 0, 0, 0, true);
|
||||
ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, location.x, location.y, location.z, 3, 0, 0.1, 0, 0.01, true);
|
||||
BulletDecalOption bulletDecalOption = new BulletDecalOption(result.getDirection(), result.getBlockPos());
|
||||
serverLevel.sendParticles(bulletDecalOption, location.x, location.y, location.z, 1, 0, 0, 0, 0);
|
||||
|
||||
ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, location.x, location.y, location.z, 3, vx, vy, vz, 0.01, true);
|
||||
ParticleTool.sendParticle(serverLevel, particleData, location.x, location.y, location.z, 5, vx, vy, vz, 0.1, true);
|
||||
this.discard();
|
||||
}
|
||||
serverLevel.playSound(null, new BlockPos((int) location.x, (int) location.y, (int) location.z), ModSounds.LAND.get(), SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
|
|
|
@ -1,18 +1,38 @@
|
|||
package com.atsuishio.superbwarfare.init;
|
||||
|
||||
import com.atsuishio.superbwarfare.Mod;
|
||||
import com.atsuishio.superbwarfare.client.particle.BulletDecalOption;
|
||||
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.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ModParticleTypes {
|
||||
public static final DeferredRegister<ParticleType<?>> REGISTRY = DeferredRegister.create(BuiltInRegistries.PARTICLE_TYPE, Mod.MODID);
|
||||
|
||||
|
||||
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> FIRE_STAR = REGISTRY.register("fire_star", () -> new SimpleParticleType(false));
|
||||
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> BULLET_HOLE = REGISTRY.register("bullet_hole", () -> 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<?>, 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));
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static class ModParticleType<T extends ParticleOptions> extends ParticleType<T> {
|
||||
private final Codec<T> codec;
|
||||
|
||||
public ModParticleType(boolean overrideLimiter, ParticleOptions.Deserializer<T> deserializer, Codec<T> codec) {
|
||||
super(overrideLimiter, deserializer);
|
||||
this.codec = codec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Codec<T> codec() {
|
||||
return this.codec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.atsuishio.superbwarfare.init;
|
||||
|
||||
import com.atsuishio.superbwarfare.client.particle.BulletHoleParticle;
|
||||
import com.atsuishio.superbwarfare.client.particle.BulletDecalParticle;
|
||||
import com.atsuishio.superbwarfare.client.particle.CustomCloudParticle;
|
||||
import com.atsuishio.superbwarfare.client.particle.CustomSmokeParticle;
|
||||
import com.atsuishio.superbwarfare.client.particle.FireStarParticle;
|
||||
|
@ -14,7 +14,7 @@ public class ModParticles {
|
|||
@SubscribeEvent
|
||||
public static void registerParticles(RegisterParticleProvidersEvent event) {
|
||||
event.registerSpriteSet(ModParticleTypes.FIRE_STAR.get(), FireStarParticle::provider);
|
||||
event.registerSpriteSet(ModParticleTypes.BULLET_HOLE.get(), BulletHoleParticle::provider);
|
||||
event.registerSpecial(ModParticleTypes.BULLET_DECAL.get(), new BulletDecalParticle.Provider());
|
||||
event.registerSpriteSet(ModParticleTypes.CUSTOM_CLOUD.get(), CustomCloudParticle::provider);
|
||||
event.registerSpriteSet(ModParticleTypes.CUSTOM_SMOKE.get(), CustomSmokeParticle::provider);
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"textures": [
|
||||
"superbwarfare:bullet_hole"
|
||||
]
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 99 B |
Loading…
Add table
Reference in a new issue