From 3bc28083f083a9f3de7b784e7a80cb6d742d4370 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 5 Oct 2020 23:17:51 +0300 Subject: [PATCH] Slime fixes --- .../blocks/basis/BlockPlantWithAge.java | 2 +- .../ru/betterend/entity/EntityEndSlime.java | 69 ++++++++++++++++++- .../mixin/common/SlimeEntityMixin.java | 18 +++++ .../ru/betterend/registry/EntityRegistry.java | 7 +- src/main/java/ru/betterend/util/ISlime.java | 5 ++ .../java/ru/betterend/util/SpawnHelper.java | 39 +++++++++++ .../world/biome/BiomeFoggyMushroomland.java | 5 +- .../resources/betterend.mixins.common.json | 3 +- 8 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 src/main/java/ru/betterend/mixin/common/SlimeEntityMixin.java create mode 100644 src/main/java/ru/betterend/util/ISlime.java create mode 100644 src/main/java/ru/betterend/util/SpawnHelper.java diff --git a/src/main/java/ru/betterend/blocks/basis/BlockPlantWithAge.java b/src/main/java/ru/betterend/blocks/basis/BlockPlantWithAge.java index 7aca0f55..e12eea72 100644 --- a/src/main/java/ru/betterend/blocks/basis/BlockPlantWithAge.java +++ b/src/main/java/ru/betterend/blocks/basis/BlockPlantWithAge.java @@ -11,7 +11,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.StructureWorldAccess; 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 protected void appendProperties(StateManager.Builder stateManager) { diff --git a/src/main/java/ru/betterend/entity/EntityEndSlime.java b/src/main/java/ru/betterend/entity/EntityEndSlime.java index a5601c97..0708b42f 100644 --- a/src/main/java/ru/betterend/entity/EntityEndSlime.java +++ b/src/main/java/ru/betterend/entity/EntityEndSlime.java @@ -1,5 +1,9 @@ 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; @@ -13,13 +17,19 @@ 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 MOSSY = DataTracker.registerData(EntityEndSlime.class, TrackedDataHandlerRegistry.BOOLEAN); + private static final Mutable POS = new Mutable(); public EntityEndSlime(EntityType entityType, World world) { super(entityType, world); @@ -36,7 +46,7 @@ public class EntityEndSlime extends SlimeEntity { @Override public EntityData initialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, EntityData entityData, CompoundTag 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); } return data; @@ -53,6 +63,37 @@ public class EntityEndSlime extends SlimeEntity { 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) { this.dataTracker.set(MOSSY, mossy); } @@ -60,4 +101,30 @@ public class EntityEndSlime extends SlimeEntity { public boolean isMossy() { return this.dataTracker.get(MOSSY); } + + public static boolean canSpawn(EntityType 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 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; + } } diff --git a/src/main/java/ru/betterend/mixin/common/SlimeEntityMixin.java b/src/main/java/ru/betterend/mixin/common/SlimeEntityMixin.java new file mode 100644 index 00000000..977c2e43 --- /dev/null +++ b/src/main/java/ru/betterend/mixin/common/SlimeEntityMixin.java @@ -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); + } +} diff --git a/src/main/java/ru/betterend/registry/EntityRegistry.java b/src/main/java/ru/betterend/registry/EntityRegistry.java index b5d173b8..64f93d5b 100644 --- a/src/main/java/ru/betterend/registry/EntityRegistry.java +++ b/src/main/java/ru/betterend/registry/EntityRegistry.java @@ -14,12 +14,15 @@ import ru.betterend.BetterEnd; import ru.betterend.entity.EntityDragonfly; import ru.betterend.entity.EntityEndSlime; import ru.betterend.util.MHelper; +import ru.betterend.util.SpawnHelper; public class EntityRegistry { public static final EntityType 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 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 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 EntityType register(String name, SpawnGroup group, float width, float height, EntityFactory entity) { EntityType type = Registry.register(Registry.ENTITY_TYPE, BetterEnd.makeID(name), FabricEntityTypeBuilder.create(group, entity).dimensions(EntityDimensions.fixed(width, height)).build()); diff --git a/src/main/java/ru/betterend/util/ISlime.java b/src/main/java/ru/betterend/util/ISlime.java new file mode 100644 index 00000000..6e029f93 --- /dev/null +++ b/src/main/java/ru/betterend/util/ISlime.java @@ -0,0 +1,5 @@ +package ru.betterend.util; + +public interface ISlime { + public void setSlimeSize(int size, boolean heal); +} diff --git a/src/main/java/ru/betterend/util/SpawnHelper.java b/src/main/java/ru/betterend/util/SpawnHelper.java new file mode 100644 index 00000000..155f8f20 --- /dev/null +++ b/src/main/java/ru/betterend/util/SpawnHelper.java @@ -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 void restriction(EntityType entity, Location location, Type heughtmapType, SpawnPredicate predicate) { + try { + regRestriction.invoke(null, entity, location, heughtmapType, predicate); + } + catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + BetterEnd.LOGGER.error(e.getMessage()); + } + } + + public static void restrictionLand(EntityType entity, SpawnPredicate 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()); + } + } +} diff --git a/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java b/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java index 8a53ed29..4c89abda 100644 --- a/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java +++ b/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java @@ -1,5 +1,6 @@ package ru.betterend.world.biome; +import net.minecraft.entity.EntityType; import ru.betterend.registry.BlockRegistry; import ru.betterend.registry.EntityRegistry; import ru.betterend.registry.FeatureRegistry; @@ -23,6 +24,8 @@ public class BiomeFoggyMushroomland extends EndBiome { .addFeature(FeatureRegistry.BLUE_VINE) .addFeature(FeatureRegistry.UMBRELLA_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)); } } diff --git a/src/main/resources/betterend.mixins.common.json b/src/main/resources/betterend.mixins.common.json index dcca3bc6..19458ad8 100644 --- a/src/main/resources/betterend.mixins.common.json +++ b/src/main/resources/betterend.mixins.common.json @@ -13,7 +13,8 @@ "AnvilScreenHandlerMixin", "AbstractBlockMixin", "LivingEntityMixin", - "BiomeMixin" + "BiomeMixin", + "SlimeEntityMixin" ], "injectors": { "defaultRequire": 1