BetterEnd/src/main/java/ru/betterend/entity/EntityEndSlime.java
2020-10-08 22:55:48 +03:00

132 lines
4.7 KiB
Java

package ru.betterend.entity;
import java.util.List;
import java.util.Random;
import net.minecraft.block.Blocks;
import net.minecraft.entity.EntityData;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.attribute.DefaultAttributeContainer;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.entity.mob.SlimeEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.util.math.Box;
import net.minecraft.world.LocalDifficulty;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.World;
import ru.betterend.registry.BiomeRegistry;
import ru.betterend.util.ISlime;
public class EntityEndSlime extends SlimeEntity {
private static final TrackedData<Boolean> MOSSY = DataTracker.registerData(EntityEndSlime.class, TrackedDataHandlerRegistry.BOOLEAN);
private static final Mutable POS = new Mutable();
public EntityEndSlime(EntityType<EntityEndSlime> entityType, World world) {
super(entityType, world);
}
public static DefaultAttributeContainer.Builder createMobAttributes() {
return LivingEntity.createLivingAttributes()
.add(EntityAttributes.GENERIC_MAX_HEALTH, 1.0D)
.add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 1.0D)
.add(EntityAttributes.GENERIC_FOLLOW_RANGE, 16.0D)
.add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.15D);
}
@Override
public EntityData initialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, EntityData entityData, CompoundTag entityTag) {
EntityData data = super.initialize(world, difficulty, spawnReason, entityData, entityTag);
if (BiomeRegistry.getFromBiome(world.getBiome(getBlockPos())) == BiomeRegistry.FOGGY_MUSHROOMLAND) {
this.setMossy(true);
}
this.calculateDimensions();
return data;
}
@Override
protected void initDataTracker() {
super.initDataTracker();
this.dataTracker.startTracking(MOSSY, false);
}
@Override
protected ParticleEffect getParticles() {
return ParticleTypes.PORTAL;
}
@Override
public void remove() {
int i = this.getSize();
if (!this.world.isClient && i > 1 && this.isDead()) {
Text text = this.getCustomName();
boolean bl = this.isAiDisabled();
float f = (float) i / 4.0F;
int j = i / 2;
int k = 2 + this.random.nextInt(3);
boolean mossy = this.isMossy();
for (int l = 0; l < k; ++l) {
float g = ((float) (l % 2) - 0.5F) * f;
float h = ((float) (l / 2) - 0.5F) * f;
EntityEndSlime slimeEntity = (EntityEndSlime) this.getType().create(this.world);
if (this.isPersistent()) {
slimeEntity.setPersistent();
}
slimeEntity.setMossy(mossy);
slimeEntity.setCustomName(text);
slimeEntity.setAiDisabled(bl);
slimeEntity.setInvulnerable(this.isInvulnerable());
((ISlime) slimeEntity).setSlimeSize(j, true);
slimeEntity.calculateDimensions();
slimeEntity.refreshPositionAndAngles(this.getX() + (double) g, this.getY() + 0.5D, this.getZ() + (double) h, this.random.nextFloat() * 360.0F, 0.0F);
this.world.spawnEntity(slimeEntity);
}
}
this.removed = true;
}
protected void setMossy(boolean mossy) {
this.dataTracker.set(MOSSY, mossy);
}
public boolean isMossy() {
return this.dataTracker.get(MOSSY);
}
public static boolean canSpawn(EntityType<EntityEndSlime> type, ServerWorldAccess world, SpawnReason spawnReason, BlockPos pos, Random random) {
return notManyEntities(world, pos, 32, 3) && isWaterNear(world, pos, 32);
}
private static boolean notManyEntities(ServerWorldAccess world, BlockPos pos, int radius, int maxCount) {
Box box = new Box(pos).expand(radius);
List<EntityEndSlime> list = world.getEntitiesByClass(EntityEndSlime.class, box, (entity) -> { return true; });
return list.size() <= maxCount;
}
private static boolean isWaterNear(ServerWorldAccess world, BlockPos pos, int radius) {
for (int x = pos.getX() - radius; x <= pos.getX() + radius; x++) {
POS.setX(x);
for (int z = pos.getZ() - radius; z <= pos.getZ() + radius; z++) {
POS.setZ(z);
for (int y = pos.getY() - radius; y <= pos.getY() + radius; y++) {
POS.setY(y);
if (world.getBlockState(POS).getBlock() == Blocks.WATER) {
return true;
}
}
}
}
return false;
}
}