diff --git a/src/main/java/ru/betterend/blocks/BlockProperties.java b/src/main/java/ru/betterend/blocks/BlockProperties.java index f1c2f10a..27e13d36 100644 --- a/src/main/java/ru/betterend/blocks/BlockProperties.java +++ b/src/main/java/ru/betterend/blocks/BlockProperties.java @@ -15,6 +15,7 @@ public class BlockProperties { public static final BooleanProperty ACTIVE = BooleanProperty.of("active"); public static final IntProperty ROTATION = IntProperty.of("rotation", 0, 3); public static final BooleanProperty NATURAL = BooleanProperty.of("natural"); + public static final IntProperty FULLNESS = IntProperty.of("fullness", 0, 3); public static enum TripleShape implements StringIdentifiable { TOP("top"), diff --git a/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java b/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java index 6f502ded..f7e8cd62 100644 --- a/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java +++ b/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java @@ -21,6 +21,7 @@ import net.minecraft.sound.SoundEvents; import net.minecraft.state.StateManager; import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.DirectionProperty; +import net.minecraft.state.property.IntProperty; import net.minecraft.state.property.Properties; import net.minecraft.tag.BlockTags; import net.minecraft.util.BlockMirror; @@ -43,17 +44,18 @@ import ru.betterend.util.BlocksHelper; public class SilkMothNestBlock extends BaseBlock implements IRenderTypeable { public static final BooleanProperty ACTIVE = BlockProperties.ACTIVE; public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; + public static final IntProperty FULLNESS = BlockProperties.FULLNESS; private static final VoxelShape TOP = createCuboidShape(6, 0, 6, 10, 16, 10); private static final VoxelShape BOTTOM = createCuboidShape(0, 0, 0, 16, 16, 16); public SilkMothNestBlock() { super(FabricBlockSettings.of(Material.WOOL).hardness(0.5F).resistance(0.1F).sounds(BlockSoundGroup.WOOL).nonOpaque().ticksRandomly()); - this.setDefaultState(getDefaultState().with(ACTIVE, true)); + this.setDefaultState(getDefaultState().with(ACTIVE, true).with(FULLNESS, 0)); } @Override protected void appendProperties(StateManager.Builder stateManager) { - stateManager.add(ACTIVE, FACING); + stateManager.add(ACTIVE, FACING, FULLNESS); } @Override diff --git a/src/main/java/ru/betterend/entity/SilkMothEntity.java b/src/main/java/ru/betterend/entity/SilkMothEntity.java index dc1169de..75085238 100644 --- a/src/main/java/ru/betterend/entity/SilkMothEntity.java +++ b/src/main/java/ru/betterend/entity/SilkMothEntity.java @@ -1,6 +1,7 @@ package ru.betterend.entity; import java.util.EnumSet; +import java.util.Random; import org.jetbrains.annotations.Nullable; @@ -8,6 +9,7 @@ import net.minecraft.block.BlockState; import net.minecraft.entity.EntityType; import net.minecraft.entity.Flutterer; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.SpawnReason; import net.minecraft.entity.ai.TargetFinder; import net.minecraft.entity.ai.control.FlightMoveControl; import net.minecraft.entity.ai.control.LookControl; @@ -33,11 +35,15 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryKey; +import net.minecraft.world.ServerWorldAccess; import net.minecraft.world.World; +import net.minecraft.world.Heightmap.Type; import ru.betterend.BetterEnd; +import ru.betterend.blocks.BlockProperties; import ru.betterend.blocks.SilkMothNestBlock; import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndEntities; +import ru.betterend.util.BlocksHelper; public class SilkMothEntity extends AnimalEntity implements Flutterer { private BlockPos hivePos; @@ -146,6 +152,11 @@ public class SilkMothEntity extends AnimalEntity implements Flutterer { return EndEntities.SILK_MOTH.create(world); } + public static boolean canSpawn(EntityType type, ServerWorldAccess world, SpawnReason spawnReason, BlockPos pos, Random random) { + int y = world.getChunk(pos).sampleHeightmap(Type.WORLD_SURFACE, pos.getX() & 15, pos.getY() & 15); + return y > 0 && pos.getY() >= y; + } + class MothLookControl extends LookControl { MothLookControl(MobEntity entity) { super(entity); @@ -206,7 +217,7 @@ public class SilkMothEntity extends AnimalEntity implements Flutterer { @Override public boolean shouldContinue() { - return SilkMothEntity.this.navigation.isFollowingPath() && world.getBlockState(entrance).isAir(); + return SilkMothEntity.this.navigation.isFollowingPath() && world.getBlockState(entrance).isAir() && world.getBlockState(hivePos).isOf(EndBlocks.SILK_MOTH_NEST); } @Override @@ -216,7 +227,7 @@ public class SilkMothEntity extends AnimalEntity implements Flutterer { SilkMothEntity.this.hivePos = null; } try { - entrance = SilkMothEntity.this.hivePos.offset(state.get(SilkMothNestBlock.FACING)); + SilkMothEntity.this.entrance = SilkMothEntity.this.hivePos.offset(state.get(SilkMothNestBlock.FACING)); SilkMothEntity.this.navigation.startMovingAlong(SilkMothEntity.this.navigation.findPathTo(entrance, 1), 1.0D); } catch (Exception e) {} @@ -229,8 +240,16 @@ public class SilkMothEntity extends AnimalEntity implements Flutterer { double dy = Math.abs(SilkMothEntity.this.entrance.getY() - SilkMothEntity.this.getY()); double dz = Math.abs(SilkMothEntity.this.entrance.getZ() - SilkMothEntity.this.getZ()); if (dx + dy + dz < 1) { - SilkMothEntity.this.world.playSound(null, SilkMothEntity.this.entrance, SoundEvents.BLOCK_BEEHIVE_ENTER, SoundCategory.BLOCKS, 1, 1); - SilkMothEntity.this.remove(); + BlockState state = SilkMothEntity.this.world.getBlockState(hivePos); + if (state.isOf(EndBlocks.SILK_MOTH_NEST)) { + int fullness = state.get(BlockProperties.FULLNESS); + if (fullness < 3 && SilkMothEntity.this.random.nextBoolean()) { + fullness ++; + BlocksHelper.setWithUpdate(SilkMothEntity.this.hiveWorld, SilkMothEntity.this.hivePos, state); + } + SilkMothEntity.this.world.playSound(null, SilkMothEntity.this.entrance, SoundEvents.BLOCK_BEEHIVE_ENTER, SoundCategory.BLOCKS, 1, 1); + SilkMothEntity.this.remove(); + } } } } diff --git a/src/main/java/ru/betterend/registry/EndEntities.java b/src/main/java/ru/betterend/registry/EndEntities.java index 3da97dc8..d89d2d46 100644 --- a/src/main/java/ru/betterend/registry/EndEntities.java +++ b/src/main/java/ru/betterend/registry/EndEntities.java @@ -36,6 +36,7 @@ public class EndEntities { SpawnHelper.restrictionWater(END_FISH, EndFishEntity::canSpawn); SpawnHelper.restrictionLand(SHADOW_WALKER, ShadowWalkerEntity::canSpawn); SpawnHelper.restrictionWater(CUBOZOA, CubozoaEntity::canSpawn); + SpawnHelper.restrictionAir(SILK_MOTH, SilkMothEntity::canSpawn); } protected static EntityType register(String name, SpawnGroup group, float width, float height, EntityFactory entity) { diff --git a/src/main/java/ru/betterend/registry/EndFeatures.java b/src/main/java/ru/betterend/registry/EndFeatures.java index f1fa80a4..da3e61c1 100644 --- a/src/main/java/ru/betterend/registry/EndFeatures.java +++ b/src/main/java/ru/betterend/registry/EndFeatures.java @@ -24,6 +24,7 @@ import ru.betterend.world.features.HydraluxFeature; import ru.betterend.world.features.LanceleafFeature; import ru.betterend.world.features.MengerSpongeFeature; import ru.betterend.world.features.OverworldIslandFeature; +import ru.betterend.world.features.SilkMothNestFeature; import ru.betterend.world.features.SingleInvertedScatterFeature; import ru.betterend.world.features.SinglePlantFeature; import ru.betterend.world.features.UnderwaterPlantFeature; @@ -155,6 +156,9 @@ public class EndFeatures { // Buildings public static final EndFeature CRASHED_SHIP = EndFeature.makeChansedFeature("crashed_ship", new CrashedShipFeature(), 500); + // Mobs + public static final EndFeature SILK_MOTH_NEST = EndFeature.makeChansedFeature("silk_moth_nest", new SilkMothNestFeature(), 2); + public static void registerBiomeFeatures(Identifier id, Biome biome, List>>> features) { if (GeneratorOptions.removeChorusFromVanillaBiomes()) { if (id.getNamespace().equals("minecraft")) { diff --git a/src/main/java/ru/betterend/world/biome/BiomeBlossomingSpires.java b/src/main/java/ru/betterend/world/biome/BiomeBlossomingSpires.java index 69aed399..08630fbf 100644 --- a/src/main/java/ru/betterend/world/biome/BiomeBlossomingSpires.java +++ b/src/main/java/ru/betterend/world/biome/BiomeBlossomingSpires.java @@ -2,6 +2,7 @@ package ru.betterend.world.biome; import net.minecraft.entity.EntityType; import ru.betterend.registry.EndBlocks; +import ru.betterend.registry.EndEntities; import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndSounds; @@ -25,6 +26,8 @@ public class BiomeBlossomingSpires extends EndBiome { .addFeature(EndFeatures.BLOSSOM_BERRY) .addFeature(EndFeatures.TWISTED_MOSS) .addFeature(EndFeatures.TWISTED_MOSS_WOOD) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 4)); + .addFeature(EndFeatures.SILK_MOTH_NEST) + .addMobSpawn(EntityType.ENDERMAN, 50, 1, 4) + .addMobSpawn(EndEntities.SILK_MOTH, 5, 1, 2)); } } diff --git a/src/main/java/ru/betterend/world/features/SilkMothNestFeature.java b/src/main/java/ru/betterend/world/features/SilkMothNestFeature.java new file mode 100644 index 00000000..a66d8862 --- /dev/null +++ b/src/main/java/ru/betterend/world/features/SilkMothNestFeature.java @@ -0,0 +1,55 @@ +package ru.betterend.world.features; + +import java.util.Random; + +import net.minecraft.block.BlockState; +import net.minecraft.state.property.Properties; +import net.minecraft.tag.BlockTags; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockPos.Mutable; +import net.minecraft.util.math.Direction; +import net.minecraft.world.Heightmap; +import net.minecraft.world.StructureWorldAccess; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import ru.betterend.blocks.BlockProperties; +import ru.betterend.registry.EndBlocks; +import ru.betterend.util.BlocksHelper; + +public class SilkMothNestFeature extends DefaultFeature { + private static final Mutable POS = new Mutable(); + + private boolean canGenerate(StructureWorldAccess world, BlockPos pos) { + BlockState state = world.getBlockState(pos.up()); + if (state.isIn(BlockTags.LEAVES) || state.isIn(BlockTags.LOGS)) { + state = world.getBlockState(pos); + if ((state.isAir() || state.isOf(EndBlocks.TENANEA_OUTER_LEAVES)) && world.isAir(pos.down())) { + for (Direction dir: BlocksHelper.HORIZONTAL) { + if (world.getBlockState(pos.down().offset(dir)).getMaterial().blocksMovement()) { + return false; + } + return true; + } + } + } + return false; + } + + @Override + public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos center, DefaultFeatureConfig featureConfig) { + int maxY = world.getTopY(Heightmap.Type.WORLD_SURFACE, center.getX(), center.getZ()); + int minY = BlocksHelper.upRay(world, new BlockPos(center.getX(), 0, center.getZ()), maxY); + POS.set(center); + for (int y = maxY; y > minY; y--) { + POS.setY(y); + if (canGenerate(world, POS)) { + Direction dir = BlocksHelper.randomHorizontal(random); + BlocksHelper.setWithoutUpdate(world, POS, EndBlocks.SILK_MOTH_NEST.getDefaultState().with(Properties.HORIZONTAL_FACING, dir).with(BlockProperties.ACTIVE, false)); + POS.setY(y - 1); + BlocksHelper.setWithoutUpdate(world, POS, EndBlocks.SILK_MOTH_NEST.getDefaultState().with(Properties.HORIZONTAL_FACING, dir)); + return true; + } + } + return false; + } +} diff --git a/src/main/resources/assets/betterend/blockstates/silk_moth_nest.json b/src/main/resources/assets/betterend/blockstates/silk_moth_nest.json index 332f6ffc..41975436 100644 --- a/src/main/resources/assets/betterend/blockstates/silk_moth_nest.json +++ b/src/main/resources/assets/betterend/blockstates/silk_moth_nest.json @@ -1,9 +1,21 @@ { "variants": { "active=false": { "model": "betterend:block/silk_moth_nest_top" }, - "active=true,facing=north": { "model": "betterend:block/silk_moth_nest_bottom" }, - "active=true,facing=south": { "model": "betterend:block/silk_moth_nest_bottom", "y": 180 }, - "active=true,facing=east": { "model": "betterend:block/silk_moth_nest_bottom", "y": 90 }, - "active=true,facing=west": { "model": "betterend:block/silk_moth_nest_bottom", "y": 270 } + "active=true,facing=north,fullness=0": { "model": "betterend:block/silk_moth_nest_bottom" }, + "active=true,facing=south,fullness=0": { "model": "betterend:block/silk_moth_nest_bottom", "y": 180 }, + "active=true,facing=east,fullness=0": { "model": "betterend:block/silk_moth_nest_bottom", "y": 90 }, + "active=true,facing=west,fullness=0": { "model": "betterend:block/silk_moth_nest_bottom", "y": 270 }, + "active=true,facing=north,fullness=1": { "model": "betterend:block/silk_moth_nest_bottom" }, + "active=true,facing=south,fullness=1": { "model": "betterend:block/silk_moth_nest_bottom", "y": 180 }, + "active=true,facing=east,fullness=1": { "model": "betterend:block/silk_moth_nest_bottom", "y": 90 }, + "active=true,facing=west,fullness=1": { "model": "betterend:block/silk_moth_nest_bottom", "y": 270 }, + "active=true,facing=north,fullness=2": { "model": "betterend:block/silk_moth_nest_bottom" }, + "active=true,facing=south,fullness=2": { "model": "betterend:block/silk_moth_nest_bottom", "y": 180 }, + "active=true,facing=east,fullness=2": { "model": "betterend:block/silk_moth_nest_bottom", "y": 90 }, + "active=true,facing=west,fullness=2": { "model": "betterend:block/silk_moth_nest_bottom", "y": 270 }, + "active=true,facing=north,fullness=3": { "model": "betterend:block/silk_moth_nest_bottom_silk" }, + "active=true,facing=south,fullness=3": { "model": "betterend:block/silk_moth_nest_bottom_silk", "y": 180 }, + "active=true,facing=east,fullness=3": { "model": "betterend:block/silk_moth_nest_bottom_silk", "y": 90 }, + "active=true,facing=west,fullness=3": { "model": "betterend:block/silk_moth_nest_bottom_silk", "y": 270 } } } diff --git a/src/main/resources/assets/betterend/models/block/silk_moth_nest_bottom_silk.json b/src/main/resources/assets/betterend/models/block/silk_moth_nest_bottom_silk.json new file mode 100644 index 00000000..7635ef7e --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/silk_moth_nest_bottom_silk.json @@ -0,0 +1,37 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "parent": "block/block", + "textures": { + "particle": "betterend:block/silk_moth_nest_side", + "texture": "betterend:block/silk_moth_nest_side", + "top": "betterend:block/silk_moth_nest_top", + "front": "betterend:block/silk_moth_nest_front_silk" + }, + "elements": [ + { + "__comment": "Box1", + "from": [ 0, 0, 0 ], + "to": [ 16, 13, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#top", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 3, 16, 16 ], "texture": "#front", "cullface": "north" }, + "south": { "uv": [ 0, 3, 16, 16 ], "texture": "#texture", "cullface": "south" }, + "west": { "uv": [ 0, 3, 16, 16 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 0, 3, 16, 16 ], "texture": "#texture", "cullface": "east" } + } + }, + { + "__comment": "Box1", + "from": [ 3, 12, 3 ], + "to": [ 13, 16, 13 ], + "faces": { + "up": { "uv": [ 3, 3, 13, 13 ], "texture": "#top", "cullface": "up" }, + "north": { "uv": [ 3, 0, 13, 4 ], "texture": "#texture" }, + "south": { "uv": [ 3, 0, 13, 4 ], "texture": "#texture" }, + "west": { "uv": [ 3, 0, 13, 4 ], "texture": "#texture" }, + "east": { "uv": [ 3, 0, 13, 4 ], "texture": "#texture" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/textures/minimap/entities/cubozoa.png b/src/main/resources/assets/betterend/textures/minimap/entities/cubozoa.png new file mode 100644 index 00000000..68b94dcc Binary files /dev/null and b/src/main/resources/assets/betterend/textures/minimap/entities/cubozoa.png differ diff --git a/src/main/resources/assets/betterend/textures/minimap/entities/dragonfly.png b/src/main/resources/assets/betterend/textures/minimap/entities/dragonfly.png new file mode 100644 index 00000000..c26c6f9e Binary files /dev/null and b/src/main/resources/assets/betterend/textures/minimap/entities/dragonfly.png differ diff --git a/src/main/resources/assets/betterend/textures/minimap/entities/end_fish.png b/src/main/resources/assets/betterend/textures/minimap/entities/end_fish.png new file mode 100644 index 00000000..6884a71d Binary files /dev/null and b/src/main/resources/assets/betterend/textures/minimap/entities/end_fish.png differ diff --git a/src/main/resources/assets/betterend/textures/minimap/entities/end_slime.png b/src/main/resources/assets/betterend/textures/minimap/entities/end_slime.png new file mode 100644 index 00000000..ac9ab7e8 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/minimap/entities/end_slime.png differ diff --git a/src/main/resources/assets/betterend/textures/minimap/entities/shadow_walker.png b/src/main/resources/assets/betterend/textures/minimap/entities/shadow_walker.png new file mode 100644 index 00000000..56de0661 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/minimap/entities/shadow_walker.png differ diff --git a/src/main/resources/assets/betterend/textures/minimap/entities/silk_moth.png b/src/main/resources/assets/betterend/textures/minimap/entities/silk_moth.png new file mode 100644 index 00000000..5dacaa25 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/minimap/entities/silk_moth.png differ