Slime fixes

This commit is contained in:
paulevsGitch 2020-10-05 23:17:51 +03:00
parent cd0d5582a8
commit 3bc28083f0
8 changed files with 142 additions and 6 deletions

View file

@ -11,7 +11,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.StructureWorldAccess;
public abstract class BlockPlantWithAge extends BlockPlant { public abstract class BlockPlantWithAge extends BlockPlant {
public static final IntProperty AGE = IntProperty.of("age", 0, 4); public static final IntProperty AGE = IntProperty.of("age", 0, 3);
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) { protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {

View file

@ -1,5 +1,9 @@
package ru.betterend.entity; 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.EntityData;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
@ -13,13 +17,19 @@ import net.minecraft.entity.mob.SlimeEntity;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleTypes; 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.LocalDifficulty;
import net.minecraft.world.ServerWorldAccess; import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import ru.betterend.registry.BiomeRegistry; import ru.betterend.registry.BiomeRegistry;
import ru.betterend.util.ISlime;
public class EntityEndSlime extends SlimeEntity { public class EntityEndSlime extends SlimeEntity {
private static final TrackedData<Boolean> MOSSY = DataTracker.registerData(EntityEndSlime.class, TrackedDataHandlerRegistry.BOOLEAN); 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) { public EntityEndSlime(EntityType<EntityEndSlime> entityType, World world) {
super(entityType, world); super(entityType, world);
@ -36,7 +46,7 @@ public class EntityEndSlime extends SlimeEntity {
@Override @Override
public EntityData initialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, EntityData entityData, CompoundTag entityTag) { public EntityData initialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, EntityData entityData, CompoundTag entityTag) {
EntityData data = super.initialize(world, difficulty, spawnReason, entityData, entityTag); EntityData data = super.initialize(world, difficulty, spawnReason, entityData, entityTag);
if (world.getRandom().nextBoolean() && BiomeRegistry.getFromBiome(world.getBiome(getBlockPos())) == BiomeRegistry.FOGGY_MUSHROOMLAND) { if (BiomeRegistry.getFromBiome(world.getBiome(getBlockPos())) == BiomeRegistry.FOGGY_MUSHROOMLAND) {
this.setMossy(true); this.setMossy(true);
} }
return data; return data;
@ -53,6 +63,37 @@ public class EntityEndSlime extends SlimeEntity {
return ParticleTypes.PORTAL; 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.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) { protected void setMossy(boolean mossy) {
this.dataTracker.set(MOSSY, mossy); this.dataTracker.set(MOSSY, mossy);
} }
@ -60,4 +101,30 @@ public class EntityEndSlime extends SlimeEntity {
public boolean isMossy() { public boolean isMossy() {
return this.dataTracker.get(MOSSY); 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;
}
} }

View file

@ -0,0 +1,18 @@
package ru.betterend.mixin.common;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.entity.mob.SlimeEntity;
import ru.betterend.util.ISlime;
@Mixin(SlimeEntity.class)
public class SlimeEntityMixin implements ISlime {
@Shadow
protected void setSize(int size, boolean heal) {}
@Override
public void setSlimeSize(int size, boolean heal) {
setSize(size, heal);
}
}

View file

@ -14,12 +14,15 @@ import ru.betterend.BetterEnd;
import ru.betterend.entity.EntityDragonfly; import ru.betterend.entity.EntityDragonfly;
import ru.betterend.entity.EntityEndSlime; import ru.betterend.entity.EntityEndSlime;
import ru.betterend.util.MHelper; import ru.betterend.util.MHelper;
import ru.betterend.util.SpawnHelper;
public class EntityRegistry { public class EntityRegistry {
public static final EntityType<EntityDragonfly> DRAGONFLY = register("dragonfly", SpawnGroup.AMBIENT, 0.6F, 0.5F, EntityDragonfly::new, EntityDragonfly.createMobAttributes(), MHelper.color(32, 42, 176), MHelper.color(115, 225, 249)); public static final EntityType<EntityDragonfly> DRAGONFLY = register("dragonfly", SpawnGroup.AMBIENT, 0.6F, 0.5F, EntityDragonfly::new, EntityDragonfly.createMobAttributes(), MHelper.color(32, 42, 176), MHelper.color(115, 225, 249));
public static final EntityType<EntityEndSlime> END_SLIME = register("end_slime", SpawnGroup.AMBIENT, 0.6F, 0.5F, EntityEndSlime::new, EntityEndSlime.createMobAttributes(), MHelper.color(28, 28, 28), MHelper.color(99, 11, 99)); public static final EntityType<EntityEndSlime> END_SLIME = register("end_slime", SpawnGroup.MONSTER, 0.6F, 0.5F, EntityEndSlime::new, EntityEndSlime.createMobAttributes(), MHelper.color(28, 28, 28), MHelper.color(99, 11, 99));
public static void register() {} public static void register() {
SpawnHelper.restrictionLand(END_SLIME, EntityEndSlime::canSpawn);
}
protected static <T extends Entity> EntityType<T> register(String name, SpawnGroup group, float width, float height, EntityFactory<T> entity) { protected static <T extends Entity> EntityType<T> register(String name, SpawnGroup group, float width, float height, EntityFactory<T> entity) {
EntityType<T> type = Registry.register(Registry.ENTITY_TYPE, BetterEnd.makeID(name), FabricEntityTypeBuilder.<T>create(group, entity).dimensions(EntityDimensions.fixed(width, height)).build()); EntityType<T> type = Registry.register(Registry.ENTITY_TYPE, BetterEnd.makeID(name), FabricEntityTypeBuilder.<T>create(group, entity).dimensions(EntityDimensions.fixed(width, height)).build());

View file

@ -0,0 +1,5 @@
package ru.betterend.util;
public interface ISlime {
public void setSlimeSize(int size, boolean heal);
}

View file

@ -0,0 +1,39 @@
package ru.betterend.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnRestriction;
import net.minecraft.entity.SpawnRestriction.Location;
import net.minecraft.entity.SpawnRestriction.SpawnPredicate;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.world.Heightmap.Type;
import ru.betterend.BetterEnd;
public class SpawnHelper {
private static Method regRestriction;
public static <T extends MobEntity> void restriction(EntityType<T> entity, Location location, Type heughtmapType, SpawnPredicate<T> predicate) {
try {
regRestriction.invoke(null, entity, location, heughtmapType, predicate);
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
BetterEnd.LOGGER.error(e.getMessage());
}
}
public static <T extends MobEntity> void restrictionLand(EntityType<T> entity, SpawnPredicate<T> predicate) {
restriction(entity, Location.ON_GROUND, Type.MOTION_BLOCKING, predicate);
}
static {
try {
regRestriction = SpawnRestriction.class.getDeclaredMethod("register", EntityType.class, Location.class, Type.class, SpawnPredicate.class);
regRestriction.setAccessible(true);
}
catch (NoSuchMethodException | SecurityException e) {
BetterEnd.LOGGER.error(e.getMessage());
}
}
}

View file

@ -1,5 +1,6 @@
package ru.betterend.world.biome; package ru.betterend.world.biome;
import net.minecraft.entity.EntityType;
import ru.betterend.registry.BlockRegistry; import ru.betterend.registry.BlockRegistry;
import ru.betterend.registry.EntityRegistry; import ru.betterend.registry.EntityRegistry;
import ru.betterend.registry.FeatureRegistry; import ru.betterend.registry.FeatureRegistry;
@ -23,6 +24,8 @@ public class BiomeFoggyMushroomland extends EndBiome {
.addFeature(FeatureRegistry.BLUE_VINE) .addFeature(FeatureRegistry.BLUE_VINE)
.addFeature(FeatureRegistry.UMBRELLA_MOSS) .addFeature(FeatureRegistry.UMBRELLA_MOSS)
.addFeature(FeatureRegistry.CREEPING_MOSS) .addFeature(FeatureRegistry.CREEPING_MOSS)
.addMobSpawn(EntityRegistry.DRAGONFLY, 80, 2, 4)); .addMobSpawn(EntityRegistry.DRAGONFLY, 80, 2, 5)
.addMobSpawn(EntityRegistry.END_SLIME, 10, 1, 2)
.addMobSpawn(EntityType.ENDERMAN, 10, 1, 2));
} }
} }

View file

@ -13,7 +13,8 @@
"AnvilScreenHandlerMixin", "AnvilScreenHandlerMixin",
"AbstractBlockMixin", "AbstractBlockMixin",
"LivingEntityMixin", "LivingEntityMixin",
"BiomeMixin" "BiomeMixin",
"SlimeEntityMixin"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1