实现烟雾染色

This commit is contained in:
17146 2025-07-07 18:59:25 +08:00 committed by Light_Quanta
parent c69536f32c
commit cc1f635ad1
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
7 changed files with 96 additions and 50 deletions

View file

@ -0,0 +1,59 @@
package com.atsuishio.superbwarfare.client.particle;
import com.atsuishio.superbwarfare.init.ModParticleTypes;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.netty.buffer.ByteBuf;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import org.jetbrains.annotations.NotNull;
public class CustomSmokeOption implements ParticleOptions {
public static final MapCodec<CustomSmokeOption> CODEC = RecordCodecBuilder.mapCodec(builder ->
builder.group(
Codec.FLOAT.fieldOf("r").forGetter(option -> option.red),
Codec.FLOAT.fieldOf("g").forGetter(option -> option.green),
Codec.FLOAT.fieldOf("b").forGetter(option -> option.blue)
).apply(builder, CustomSmokeOption::new));
public static final StreamCodec<ByteBuf, CustomSmokeOption> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.FLOAT,
CustomSmokeOption::getRed,
ByteBufCodecs.FLOAT,
CustomSmokeOption::getGreen,
ByteBufCodecs.FLOAT,
CustomSmokeOption::getBlue,
CustomSmokeOption::new
);
private final float red;
private final float green;
private final float blue;
public CustomSmokeOption(float r, float g, float b) {
this.red = r;
this.green = g;
this.blue = b;
}
public float getRed() {
return red;
}
public float getGreen() {
return green;
}
public float getBlue() {
return blue;
}
@Override
public @NotNull ParticleType<?> getType() {
return ModParticleTypes.CUSTOM_SMOKE.get();
}
}

View file

@ -2,33 +2,15 @@ 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 CustomSmokeParticle extends TextureSheetParticle {
public static FireStarParticleProvider provider(SpriteSet spriteSet) {
return new FireStarParticleProvider(spriteSet);
}
public static class FireStarParticleProvider implements ParticleProvider<SimpleParticleType> {
private final SpriteSet spriteSet;
public FireStarParticleProvider(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 CustomSmokeParticle(worldIn, x, y, z, xSpeed, ySpeed, zSpeed, this.spriteSet);
}
}
private final SpriteSet spriteSet;
protected CustomSmokeParticle(ClientLevel world, double x, double y, double z, double vx, double vy, double vz, SpriteSet spriteSet) {
super(world, x, y, z);
protected CustomSmokeParticle(ClientLevel level, double x, double y, double z, double vx, double vy, double vz, SpriteSet spriteSet, float rCol, float gCol, float bCol) {
super(level, x, y, z);
this.spriteSet = spriteSet;
this.setSize(0.4f, 0.4f);
this.quadSize *= 10f;
@ -39,6 +21,24 @@ public class CustomSmokeParticle extends TextureSheetParticle {
this.yd = vy * 0.9;
this.zd = vz * 0.9;
this.setSpriteFromAge(spriteSet);
this.rCol = rCol;
this.gCol = gCol;
this.bCol = bCol;
}
private final SpriteSet spriteSet;
@OnlyIn(Dist.CLIENT)
public static class Provider implements ParticleProvider<CustomSmokeOption> {
private final SpriteSet spriteSet;
public Provider(SpriteSet spriteSet) {
this.spriteSet = spriteSet;
}
public Particle createParticle(CustomSmokeOption pType, @NotNull ClientLevel pLevel, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) {
return new CustomSmokeParticle(pLevel, x, y, z, xSpeed, ySpeed, zSpeed, this.spriteSet, pType.getRed(), pType.getGreen(), pType.getBlue());
}
}
@Override

View file

@ -1,9 +1,8 @@
package com.atsuishio.superbwarfare.entity.projectile;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.client.particle.CustomSmokeOption;
import com.atsuishio.superbwarfare.init.ModEntities;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModParticleTypes;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
import com.atsuishio.superbwarfare.tools.ParticleTool;
@ -11,8 +10,6 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
@ -30,9 +27,7 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.NetworkHooks;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.PlayMessages;
import net.neoforged.neoforge.network.PacketDistributor;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
@ -79,12 +74,7 @@ public class M18SmokeGrenadeEntity extends ThrowableItemProjectile implements Ge
}
@Override
public Packet<ClientGamePacketListener> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
protected Item getDefaultItem() {
protected @NotNull Item getDefaultItem() {
return ModItems.M18_SMOKE_GRENADE.get();
}
@ -121,8 +111,7 @@ public class M18SmokeGrenadeEntity extends ThrowableItemProjectile implements Ge
if (this.getOwner() instanceof LivingEntity living) {
if (!living.level().isClientSide() && living instanceof ServerPlayer player) {
living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1);
Mod.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new ClientIndicatorMessage(0, 5));
PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(0, 5));
}
}
entity.hurt(entity.damageSources().thrown(this, this.getOwner()), 1);
@ -171,7 +160,7 @@ public class M18SmokeGrenadeEntity extends ThrowableItemProjectile implements Ge
if (fuse <= 0 && tickCount % 2 == 0) {
if (this.level() instanceof ServerLevel serverLevel) {
ParticleTool.sendParticle(serverLevel, ModParticleTypes.CUSTOM_SMOKE.get(), this.getX(), this.getY() + getBbHeight(), this.getZ(),
ParticleTool.sendParticle(serverLevel, new CustomSmokeOption(1, 1, 1), this.getX(), this.getY() + getBbHeight(), this.getZ(),
8, 0.075, 0.01, 0.075, 0.08, true);
}
}
@ -203,7 +192,8 @@ public class M18SmokeGrenadeEntity extends ThrowableItemProjectile implements Ge
}
@Override
protected float getGravity() {
protected double getDefaultGravity() {
return 0.07F;
}
}

