Рендер кастомного эффекта

Версия Minecraft
1.15.2
205
12
103
Ахой. Проблема заключается в следующем: накладываю на моба эффект, который должен наносить урон и спавнить вокруг него специальные партиклы - урон наносится, а партиклов нет. Накладываю на себя при помощи команды - всё работает. Подозреваю что косяк где-то в области применения !world.isRemote, но где именно - понять не могу.

Наложение эффекта:

Java:
    @Override
    protected void onImpact(RayTraceResult rayTraceResult) {
        if (!world.isRemote) {
            switch (rayTraceResult.getType()) {
                case BLOCK:
                    BlockRayTraceResult blockRayTraceResult = (BlockRayTraceResult) rayTraceResult;
                    if (world.getBlockState(blockRayTraceResult.getPos()).isSolid()) {
                        if (dataManager.get(IS_RETURNING) == 0) {
                            world.playSound((PlayerEntity) null, this.getPosX(), this.getPosY(), this.getPosZ(), ModSounds.DIG, SoundCategory.NEUTRAL, 1.0F, 1.0F / (new Random().nextFloat() * 0.4F + 0.8F));
                            Vec3d currentMovementVec = new Vec3d(getMotion().x, getMotion().y, getMotion().z);
                            Direction dir = blockRayTraceResult.getFace();
                            Vec3d normalVector = new Vec3d(-2 * dir.getXOffset(), -2 * dir.getYOffset(), -2 * dir.getZOffset()).normalize();
                            Vec3d movementVec = normalVector.mul(
                                    -0.5 * currentMovementVec.dotProduct(normalVector),
                                    -0.5 * currentMovementVec.dotProduct(normalVector),
                                    -0.5 * currentMovementVec.dotProduct(normalVector))
                                    .add(currentMovementVec);
                            setMotion(movementVec);
                            this.setIsReturning();
                        }
                    }
                    break;
                case ENTITY:
                    EntityRayTraceResult entityRayTraceResult = (EntityRayTraceResult) rayTraceResult;
                    if (entityRayTraceResult.getEntity() instanceof LivingEntity && entityRayTraceResult.getEntity() != getThrower()) {
                        LivingEntity thrower = getThrower();
                        entityRayTraceResult.getEntity().attackEntityFrom(thrower != null
                                ? thrower instanceof PlayerEntity
                                ? DamageSource.causeThrownDamage(this, thrower)
                                : DamageSource.causeMobDamage(thrower)
                                : DamageSource.GENERIC, 8);
                        if (entityRayTraceResult.getEntity() != (LivingEntity) thrower) {
                            if (new Random().nextInt(3) == 0) {
                                ((LivingEntity) entityRayTraceResult.getEntity()).addPotionEffect(new EffectInstance(ModEffects.Effects.on_fire, 60));
                            }
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }

Сам эффект:

Java:
public class OnFireEffect extends TerraEffect {
    public OnFireEffect(String name, EffectType typeIn, int liquidColorIn) {
        super(name, typeIn, liquidColorIn);
    }

    @Override
    public boolean isReady(int duration, int amplifier) {
        return true;
    }

    @Override
    public void performEffect(LivingEntity entityLivingBaseIn, int amplifier) {
        entityLivingBaseIn.attackEntityFrom(DamageSource.GENERIC, 4 + new Random().nextInt(2));

            TintParticleData tintParticleData = new TintParticleData(new Color(
                    1.0F,
                    0.7F * new Random().nextFloat(),
                    0.1F * new Random().nextFloat()),
                    0.2F * new Random().nextFloat(),
                    15 + new Random().nextInt(10));
            for (int i = 0; i < 7; i++)
                entityLivingBaseIn.world.addParticle(tintParticleData,
                        entityLivingBaseIn.getPosX() + 0.4F * (Math.random() - 0.5F),
                        entityLivingBaseIn.getPosY() + 1.5F * (Math.random() + 0.25F),
                        entityLivingBaseIn.getPosZ() + 0.4F * (Math.random() - 0.5F),
                        0.15F * (Math.random() - 0.5F),
                        0.15F * (Math.random() - 0.5F),
                        0.15F * (Math.random() - 0.5F));
    }
}

Также не могу понять как убрать из эффекта рендер ванильных партиклов зелья, мне они вообще не нужны.
 

tox1cozZ

aka Agravaine
8,456
598
2,893
Нужно пакет отправлять всем игрокам в радиусе и на клиенте уже спавнить частицы.

как убрать из эффекта рендер ванильных партиклов зелья
В конструкторе EffectInstance должен быть булев, вроде.
 
7,099
324
1,510
Если частицы ванильные, то в классе WorldServer есть вариант addParticle, который отправляет пакеты игрокам рядом
 
205
12
103
Если частицы ванильные
Свои.

Вроде ж им партикл и создаю. Беру мир энтити и вызываю там addParticle.

Нужно пакет отправлять всем игрокам в радиусе и на клиенте уже спавнить частицы.
Ванильного пакета на этот случай нет?
 
7,099
324
1,510
У мя под рукой только воркспейс 1.14.4, там в серверном мире есть метод, отправляющий пакет
В 1.15 класс называется также
1586621651659.png
Заголовок метода, чтобы легче найти:
public <T extends IParticleData> int spawnParticle(T type, double posX, double posY, double posZ, int particleCount, double xOffset, double yOffset, double zOffset, double speed)
 
205
12
103
Попробовал использовать этот метод. Говорит, мол, я там пытаюсь клиентский мир кастовать к серверному.
Код:
Java:
    @Override
    public void performEffect(LivingEntity entityLivingBaseIn, int amplifier) {
        entityLivingBaseIn.attackEntityFrom(DamageSource.GENERIC, 4 + new Random().nextInt(2));

        TintParticleData tintParticleData = new TintParticleData(new Color(
                1.0F,
                0.7F * new Random().nextFloat(),
                0.1F * new Random().nextFloat()),
                0.2F * new Random().nextFloat(),
                15 + new Random().nextInt(10));
        for (int i = 0; i < 7; i++)
            ((ServerWorld)entityLivingBaseIn.world).spawnParticle(tintParticleData,
                    entityLivingBaseIn.getPosX() + 0.4F * (Math.random() - 0.5F),
                    entityLivingBaseIn.getPosY() + 1.5F * (Math.random() + 0.25F),
                    entityLivingBaseIn.getPosZ() + 0.4F * (Math.random() - 0.5F),
                    10,
                    entityLivingBaseIn.getPosX() + 0.4F * (Math.random() - 0.5F),
                    entityLivingBaseIn.getPosY() + 1.5F * (Math.random() + 0.25F),
                    entityLivingBaseIn.getPosZ() + 0.4F * (Math.random() - 0.5F),
                    10);
                    //Не смотрите на параметры оффсета, я пока их вообще не трогал и просто скопировал с позиции
    }

Ошибка:

Java:
java.lang.ClassCastException: net.minecraft.client.world.ClientWorld cannot be cast to net.minecraft.world.server.ServerWorld
    at com.sskirillss.terracraft.effects.OnFireEffect.performEffect(OnFireEffect.java:34) ~[main/:?] {re:classloading}
    at net.minecraft.potion.EffectInstance.performEffect(EffectInstance.java:173) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,xf:fml:forge:potion}
    at net.minecraft.potion.EffectInstance.tick(EffectInstance.java:149) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,xf:fml:forge:potion}
    at net.minecraft.entity.LivingEntity.updatePotionEffects(LivingEntity.java:615) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading}
    at net.minecraft.entity.LivingEntity.baseTick(LivingEntity.java:380) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading}
    at net.minecraft.entity.Entity.tick(Entity.java:396) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.entity.LivingEntity.tick(LivingEntity.java:2184) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading}
    at net.minecraft.entity.player.PlayerEntity.tick(PlayerEntity.java:237) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.client.entity.player.ClientPlayerEntity.tick(ClientPlayerEntity.java:220) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A}
    at net.minecraft.client.world.ClientWorld.updateEntity(ClientWorld.java:182) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A}
    at net.minecraft.world.World.guardEntityTick(World.java:586) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.client.world.ClientWorld.tickEntities(ClientWorld.java:152) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A}
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:1457) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:942) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
    at net.minecraft.client.Minecraft.run(Minecraft.java:559) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
    at net.minecraft.client.main.Main.main(Main.java:177) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A}
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_242] {}
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_242] {}
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_242] {}
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_242] {}
    at net.minecraftforge.userdev.FMLUserdevClientLaunchProvider.lambda$launchService$0(FMLUserdevClientLaunchProvider.java:55) ~[forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {}
    at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37) [modlauncher-5.0.0-milestone.4.jar:?] {}
    at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:54) [modlauncher-5.0.0-milestone.4.jar:?] {}
    at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:72) [modlauncher-5.0.0-milestone.4.jar:?] {}
    at cpw.mods.modlauncher.Launcher.run(Launcher.java:81) [modlauncher-5.0.0-milestone.4.jar:?] {}
    at cpw.mods.modlauncher.Launcher.main(Launcher.java:65) [modlauncher-5.0.0-milestone.4.jar:?] {}
    at net.minecraftforge.userdev.LaunchTesting.main(LaunchTesting.java:102) [forge-1.15.2-31.1.30_mapped_snapshot_20200229-1.15.1-recomp.jar:?] {}

Подробности: Когда накладываю эффект на энтить - ничего не происходит (не крашит и партиклы не спавнятся), накладываю на себя - крашит.
 
Сверху