Fix landing/running particles for cable bus (#372)

Co-authored-by: NotMyWing <winwyv@gmail.com>
This commit is contained in:
Serenibyss
2024-01-15 13:40:01 -06:00
committed by GitHub
parent 503f14f0a6
commit dd3cdfcec5
4 changed files with 152 additions and 1 deletions
@@ -29,8 +29,10 @@ import appeng.block.AEBaseTileBlock;
import appeng.client.UnlistedProperty;
import appeng.client.render.cablebus.CableBusBakedModel;
import appeng.client.render.cablebus.CableBusRenderState;
import appeng.client.render.cablebus.FacadeRenderState;
import appeng.core.AppEng;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketCableBusLandingParticle;
import appeng.core.sync.packets.PacketClick;
import appeng.helpers.AEGlassMaterial;
import appeng.integration.abstraction.IAEFacade;
@@ -70,10 +72,12 @@ import net.minecraft.util.math.RayTraceResult.Type;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -298,6 +302,90 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
return true;
}
@Override
public boolean addRunningEffects(IBlockState state, World world, BlockPos pos, Entity entity) {
if (world.isRemote) {
addRunningParticle(world, pos, entity);
}
return true;
}
@SideOnly(Side.CLIENT)
private void addRunningParticle(World world, BlockPos pos, Entity entity) {
final ICableBusContainer cb = this.cb(world, pos);
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(this.getDefaultState());
if (!(model instanceof CableBusBakedModel cableBusModel)) {
return;
}
final CableBusRenderState renderState = cb.getRenderState();
final TextureAtlasSprite texture = getSpriteForParticle(renderState, cableBusModel);
if (texture != null) {
final double d0 = entity.posX + (world.rand.nextFloat() - 0.5f) * entity.width;
final double d1 = entity.getEntityBoundingBox().minY + 0.1f;
final double d2 = entity.posZ + (world.rand.nextFloat() - 0.5f) * entity.width;
final ParticleDigging particle = new DestroyFX(world, d0, d1, d2, -entity.motionX * 4.0f, 1.5f, -entity.motionZ * 4.0f, this.getDefaultState()).setBlockPos(pos);
particle.setParticleTexture(texture);
Minecraft.getMinecraft().effectRenderer.addEffect(particle);
}
}
@Override
public boolean addLandingEffects(IBlockState state, WorldServer world, BlockPos pos, IBlockState iblockstate, EntityLivingBase entity, int numberOfParticles) {
// for reasons only notch can explain, this method is only called on the server, so we have to sync
// a packet to all tracking players for landing particle effects
if (!world.isRemote) {
final PacketCableBusLandingParticle packet = new PacketCableBusLandingParticle(pos, entity, numberOfParticles);
final NetworkRegistry.TargetPoint point = new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 32);
NetworkHandler.instance().sendToAllTracking(packet, point);
}
return true;
}
@SideOnly(Side.CLIENT)
public void addLandingParticle(BlockPos pos, double entityX, double entityY, double entityZ, int numberOfParticles) {
final World world = Minecraft.getMinecraft().world;
final ICableBusContainer cb = this.cb(world, pos);
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(this.getDefaultState());
if (!(model instanceof CableBusBakedModel cableBusModel)) {
return;
}
final TextureAtlasSprite texture = getSpriteForParticle(cb.getRenderState(), cableBusModel);
if (texture != null) {
final Vec3d startVec = new Vec3d(entityX, entityY, entityZ);
final Vec3d endVec = startVec.add(0.0f, -4.0f, 0.0f);
RayTraceResult result = world.rayTraceBlocks(startVec, endVec, true, false, true);
final double speed = 0.15f;
if (result != null && result.typeOfHit == Type.BLOCK && numberOfParticles != 0) {
for (int i = 0; i < numberOfParticles; i++) {
final double d0 = world.rand.nextGaussian() * speed;
final double d1 = world.rand.nextGaussian() * speed;
final double d2 = world.rand.nextGaussian() * speed;
final ParticleDigging particle = new DestroyFX(world, entityX, entityY, entityZ, d0, d1, d2, this.getDefaultState()).setBlockPos(pos);
particle.setParticleTexture(texture);
Minecraft.getMinecraft().effectRenderer.addEffect(particle);
}
}
}
}
@SideOnly(Side.CLIENT)
private TextureAtlasSprite getSpriteForParticle(CableBusRenderState renderState, CableBusBakedModel cableBusModel) {
final FacadeRenderState frs = renderState.getFacades().get(EnumFacing.UP);
if (frs != null) {
final IBlockState state = frs.getSourceBlock();
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(state);
return model.getParticleTexture();
}
return Platform.pickRandom(cableBusModel.getParticleTextures(renderState));
}
@Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) {
if (Platform.isServer()) {
@@ -88,7 +88,11 @@ public class AppEngPacketHandlerBase {
PACKET_CRAFTING_TOAST(PacketCraftingToast.class),
PACKET_COLOR_APPLICATOR_SELECT_COLOR(PacketColorApplicatorSelectColor.class);
PACKET_COLOR_APPLICATOR_SELECT_COLOR(PacketColorApplicatorSelectColor.class),
PACKET_CABLE_BUS_LANDING_PARTICLE(PacketCableBusLandingParticle.class),
;
private final Class<? extends AppEngPacket> packetClass;
@@ -112,6 +112,10 @@ public class NetworkHandler {
this.ec.sendToAllAround(message.getProxy(), point);
}
public void sendToAllTracking(final AppEngPacket message, final NetworkRegistry.TargetPoint point) {
this.ec.sendToAllTracking(message.getProxy(), point);
}
public void sendToDimension(final AppEngPacket message, final int dimensionId) {
this.ec.sendToDimension(message.getProxy(), dimensionId);
}
@@ -0,0 +1,55 @@
package appeng.core.sync.packets;
import appeng.block.networking.BlockCableBus;
import appeng.core.sync.AppEngPacket;
import appeng.core.sync.network.INetworkInfo;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class PacketCableBusLandingParticle extends AppEngPacket {
private BlockPos pos;
private double entityX;
private double entityY;
private double entityZ;
private int numberOfParticles;
public PacketCableBusLandingParticle(final ByteBuf stream) {
this.pos = BlockPos.fromLong(stream.readLong());
this.entityX = stream.readDouble();
this.entityY = stream.readDouble();
this.entityZ = stream.readDouble();
this.numberOfParticles = stream.readInt();
}
public PacketCableBusLandingParticle(final BlockPos pos, final Entity entity, final int numberOfParticles) {
final ByteBuf data = Unpooled.buffer();
data.writeInt(this.getPacketID());
data.writeLong(pos.toLong());
data.writeDouble(entity.posX);
data.writeDouble(entity.posY);
data.writeDouble(entity.posZ);
data.writeInt(numberOfParticles);
this.configureWrite(data);
}
@Override
@SideOnly(Side.CLIENT)
public void clientPacketData(INetworkInfo network, AppEngPacket packet, EntityPlayer player) {
final World world = Minecraft.getMinecraft().world;
final IBlockState state = world.getBlockState(pos);
if (state.getBlock() instanceof BlockCableBus cb) {
cb.addLandingParticle(pos, entityX, entityY, entityZ, numberOfParticles);
}
}
}