View file

@ -1,5 +1,6 @@
package com.atsuishio.superbwarfare.entity.projectile;
import com.atsuishio.superbwarfare.client.particle.CustomSmokeOption;
import com.atsuishio.superbwarfare.init.ModEntities;
import com.atsuishio.superbwarfare.init.ModParticleTypes;
import com.atsuishio.superbwarfare.init.ModSounds;
@ -11,13 +12,16 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MoverType;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
public class SmokeDecoyEntity extends Entity {
public boolean releaseSmoke = true;
public SmokeDecoyEntity(EntityType<? extends SmokeDecoyEntity> type, Level world) {
super(type, world);
}
@ -31,15 +35,6 @@ public class SmokeDecoyEntity extends Entity {
super(ModEntities.SMOKE_DECOY.get(), level);
}
public SmokeDecoyEntity(PlayMessages.SpawnEntity spawnEntity, Level level) {
this(ModEntities.SMOKE_DECOY.get(), level, true);
}
@Override
public @NotNull Packet<ClientGamePacketListener> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
public int life = 400;
public int igniteTime = 4;
@ -70,7 +65,7 @@ public class SmokeDecoyEntity extends Entity {
if (tickCount == this.igniteTime) {
if (releaseSmoke) {
if (this.level() instanceof ServerLevel serverLevel) {
ParticleTool.sendParticle(serverLevel, ModParticleTypes.CUSTOM_SMOKE.get(), this.xo, this.yo, this.zo,
ParticleTool.sendParticle(serverLevel, new CustomSmokeOption(1, 1, 1), this.xo, this.yo, this.zo,
50, 0, 0, 0, 0.07, true);
ParticleTool.sendParticle(serverLevel, ParticleTypes.LARGE_SMOKE, this.xo, this.yo, this.zo, 10, 1, 1, 1, 0.1, true);
ParticleTool.sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), this.xo, this.yo, this.zo, 30, 0, 0, 0, 0.2, true);

View file

@ -7,6 +7,7 @@ import com.atsuishio.superbwarfare.entity.projectile.FlareDecoyEntity;
import com.atsuishio.superbwarfare.entity.projectile.SmokeDecoyEntity;
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModEntities;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
@ -294,7 +295,7 @@ public abstract class MobileVehicleEntity extends EnergyVehicleEntity implements
if (decoyInputDown) {
if (this.entityData.get(DECOY_COUNT) > 0 && this.level() instanceof ServerLevel) {
for (int i = 0; i < 8; i++) {
SmokeDecoyEntity smokeDecoyEntity = new SmokeDecoyEntity(this.level());
SmokeDecoyEntity smokeDecoyEntity = new SmokeDecoyEntity(ModEntities.SMOKE_DECOY.get(), this.level());
smokeDecoyEntity.setPos(this.getX(), this.getY() + getBbHeight(), this.getZ());
smokeDecoyEntity.decoyShoot(this, vec3.yRot((-78.75f + 22.5F * i) * Mth.DEG_TO_RAD), 4f, 8);
this.level().addFreshEntity(smokeDecoyEntity);

View file

@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.init;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.client.particle.BulletDecalOption;
import com.atsuishio.superbwarfare.client.particle.CustomSmokeOption;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType;
@ -21,7 +22,7 @@ public class ModParticleTypes {
public static final DeferredHolder<ParticleType<?>, ParticleType<BulletDecalOption>> BULLET_DECAL = REGISTRY.register("bullet_decal",
() -> createOptions(BulletDecalOption.CODEC, BulletDecalOption.STREAM_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));
public static final DeferredHolder<ParticleType<?>, ParticleType<CustomSmokeOption>> CUSTOM_SMOKE = REGISTRY.register("custom_smoke", () -> createOptions(CustomSmokeOption.CODEC, CustomSmokeOption.STREAM_CODEC));
public static <T extends ParticleOptions> ParticleType<T> createOptions(MapCodec<T> codec, StreamCodec<? super RegistryFriendlyByteBuf, T> streamCodec) {
return new ParticleType<>(false) {

View file

@ -17,7 +17,7 @@ public class ModParticles {
event.registerSpriteSet(ModParticleTypes.FIRE_STAR.get(), FireStarParticle::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);
event.registerSpriteSet(ModParticleTypes.CUSTOM_SMOKE.get(), CustomSmokeParticle.Provider::new);
}
}