Привет всем! Пытаюсь добавить магический посох, который бы выстреливал снарядом, который в свою очередь касаясь моба или твердой поверхности вызывал бы эффект снежной метели из партиклов с периодическим аое уроном.
Т.к статьи по этому поводу в учебнике не нашел, колхозил это дело с чатом гпт.
Проблема следующая: снаряд вылетает из посоха, в полете за ним создаются партиклы (пока все по плану), снаряд об что то ударяется. Далее спавнится область с переодическим уроном, но вот партиклы очерчивающие область уже спавниться не хотят.
Я создал событие в котором при прыжке игрока должен вызваться этот же метод (отвечающий за спавн цилиндра из партиклов) и там все работает.
Прилагаю код:
package com.vinelles.testmod.entities;
import com.vinelles.testmod.particle_effects.ParticleCircle;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World;
import java.util.List;
public class EntityBlizzard extends Entity {
private int duration = 100; // Продолжительность метели в тиках (5 секунд)
private int tickCounter = 0;
private double radius = 5.0;
public EntityBlizzard(World worldIn) {
super(worldIn);
this.setSize(1.0F, 1.0F);
}
public EntityBlizzard(World worldIn, double x, double y, double z) {
this(worldIn);
this.setPosition(x, y, z);
}
@Override
protected void entityInit() {
}
@Override
protected void readEntityFromNBT(NBTTagCompound compound) {
}
@Override
protected void writeEntityToNBT(NBTTagCompound compound) {
}
@Override
public void onUpdate() {
super.onUpdate();
tickCounter++;
if (world.isRemote) {
int layers = 5; // Количество слоев
int particleCount = 20; // Количество частиц в каждом слое
// Создание цилиндра из частиц
ParticleCircle.createCylinder(world, this.posX, this.posY, this.posZ, radius, layers, particleCount, EnumParticleTypes.EXPLOSION_NORMAL);
}
// Нанесение урона всем сущностям в радиусе каждую секунду
if (!this.world.isRemote && tickCounter % 20 == 0) { // Каждые 20 тиков (1 секунда)
List<EntityLivingBase> nearbyEntities = this.world.getEntitiesWithinAABB(EntityLivingBase.class, new AxisAlignedBB(
posX - radius, posY - 1, posZ - radius, posX + radius, posY + 1, posZ + radius));
for (EntityLivingBase entity : nearbyEntities) {
entity.attackEntityFrom(DamageSource.MAGIC, 2.0F); // Урон магией
}
}
// Если метель длится дольше 5 секунд, отключаем её
if (!this.world.isRemote && tickCounter >= duration) {
this.setDead();
}
}
}
Класс ParticleCircle:
package com.vinelles.testmod.particle_effects;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.world.World;
public class ParticleCircle {
public static void createCylinder(World world, double centerX, double centerY, double centerZ, double radius, int layers, int particleCount, EnumParticleTypes particleType) {
for (int layer = 0; layer < layers; layer++) {
double yOffset = layer * 0.5; // Высота каждого слоя
for (int i = 0; i < particleCount; i++) {
double angle = 2 * Math.PI * i / particleCount;
double xOffset = Math.cos(angle) * radius;
double zOffset = Math.sin(angle) * radius;
world.spawnParticle(particleType, centerX + xOffset, centerY + yOffset, centerZ + zOffset, 0.0, 0.0, 0.0);
}
}
}
}
Там где ParticleCircle нормально функционирует:
@SubscribeEvent
public void onPlayerJump(LivingEvent.LivingJumpEvent event) {
if (event.getEntityLiving() instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) event.getEntityLiving();
World world = player.world;
if (world.isRemote) {
double radius = 2.0; // Радиус цилиндра
int layers = 5; // Количество слоев
int particleCount = 20; // Количество частиц в каждом слое
// Создание цилиндра из частиц
ParticleCircle.createCylinder(world, player.posX, player.posY, player.posZ, radius, layers, particleCount, EnumParticleTypes.EXPLOSION_NORMAL);
}
}
}
Т.к статьи по этому поводу в учебнике не нашел, колхозил это дело с чатом гпт.
Проблема следующая: снаряд вылетает из посоха, в полете за ним создаются партиклы (пока все по плану), снаряд об что то ударяется. Далее спавнится область с переодическим уроном, но вот партиклы очерчивающие область уже спавниться не хотят.
Я создал событие в котором при прыжке игрока должен вызваться этот же метод (отвечающий за спавн цилиндра из партиклов) и там все работает.
Прилагаю код:
package com.vinelles.testmod.entities;
import com.vinelles.testmod.particle_effects.ParticleCircle;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World;
import java.util.List;
public class EntityBlizzard extends Entity {
private int duration = 100; // Продолжительность метели в тиках (5 секунд)
private int tickCounter = 0;
private double radius = 5.0;
public EntityBlizzard(World worldIn) {
super(worldIn);
this.setSize(1.0F, 1.0F);
}
public EntityBlizzard(World worldIn, double x, double y, double z) {
this(worldIn);
this.setPosition(x, y, z);
}
@Override
protected void entityInit() {
}
@Override
protected void readEntityFromNBT(NBTTagCompound compound) {
}
@Override
protected void writeEntityToNBT(NBTTagCompound compound) {
}
@Override
public void onUpdate() {
super.onUpdate();
tickCounter++;
if (world.isRemote) {
int layers = 5; // Количество слоев
int particleCount = 20; // Количество частиц в каждом слое
// Создание цилиндра из частиц
ParticleCircle.createCylinder(world, this.posX, this.posY, this.posZ, radius, layers, particleCount, EnumParticleTypes.EXPLOSION_NORMAL);
}
// Нанесение урона всем сущностям в радиусе каждую секунду
if (!this.world.isRemote && tickCounter % 20 == 0) { // Каждые 20 тиков (1 секунда)
List<EntityLivingBase> nearbyEntities = this.world.getEntitiesWithinAABB(EntityLivingBase.class, new AxisAlignedBB(
posX - radius, posY - 1, posZ - radius, posX + radius, posY + 1, posZ + radius));
for (EntityLivingBase entity : nearbyEntities) {
entity.attackEntityFrom(DamageSource.MAGIC, 2.0F); // Урон магией
}
}
// Если метель длится дольше 5 секунд, отключаем её
if (!this.world.isRemote && tickCounter >= duration) {
this.setDead();
}
}
}
Класс ParticleCircle:
package com.vinelles.testmod.particle_effects;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.world.World;
public class ParticleCircle {
public static void createCylinder(World world, double centerX, double centerY, double centerZ, double radius, int layers, int particleCount, EnumParticleTypes particleType) {
for (int layer = 0; layer < layers; layer++) {
double yOffset = layer * 0.5; // Высота каждого слоя
for (int i = 0; i < particleCount; i++) {
double angle = 2 * Math.PI * i / particleCount;
double xOffset = Math.cos(angle) * radius;
double zOffset = Math.sin(angle) * radius;
world.spawnParticle(particleType, centerX + xOffset, centerY + yOffset, centerZ + zOffset, 0.0, 0.0, 0.0);
}
}
}
}
Там где ParticleCircle нормально функционирует:
@SubscribeEvent
public void onPlayerJump(LivingEvent.LivingJumpEvent event) {
if (event.getEntityLiving() instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) event.getEntityLiving();
World world = player.world;
if (world.isRemote) {
double radius = 2.0; // Радиус цилиндра
int layers = 5; // Количество слоев
int particleCount = 20; // Количество частиц в каждом слое
// Создание цилиндра из частиц
ParticleCircle.createCylinder(world, player.posX, player.posY, player.posZ, radius, layers, particleCount, EnumParticleTypes.EXPLOSION_NORMAL);
}
}
}
