diff --git a/src/main/java/ru/betterend/BetterEnd.java b/src/main/java/ru/betterend/BetterEnd.java index 3c4abda6..4a5e602b 100644 --- a/src/main/java/ru/betterend/BetterEnd.java +++ b/src/main/java/ru/betterend/BetterEnd.java @@ -9,6 +9,7 @@ import ru.betterend.registry.BiomeRegistry; import ru.betterend.registry.BlockEntityRegistry; import ru.betterend.registry.BlockRegistry; import ru.betterend.registry.BlockTagRegistry; +import ru.betterend.registry.EntityRegistry; import ru.betterend.registry.FeatureRegistry; import ru.betterend.registry.ItemRegistry; import ru.betterend.registry.SoundsRegistry; @@ -29,6 +30,7 @@ public class BetterEnd implements ModInitializer { BlockRegistry.register(); BlockEntityRegistry.register(); FeatureRegistry.register(); + EntityRegistry.register(); BiomeRegistry.register(); BetterEndBiomeSource.register(); BlockTagRegistry.register(); diff --git a/src/main/java/ru/betterend/client/BetterEndClient.java b/src/main/java/ru/betterend/client/BetterEndClient.java index f1a200ea..c7c4dfdf 100644 --- a/src/main/java/ru/betterend/client/BetterEndClient.java +++ b/src/main/java/ru/betterend/client/BetterEndClient.java @@ -5,6 +5,7 @@ import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; import net.minecraft.client.render.RenderLayer; import net.minecraft.util.registry.Registry; import ru.betterend.registry.BlockEntityRenderRegistry; +import ru.betterend.registry.EntityRenderRegistry; import ru.betterend.registry.ParticleRegistry; import ru.betterend.registry.ScreensRegistry; @@ -15,6 +16,7 @@ public class BetterEndClient implements ClientModInitializer { BlockEntityRenderRegistry.register(); ScreensRegistry.register(); ParticleRegistry.register(); + EntityRenderRegistry.register(); } private void registerRenderLayers() { diff --git a/src/main/java/ru/betterend/entity/EntityDragonfly.java b/src/main/java/ru/betterend/entity/EntityDragonfly.java new file mode 100644 index 00000000..662314ce --- /dev/null +++ b/src/main/java/ru/betterend/entity/EntityDragonfly.java @@ -0,0 +1,20 @@ +package ru.betterend.entity; + +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.attribute.DefaultAttributeContainer; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.mob.FlyingEntity; +import net.minecraft.world.World; + +public class EntityDragonfly extends FlyingEntity { + public EntityDragonfly(EntityType entityType, World world) { + super(entityType, world); + } + + public static DefaultAttributeContainer.Builder createMobAttributes() { + return LivingEntity.createLivingAttributes() + .add(EntityAttributes.GENERIC_MAX_HEALTH, 8.0D) + .add(EntityAttributes.GENERIC_FOLLOW_RANGE, 16.0D); + } +} diff --git a/src/main/java/ru/betterend/entity/model/ModelEntityDragonfly.java b/src/main/java/ru/betterend/entity/model/ModelEntityDragonfly.java new file mode 100644 index 00000000..7abc64e7 --- /dev/null +++ b/src/main/java/ru/betterend/entity/model/ModelEntityDragonfly.java @@ -0,0 +1,99 @@ +package ru.betterend.entity.model; + +import net.minecraft.client.model.ModelPart; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.util.math.MatrixStack; +import ru.betterend.entity.EntityDragonfly; + +public class ModelEntityDragonfly extends EntityModel { + private final ModelPart model; + private final ModelPart head; + private final ModelPart tail; + private final ModelPart tail_2; + private final ModelPart wing_1; + private final ModelPart wing_2; + private final ModelPart wing_3; + private final ModelPart wing_4; + private final ModelPart legs_1; + private final ModelPart legs_2; + + public ModelEntityDragonfly() { + //textureWidth = 64; + //textureHeight = 64; + + textureWidth = 16; + textureHeight = 16; + + model = new ModelPart(this); + model.setPivot(2.0F, 21.5F, -4.0F); + model.setTextureOffset(0, 0).addCuboid(-4.0F, -4.0F, 0.0F, 4.0F, 4.0F, 9.0F, 0.0F, false); + + head = new ModelPart(this); + head.setPivot(-2.0F, -2.0F, 0.0F); + model.addChild(head); + setRotationAngle(head, 0.3491F, 0.0F, 0.0F); + head.setTextureOffset(0, 0).addCuboid(-1.5F, -1.5F, -2.5F, 3.0F, 3.0F, 3.0F, 0.0F, false); + + tail = new ModelPart(this); + tail.setPivot(-2.0F, -2.0F, 9.0F); + model.addChild(tail); + tail.setTextureOffset(0, 0).addCuboid(-1.5F, -1.5F, 0.0F, 3.0F, 3.0F, 7.0F, 0.0F, false); + + tail_2 = new ModelPart(this); + tail_2.setPivot(0.0F, 0.0F, 7.0F); + tail.addChild(tail_2); + tail_2.setTextureOffset(0, 0).addCuboid(-1.0F, -1.0F, 0.0F, 2.0F, 2.0F, 10.0F, 0.0F, false); + + wing_1 = new ModelPart(this); + wing_1.setPivot(-2.0F, -4.0F, 4.0F); + model.addChild(wing_1); + setRotationAngle(wing_1, 0.0F, 0.0F, 0.3491F); + wing_1.setTextureOffset(0, 0).addCuboid(-15.0F, 0.0F, -3.0F, 15.0F, 0.0F, 4.0F, 0.0F, false); + + wing_2 = new ModelPart(this); + wing_2.setPivot(-2.0F, -4.0F, 4.0F); + model.addChild(wing_2); + setRotationAngle(wing_2, 0.0F, 0.0F, 2.7925F); + wing_2.setTextureOffset(0, 0).addCuboid(-15.0F, 0.0F, -3.0F, 15.0F, 0.0F, 4.0F, 0.0F, false); + + wing_3 = new ModelPart(this); + wing_3.setPivot(-2.0F, -4.0F, 8.0F); + model.addChild(wing_3); + setRotationAngle(wing_3, 0.0F, 0.0F, 0.3491F); + wing_3.setTextureOffset(0, 0).addCuboid(-12.0F, 0.0F, -2.5F, 12.0F, 0.0F, 3.0F, 0.0F, false); + + wing_4 = new ModelPart(this); + wing_4.setPivot(-2.0F, -4.0F, 8.0F); + model.addChild(wing_4); + setRotationAngle(wing_4, 0.0F, 0.0F, 2.7925F); + wing_4.setTextureOffset(0, 0).addCuboid(-12.0F, 0.0F, -2.5F, 12.0F, 0.0F, 3.0F, 0.0F, false); + + legs_1 = new ModelPart(this); + legs_1.setPivot(-1.0F, 0.0F, 1.0F); + model.addChild(legs_1); + setRotationAngle(legs_1, 0.0F, 0.0F, -0.5236F); + legs_1.setTextureOffset(0, 0).addCuboid(0.0F, 0.0F, 0.0F, 0.0F, 3.0F, 6.0F, 0.0F, false); + + legs_2 = new ModelPart(this); + legs_2.setPivot(-3.0F, 0.0F, 1.0F); + model.addChild(legs_2); + setRotationAngle(legs_2, 0.0F, 0.0F, 0.5236F); + legs_2.setTextureOffset(0, 0).addCuboid(0.0F, 0.0F, 0.0F, 0.0F, 3.0F, 6.0F, 0.0F, false); + } + + + @Override + public void setAngles(EntityDragonfly entity, float limbAngle, float limbDistance, float animationProgress, float headYaw, float headPitch) {} + + @Override + public void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, float red, float green, float blue, float alpha) { + model.render(matrices, vertices, light, overlay); + } + + public void setRotationAngle(ModelPart modelRenderer, float x, float y, float z) { + modelRenderer.pitch = x; + modelRenderer.yaw = y; + modelRenderer.roll = z; + } +} diff --git a/src/main/java/ru/betterend/entity/render/RendererEntityDragonfly.java b/src/main/java/ru/betterend/entity/render/RendererEntityDragonfly.java new file mode 100644 index 00000000..92b675fd --- /dev/null +++ b/src/main/java/ru/betterend/entity/render/RendererEntityDragonfly.java @@ -0,0 +1,19 @@ +package ru.betterend.entity.render; + +import net.minecraft.client.render.entity.EntityRenderDispatcher; +import net.minecraft.client.render.entity.MobEntityRenderer; +import net.minecraft.util.Identifier; +import ru.betterend.entity.EntityDragonfly; +import ru.betterend.entity.model.ModelEntityDragonfly; + +public class RendererEntityDragonfly extends MobEntityRenderer { + + public RendererEntityDragonfly(EntityRenderDispatcher entityRenderDispatcher) { + super(entityRenderDispatcher, new ModelEntityDragonfly(), 0.5f); + } + + @Override + public Identifier getTexture(EntityDragonfly entity) { + return new Identifier("textures/block/stone.png"); + } +} \ No newline at end of file diff --git a/src/main/java/ru/betterend/registry/EntityRegistry.java b/src/main/java/ru/betterend/registry/EntityRegistry.java new file mode 100644 index 00000000..1d10c2ab --- /dev/null +++ b/src/main/java/ru/betterend/registry/EntityRegistry.java @@ -0,0 +1,31 @@ +package ru.betterend.registry; + +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityDimensions; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.EntityType.EntityFactory; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.SpawnGroup; +import net.minecraft.entity.attribute.DefaultAttributeContainer.Builder; +import net.minecraft.util.registry.Registry; +import ru.betterend.BetterEnd; +import ru.betterend.entity.EntityDragonfly; + +public class EntityRegistry { + public static final EntityType DRAGONFLY = register("dragonfly", SpawnGroup.CREATURE, 0.5F, 0.25F, EntityDragonfly::new, EntityDragonfly.createMobAttributes()); + + public static void register() {} + + 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()); + return type; + } + + private static EntityType register(String name, SpawnGroup group, float width, float height, EntityFactory entity, Builder attributes) { + EntityType type = Registry.register(Registry.ENTITY_TYPE, BetterEnd.makeID(name), FabricEntityTypeBuilder.create(group, entity).dimensions(EntityDimensions.fixed(width, height)).build()); + FabricDefaultAttributeRegistry.register(type, attributes); + return type; + } +} diff --git a/src/main/java/ru/betterend/registry/EntityRenderRegistry.java b/src/main/java/ru/betterend/registry/EntityRenderRegistry.java new file mode 100644 index 00000000..0e1bbf8f --- /dev/null +++ b/src/main/java/ru/betterend/registry/EntityRenderRegistry.java @@ -0,0 +1,25 @@ +package ru.betterend.registry; + +import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; +import net.minecraft.client.render.entity.MobEntityRenderer; +import net.minecraft.entity.EntityType; +import ru.betterend.entity.render.RendererEntityDragonfly; + +public class EntityRenderRegistry { + + public static void register() { + register(EntityRegistry.DRAGONFLY, RendererEntityDragonfly.class); + } + + private static void register(EntityType type, Class> renderer) { + EntityRendererRegistry.INSTANCE.register(type, (entityRenderDispatcher, context) -> { + MobEntityRenderer render = null; + try { + render = renderer.getConstructor(entityRenderDispatcher.getClass()).newInstance(entityRenderDispatcher); + } catch (Exception e) { + e.printStackTrace(); + } + return render; + }); + } +} diff --git a/src/main/java/ru/betterend/registry/SoundsRegistry.java b/src/main/java/ru/betterend/registry/SoundsRegistry.java index fe5c6ab4..63b6f8c6 100644 --- a/src/main/java/ru/betterend/registry/SoundsRegistry.java +++ b/src/main/java/ru/betterend/registry/SoundsRegistry.java @@ -6,10 +6,20 @@ import ru.betterend.BetterEnd; public class SoundsRegistry { + // Music + public static final SoundEvent MUSIC_FOGGY_MUSHROOMLAND = registerMusic("foggy_mushroomland"); + + // Ambient public static final SoundEvent AMBIENT_FOGGY_MUSHROOMLAND = registerAmbient("foggy_mushroomland"); public static void register() {} + private static SoundEvent registerMusic(String id) + { + id = "betterend.music." + id; + return Registry.register(Registry.SOUND_EVENT, id, new SoundEvent(BetterEnd.makeID(id))); + } + private static SoundEvent registerAmbient(String id) { id = "betterend.ambient." + id; diff --git a/src/main/java/ru/betterend/util/BlocksHelper.java b/src/main/java/ru/betterend/util/BlocksHelper.java index fac1c6e6..66519785 100644 --- a/src/main/java/ru/betterend/util/BlocksHelper.java +++ b/src/main/java/ru/betterend/util/BlocksHelper.java @@ -68,6 +68,15 @@ public class BlocksHelper { length++; return length; } + + public static int downRayRep(WorldAccess world, BlockPos pos, int maxDist) { + POS.set(pos); + for (int j = 1; j < maxDist && (world.getBlockState(POS)).getMaterial().isReplaceable(); j++) + { + POS.setY(POS.getY() - 1); + } + return pos.getY() - POS.getY(); + } public static BlockState rotateHorizontal(BlockState state, BlockRotation rotation, Property facing) { return (BlockState) state.with(facing, rotation.rotate((Direction) state.get(facing))); @@ -125,49 +134,31 @@ public class BlocksHelper { state = world.getBlockState(POS); // Falling blocks if (state.getBlock() instanceof FallingBlock) { + BlockState falling = state; + POS.setY(POS.getY() - 1); state = world.getBlockState(POS); - if (state.getMaterial().isReplaceable()) { + + int ray = downRayRep(world, POS.toImmutable(), 64); + if (ray > 32) { BlocksHelper.setWithoutUpdate(world, POS, Blocks.END_STONE.getDefaultState()); if (world.getRandom().nextBoolean()) { POS.setY(POS.getY() - 1); state = world.getBlockState(POS); - if (state.getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, POS, Blocks.END_STONE.getDefaultState()); - } + BlocksHelper.setWithoutUpdate(world, POS, Blocks.END_STONE.getDefaultState()); } } - } - // Fluid fixes - else if (!state.getFluidState().isEmpty()) { - BlockState liquid = state; - - BlockPos pos = POS.down(); - state = world.getBlockState(pos); - boolean update = state.getMaterial().isReplaceable() && !state.getMaterial().isLiquid(); - - pos = POS.north(); - state = world.getBlockState(pos); - update |= state.getMaterial().isReplaceable() && state.getFluidState().isEmpty(); - - pos = POS.south(); - state = world.getBlockState(pos); - update |= state.getMaterial().isReplaceable() && state.getFluidState().isEmpty(); - - pos = POS.east(); - state = world.getBlockState(pos); - update |= state.getMaterial().isReplaceable() && state.getFluidState().isEmpty(); - - pos = POS.west(); - state = world.getBlockState(pos); - update |= state.getMaterial().isReplaceable() && state.getFluidState().isEmpty(); - - if (update) { - world.setBlockState(POS, liquid, 1 | 2 | 8); + else { + POS.setY(y); + BlocksHelper.setWithoutUpdate(world, POS, AIR); + + POS.setY(y - ray); + BlocksHelper.setWithoutUpdate(world, POS, falling); } } + // Blocks without support else if (!state.canPlaceAt(world, POS)) { - // Is blue Vine + // Blue Vine if (state.getBlock() instanceof BlockBlueVine) { while (!state.canPlaceAt(world, POS)) { BlocksHelper.setWithoutUpdate(world, POS, AIR); @@ -188,7 +179,7 @@ public class BlocksHelper { POS.setY(POS.getY() + 1); BlocksHelper.setWithoutUpdate(world, POS, AIR); } - // Common plants & blocks + // Other blocks else { BlocksHelper.setWithoutUpdate(world, POS, AIR); } diff --git a/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java b/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java index d1a5ac3f..73846448 100644 --- a/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java +++ b/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java @@ -15,6 +15,7 @@ public class BiomeFoggyMushroomland extends EndBiome { .setSurface(BlockRegistry.END_MOSS, BlockRegistry.END_MYCELIUM) .setParticles(ParticleRegistry.GLOWING_SPHERE, 0.001F) .setLoop(SoundsRegistry.AMBIENT_FOGGY_MUSHROOMLAND) + .setMusic(SoundsRegistry.MUSIC_FOGGY_MUSHROOMLAND) .addFeature(FeatureRegistry.ENDER_ORE) .addFeature(FeatureRegistry.END_LAKE) .addFeature(FeatureRegistry.MOSSY_GLOWSHROOM) diff --git a/src/main/java/ru/betterend/world/features/EndLakeFeature.java b/src/main/java/ru/betterend/world/features/EndLakeFeature.java index 7d58d9c4..edefd0b4 100644 --- a/src/main/java/ru/betterend/world/features/EndLakeFeature.java +++ b/src/main/java/ru/betterend/world/features/EndLakeFeature.java @@ -65,15 +65,17 @@ public class EndLakeFeature extends DefaultFeature { POS.setZ(z); int mz = z - maskMinZ; if (!mask[mx][mz]) { - for (int y = waterLevel; y <= blockPos.getY() + 10; y++) { + for (int y = waterLevel; y <= waterLevel + 20; y++) { POS.setY(y); FluidState fluid = world.getFluidState(POS); if (!fluid.isEmpty()) { - mask[mx][mz] = true; - mask[mx + 1][mz] = true; - mask[mx - 1][mz] = true; - mask[mx][mz + 1] = true; - mask[mx][mz - 1] = true; + for (int i = -1; i < 2; i++) { + int px = mx + i; + for (int j = -1; j < 2; j++) { + int pz = mz + j; + mask[px][pz] = true; + } + } break; } } @@ -142,22 +144,26 @@ public class EndLakeFeature extends DefaultFeature { rb *= rb; if (y2 + x2 + z2 <= r) { state = world.getBlockState(POS); - if (state.isIn(BlockTagRegistry.END_GROUND) - || state.getBlock() == BlockRegistry.ENDSTONE_DUST) { + if (state.isIn(BlockTagRegistry.END_GROUND) || state.getBlock() == BlockRegistry.ENDSTONE_DUST) { BlocksHelper.setWithoutUpdate(world, POS, y < waterLevel ? WATER : AIR); + if (y == waterLevel - 1) { + world.getFluidTickScheduler().schedule(POS, WATER.getFluidState().getFluid(), 0); + } } pos = POS.down(); if (world.getBlockState(pos).getBlock().isIn(BlockTagRegistry.END_GROUND)) - BlocksHelper.setWithoutUpdate(world, POS.down(), - BlockRegistry.ENDSTONE_DUST.getDefaultState()); + BlocksHelper.setWithoutUpdate(world, POS.down(), BlockRegistry.ENDSTONE_DUST.getDefaultState()); pos = POS.up(); if (world.getBlockState(pos).isIn(BlockTagRegistry.END_GROUND)) { while (world.getBlockState(pos).isIn(BlockTagRegistry.END_GROUND)) { BlocksHelper.setWithoutUpdate(world, pos, pos.getY() < waterLevel ? WATER : AIR); + if (y == waterLevel - 1) { + world.getFluidTickScheduler().schedule(POS, WATER.getFluidState().getFluid(), 0); + } pos = pos.up(); } } - } else if (y <= waterLevel && y2 + x2 + z2 <= rb) { + } else if (y < waterLevel && y2 + x2 + z2 <= rb) { if (world.getBlockState(POS).getMaterial().isReplaceable()) { if (world.isAir(POS.up())) { state = world.getBiome(POS).getGenerationSettings().getSurfaceConfig() diff --git a/src/main/resources/assets/betterend/sounds.json b/src/main/resources/assets/betterend/sounds.json index 50a10538..7f649869 100644 --- a/src/main/resources/assets/betterend/sounds.json +++ b/src/main/resources/assets/betterend/sounds.json @@ -1,4 +1,20 @@ { + "betterend.music.foggy_mushroomland": { + "category": "music", + "sounds": [ + { + "name": "betterend:music/dan_henig_eternal_garden", + "volume": 0.3, + "stream": false + }, + { + "name": "betterend:music/dan_henig_nebular_focus", + "volume": 0.3, + "stream": false + } + ] + }, + "betterend.ambient.foggy_mushroomland": { "category": "ambient", "sounds": [ diff --git a/src/main/resources/assets/betterend/sounds/music/dan_henig_eternal_garden.ogg b/src/main/resources/assets/betterend/sounds/music/dan_henig_eternal_garden.ogg new file mode 100644 index 00000000..49044ab5 Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/music/dan_henig_eternal_garden.ogg differ diff --git a/src/main/resources/assets/betterend/sounds/music/dan_henig_nebular_focus.ogg b/src/main/resources/assets/betterend/sounds/music/dan_henig_nebular_focus.ogg new file mode 100644 index 00000000..78e11dbe Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/music/dan_henig_nebular_focus.ogg differ diff --git a/utilities/paulevs/converter/BlockBenchToFabricJava.java b/utilities/paulevs/converter/BlockBenchToFabricJava.java new file mode 100644 index 00000000..6217a0a8 --- /dev/null +++ b/utilities/paulevs/converter/BlockBenchToFabricJava.java @@ -0,0 +1,42 @@ +package paulevs.converter; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; + +public class BlockBenchToFabricJava { + public static void main(String[] args) throws Exception { + new BlockBenchToFabricJava("D:/blockbench_models/", "dragonfly.java"); + } + + private BlockBenchToFabricJava(String path, String nameIn) throws Exception { + String string; + File in = new File(path + nameIn); + File out = new File(path + "out.txt"); + + BufferedReader br = new BufferedReader(new FileReader(in)); + BufferedWriter wr = new BufferedWriter(new FileWriter(out)); + + boolean write = false; + while ((string = br.readLine()) != null) { + string = string + .replace("ModelRenderer", "ModelPart") + .replace("setRotationPoint", "setPivot") + .replace("addBox", "addCuboid"); + + if (write) + wr.write(string + "\n"); + + if (string.contains("{")) + write = true; + + if (string.contains("}")) + break; + } + + wr.close(); + br.close(); + } +}