diff --git a/gradle.properties b/gradle.properties index 9abb7905..8921b2dd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ loader_version=0.11.3 # Mod Properties - mod_version = 0.9.4-pre + mod_version = 0.9.7-pre maven_group = ru.betterend archives_base_name = better-end diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/src/main/java/ru/betterend/BetterEnd.java b/src/main/java/ru/betterend/BetterEnd.java index 32a7ed61..65b17c92 100644 --- a/src/main/java/ru/betterend/BetterEnd.java +++ b/src/main/java/ru/betterend/BetterEnd.java @@ -39,6 +39,8 @@ import ru.betterend.world.surface.SurfaceBuilders; public class BetterEnd implements ModInitializer { public static final String MOD_ID = "betterend"; public static final Logger LOGGER = Logger.get(); + private static boolean hasHydrogen; + @Override public void onInitialize() { EndPortals.loadPortals(); @@ -70,6 +72,7 @@ public class BetterEnd implements ModInitializer { if (hasGuideBook()) { GuideBookItem.register(); } + hasHydrogen = FabricLoader.getInstance().isModLoaded("hydrogen"); FabricLoader.getInstance().getEntrypoints("betterend", BetterEndPlugin.class).forEach(BetterEndPlugin::register); Configs.saveConfigs(); @@ -88,6 +91,10 @@ public class BetterEnd implements ModInitializer { return FabricLoader.getInstance().isModLoaded("patchouli"); } + public static boolean hasHydrogen() { + return hasHydrogen; + } + public static ResourceLocation makeID(String path) { return new ResourceLocation(MOD_ID, path); } diff --git a/src/main/java/ru/betterend/blocks/LucerniaSaplingBlock.java b/src/main/java/ru/betterend/blocks/LucerniaSaplingBlock.java new file mode 100644 index 00000000..cb9a74e1 --- /dev/null +++ b/src/main/java/ru/betterend/blocks/LucerniaSaplingBlock.java @@ -0,0 +1,25 @@ +package ru.betterend.blocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; +import ru.betterend.blocks.basis.FeatureSaplingBlock; +import ru.betterend.registry.EndBlocks; +import ru.betterend.registry.EndFeatures; + +public class LucerniaSaplingBlock extends FeatureSaplingBlock { + public LucerniaSaplingBlock() { + super(); + } + + @Override + protected Feature getFeature() { + return EndFeatures.LUCERNIA.getFeature(); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return world.getBlockState(pos.below()).is(EndBlocks.RUTISCUS); + } +} diff --git a/src/main/java/ru/betterend/blocks/TenaneaFlowersBlock.java b/src/main/java/ru/betterend/blocks/TenaneaFlowersBlock.java index 82238857..b032941b 100644 --- a/src/main/java/ru/betterend/blocks/TenaneaFlowersBlock.java +++ b/src/main/java/ru/betterend/blocks/TenaneaFlowersBlock.java @@ -27,6 +27,7 @@ public class TenaneaFlowersBlock extends VineBlock implements IColorProvider { @Override public BlockColor getProvider() { return (state, world, pos, tintIndex) -> { + if (pos == null) pos = BlockPos.ZERO; long i = (MHelper.getRandom(pos.getX(), pos.getZ()) & 63) + pos.getY(); double delta = i * 0.1; int index = MHelper.floor(delta); diff --git a/src/main/java/ru/betterend/blocks/TenaneaSaplingBlock.java b/src/main/java/ru/betterend/blocks/TenaneaSaplingBlock.java index c4e8393f..d08211e2 100644 --- a/src/main/java/ru/betterend/blocks/TenaneaSaplingBlock.java +++ b/src/main/java/ru/betterend/blocks/TenaneaSaplingBlock.java @@ -15,11 +15,11 @@ public class TenaneaSaplingBlock extends FeatureSaplingBlock { @Override protected Feature getFeature() { - return EndFeatures.LUCERNIA.getFeature(); + return EndFeatures.TENANEA.getFeature(); } @Override public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return world.getBlockState(pos.below()).is(EndBlocks.RUTISCUS); + return world.getBlockState(pos.below()).is(EndBlocks.PINK_MOSS); } } diff --git a/src/main/java/ru/betterend/blocks/basis/FeatureSaplingBlock.java b/src/main/java/ru/betterend/blocks/basis/FeatureSaplingBlock.java index b982a580..cc091cc4 100644 --- a/src/main/java/ru/betterend/blocks/basis/FeatureSaplingBlock.java +++ b/src/main/java/ru/betterend/blocks/basis/FeatureSaplingBlock.java @@ -1,6 +1,8 @@ package ru.betterend.blocks.basis; import java.io.Reader; +import java.util.Collections; +import java.util.List; import java.util.Random; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; @@ -9,38 +11,41 @@ import net.minecraft.core.Direction; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.BonemealableBlock; +import net.minecraft.world.level.block.SaplingBlock; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import ru.betterend.client.render.ERenderLayer; import ru.betterend.interfaces.IRenderTypeable; +import ru.betterend.patterns.BlockPatterned; import ru.betterend.patterns.Patterns; import ru.betterend.registry.EndTags; -public abstract class FeatureSaplingBlock extends BlockBaseNotFull implements BonemealableBlock, IRenderTypeable { +public abstract class FeatureSaplingBlock extends SaplingBlock implements IRenderTypeable, BlockPatterned { private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12); - + public FeatureSaplingBlock() { - super(FabricBlockSettings.of(Material.PLANT) + super(null, FabricBlockSettings.of(Material.PLANT) .breakByHand(true) .collidable(false) .instabreak() .sound(SoundType.GRASS) .randomTicks()); } - + public FeatureSaplingBlock(int light) { - super(FabricBlockSettings.of(Material.PLANT) + super(null, FabricBlockSettings.of(Material.PLANT) .breakByHand(true) .collidable(false) .luminance(light) @@ -48,8 +53,13 @@ public abstract class FeatureSaplingBlock extends BlockBaseNotFull implements Bo .sound(SoundType.GRASS) .randomTicks()); } - + protected abstract Feature getFeature(); + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + return Collections.singletonList(new ItemStack(this)); + } @Override public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { @@ -69,21 +79,21 @@ public abstract class FeatureSaplingBlock extends BlockBaseNotFull implements Bo return state; } - @Override - public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { - return true; - } - @Override public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { return random.nextInt(16) == 0; } @Override - public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) { + public void advanceTree(ServerLevel world, BlockPos pos, BlockState blockState, Random random) { getFeature().place(world, world.getChunkSource().getGenerator(), random, pos, null); } + @Override + public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) { + this.tick(state, world, pos, random); + } + @Override public void tick(BlockState state, ServerLevel world, BlockPos pos, Random random) { super.tick(state, world, pos, random); @@ -91,18 +101,18 @@ public abstract class FeatureSaplingBlock extends BlockBaseNotFull implements Bo performBonemeal(world, random, pos, state); } } - + @Override public ERenderLayer getRenderLayer() { return ERenderLayer.CUTOUT; } - + @Override public String getStatesPattern(Reader data) { ResourceLocation blockId = Registry.BLOCK.getKey(this); return Patterns.createJson(data, blockId.getPath(), blockId.getPath()); } - + @Override public String getModelString(String block) { if (block.contains("item")) { @@ -111,7 +121,7 @@ public abstract class FeatureSaplingBlock extends BlockBaseNotFull implements Bo } return Patterns.createJson(Patterns.BLOCK_CROSS, block); } - + @Override public ResourceLocation statePatternId() { return Patterns.STATE_SAPLING; diff --git a/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java b/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java index e48d9f14..3e6463ae 100644 --- a/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java +++ b/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java @@ -49,7 +49,7 @@ public class MetalMaterial { public final Block block; public final Block tile; public final Block bars; - public final Block plate; + public final Block pressurePlate; public final Block door; public final Block trapdoor; public final Block anvil; @@ -78,6 +78,7 @@ public class MetalMaterial { public final Item hoe; public final Item hammer; + public final Item forgedPlate; public final Item helmet; public final Item chestplate; public final Item leggings; @@ -113,7 +114,7 @@ public class MetalMaterial { anvil = EndBlocks.registerBlock(name + "_anvil", new EndAnvilBlock(block.defaultMaterialColor(), level)); bars = EndBlocks.registerBlock(name + "_bars", new EndMetalPaneBlock(block)); chain = EndBlocks.registerBlock(name + "_chain", new EndChainBlock(block.defaultMaterialColor())); - plate = EndBlocks.registerBlock(name + "_plate", new EndWoodenPlateBlock(block)); + pressurePlate = EndBlocks.registerBlock(name + "_plate", new EndWoodenPlateBlock(block)); chandelier = EndBlocks.registerBlock(name + "_chandelier", new ChandelierBlock(block)); bulb_lantern = EndBlocks.registerBlock(name + "_bulb_lantern", new BulbVineLanternBlock(lanternProperties)); @@ -136,6 +137,7 @@ public class MetalMaterial { hoe = EndItems.registerTool(name + "_hoe", new EndHoeItem(material, -3, 0.0F, itemSettings)); hammer = EndItems.registerTool(name + "_hammer", new EndHammerItem(material, 5.0F, -3.2F, 0.3D, itemSettings)); + forgedPlate = EndItems.registerItem(name + "_forged_plate"); helmet = EndItems.registerItem(name + "_helmet", new EndArmorItem(armor, EquipmentSlot.HEAD, itemSettings)); chestplate = EndItems.registerItem(name + "_chestplate", new EndArmorItem(armor, EquipmentSlot.CHEST, itemSettings)); leggings = EndItems.registerItem(name + "_leggings", new EndArmorItem(armor, EquipmentSlot.LEGS, itemSettings)); @@ -148,13 +150,14 @@ public class MetalMaterial { // Basic recipes GridRecipe.make(name + "_ingot_from_nuggets", ingot).setShape("###", "###", "###").addMaterial('#', nugget).setGroup("end_metal_ingots_nug").build(); + GridRecipe.make(name + "_nuggets_from_ingot", nugget).setOutputCount(9).setList("#").addMaterial('#', ingot).setGroup("end_metal_nuggets_ing").build(); GridRecipe.make(name + "_block", block).setShape("###", "###", "###").addMaterial('#', ingot).setGroup("end_metal_blocks").build(); GridRecipe.make(name + "_ingot_from_block", ingot).setOutputCount(9).setList("#").addMaterial('#', block).setGroup("end_metal_ingots").build(); // Block recipes GridRecipe.make(name + "_tile", tile).setOutputCount(4).setShape("##", "##").addMaterial('#', block).setGroup("end_metal_tiles").build(); GridRecipe.make(name + "_bars", bars).setOutputCount(16).setShape("###", "###").addMaterial('#', ingot).setGroup("end_metal_bars").build(); - GridRecipe.make(name + "_plate", plate).setShape("##").addMaterial('#', ingot).setGroup("end_metal_plates").build(); + GridRecipe.make(name + "_pressure_plate", pressurePlate).setShape("##").addMaterial('#', ingot).setGroup("end_metal_plates").build(); GridRecipe.make(name + "_door", door).setOutputCount(3).setShape("##", "##", "##").addMaterial('#', ingot).setGroup("end_metal_doors").build(); GridRecipe.make(name + "_trapdoor", trapdoor).setShape("##", "##").addMaterial('#', ingot).setGroup("end_metal_trapdoors").build(); GridRecipe.make(name + "_stairs", stairs).setOutputCount(4).setShape("# ", "## ", "###").addMaterial('#', block, tile).setGroup("end_metal_stairs").build(); @@ -182,6 +185,7 @@ public class MetalMaterial { AnvilRecipe.Builder.create(name + "_axe_head").setInput(ingot).setInputCount(3).setOutput(axeHead).setAnvilLevel(level).setToolLevel(level).setDamage(level).build(); AnvilRecipe.Builder.create(name + "_hoe_head").setInput(ingot).setInputCount(2).setOutput(hoeHead).setAnvilLevel(level).setToolLevel(level).setDamage(level).build(); AnvilRecipe.Builder.create(name + "_sword_blade").setInput(ingot).setOutput(swordBlade).setAnvilLevel(level).setToolLevel(level).setDamage(level).build(); + AnvilRecipe.Builder.create(name + "_forged_plate").setInput(ingot).setOutput(forgedPlate).setAnvilLevel(level).setToolLevel(level).setDamage(level).build(); // Tools from parts SmithingTableRecipe.create(name + "_hammer").setResult(hammer).setBase(block).setAddition(Items.STICK).build(); @@ -193,10 +197,10 @@ public class MetalMaterial { SmithingTableRecipe.create(name + "_shovel").setResult(shovel).setBase(shovelHead).setAddition(Items.STICK).build(); // Armor crafting - GridRecipe.make(name + "_helmet", helmet).setShape("###", "# #").addMaterial('#', ingot).setGroup("end_metal_helmets").build(); - GridRecipe.make(name + "_chestplate", chestplate).setShape("# #", "###", "###").addMaterial('#', ingot).setGroup("end_metal_chestplates").build(); - GridRecipe.make(name + "_leggings", leggings).setShape("###", "# #", "# #").addMaterial('#', ingot).setGroup("end_metal_leggings").build(); - GridRecipe.make(name + "_boots", boots).setShape("# #", "# #").addMaterial('#', ingot).setGroup("end_metal_boots").build(); + GridRecipe.make(name + "_helmet", helmet).setShape("###", "# #").addMaterial('#', forgedPlate).setGroup("end_metal_helmets").build(); + GridRecipe.make(name + "_chestplate", chestplate).setShape("# #", "###", "###").addMaterial('#', forgedPlate).setGroup("end_metal_chestplates").build(); + GridRecipe.make(name + "_leggings", leggings).setShape("###", "# #", "# #").addMaterial('#', forgedPlate).setGroup("end_metal_leggings").build(); + GridRecipe.make(name + "_boots", boots).setShape("# #", "# #").addMaterial('#', forgedPlate).setGroup("end_metal_boots").build(); TagHelper.addTag(BlockTags.ANVIL, anvil); TagHelper.addTag(BlockTags.BEACON_BASE_BLOCKS, block); diff --git a/src/main/java/ru/betterend/client/BetterEndClient.java b/src/main/java/ru/betterend/client/BetterEndClient.java index b9ba6104..57d04ae1 100644 --- a/src/main/java/ru/betterend/client/BetterEndClient.java +++ b/src/main/java/ru/betterend/client/BetterEndClient.java @@ -7,6 +7,8 @@ import net.minecraft.core.Registry; import ru.betterend.BetterEnd; import ru.betterend.client.render.ERenderLayer; import ru.betterend.interfaces.IRenderTypeable; +import ru.betterend.interfaces.MultiModelItem; +import ru.betterend.item.CrystaliteArmor; import ru.betterend.registry.EndBlockEntityRenders; import ru.betterend.registry.EndEntitiesRenders; import ru.betterend.registry.EndModelProviders; @@ -23,6 +25,8 @@ public class BetterEndClient implements ClientModInitializer { EndParticles.register(); EndEntitiesRenders.register(); EndModelProviders.register(); + MultiModelItem.register(); + CrystaliteArmor.registerTooltips(); ClientOptions.init(); if (BetterEnd.isDevEnvironment()) { diff --git a/src/main/java/ru/betterend/effects/EndPotions.java b/src/main/java/ru/betterend/effects/EndPotions.java index 64608d37..0b2e2394 100644 --- a/src/main/java/ru/betterend/effects/EndPotions.java +++ b/src/main/java/ru/betterend/effects/EndPotions.java @@ -16,7 +16,7 @@ public class EndPotions { public final static Potion LONG_END_VEIL = registerPotion("long_end_veil", EndStatusEffects.END_VEIL, 9600); public static Potion registerPotion(String name, MobEffect effect, int duration) { - return registerPotion(name, new Potion(name, new MobEffectInstance[]{ new MobEffectInstance(effect, duration) })); + return registerPotion(name, new Potion(name, new MobEffectInstance(effect, duration))); } public static Potion registerPotion(String name, Potion potion) { diff --git a/src/main/java/ru/betterend/effects/EndStatusEffects.java b/src/main/java/ru/betterend/effects/EndStatusEffects.java index b5176126..1a7edb84 100644 --- a/src/main/java/ru/betterend/effects/EndStatusEffects.java +++ b/src/main/java/ru/betterend/effects/EndStatusEffects.java @@ -2,13 +2,18 @@ package ru.betterend.effects; import net.minecraft.core.Registry; import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; import ru.betterend.BetterEnd; import ru.betterend.effects.status.EndVeilEffect; public class EndStatusEffects { - + public final static MobEffectInstance CRYSTALITE_HEALTH_REGEN = new MobEffectInstance(MobEffects.REGENERATION, 40, 0, true, false, true); + public final static MobEffectInstance CRYSTALITE_DIG_SPEED = new MobEffectInstance(MobEffects.DIG_SPEED, 40, 0, true, false, true); + public final static MobEffectInstance CRYSTALITE_MOVE_SPEED = new MobEffectInstance(MobEffects.MOVEMENT_SPEED, 40, 0, true, false, true); + public final static MobEffect END_VEIL = registerEffect("end_veil", new EndVeilEffect()); - + public static MobEffect registerEffect(String name, E effect) { return Registry.register(Registry.MOB_EFFECT, BetterEnd.makeID(name), effect); } diff --git a/src/main/java/ru/betterend/entity/DragonflyEntity.java b/src/main/java/ru/betterend/entity/DragonflyEntity.java index b5e7a5b3..a57d0e3b 100644 --- a/src/main/java/ru/betterend/entity/DragonflyEntity.java +++ b/src/main/java/ru/betterend/entity/DragonflyEntity.java @@ -7,7 +7,6 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.AgableMob; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; @@ -25,6 +24,7 @@ import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.ai.util.RandomPos; import net.minecraft.world.entity.animal.Animal; import net.minecraft.world.entity.animal.FlyingAnimal; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.ServerLevelAccessor; @@ -57,8 +57,8 @@ public class DragonflyEntity extends Animal implements FlyingAnimal { } @Override - public Entity getLeashHolder() { - return null; + public boolean canBeLeashed(Player player) { + return false; } @Override diff --git a/src/main/java/ru/betterend/entity/SilkMothEntity.java b/src/main/java/ru/betterend/entity/SilkMothEntity.java index 3365d894..a02716d1 100644 --- a/src/main/java/ru/betterend/entity/SilkMothEntity.java +++ b/src/main/java/ru/betterend/entity/SilkMothEntity.java @@ -17,7 +17,6 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.AgableMob; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; @@ -36,6 +35,7 @@ import net.minecraft.world.entity.ai.util.RandomPos; import net.minecraft.world.entity.animal.Animal; import net.minecraft.world.entity.animal.FlyingAnimal; import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.level.Level; @@ -82,8 +82,8 @@ public class SilkMothEntity extends Animal implements FlyingAnimal { } @Override - public Entity getLeashHolder() { - return null; + public boolean canBeLeashed(Player player) { + return false; } @Override diff --git a/src/main/java/ru/betterend/integration/NourishIntegration.java b/src/main/java/ru/betterend/integration/NourishIntegration.java index 37a92fa6..0fdf6274 100644 --- a/src/main/java/ru/betterend/integration/NourishIntegration.java +++ b/src/main/java/ru/betterend/integration/NourishIntegration.java @@ -17,9 +17,38 @@ public class NourishIntegration extends ModIntegration { Tag.Named protein = getItemTag("protein"); Tag.Named sweets = getItemTag("sweets"); - TagHelper.addTag(fats, EndItems.END_FISH_RAW, EndItems.END_FISH_COOKED); - TagHelper.addTag(fruit, EndItems.SHADOW_BERRY_RAW, EndItems.SHADOW_BERRY_COOKED, EndItems.BLOSSOM_BERRY, EndItems.SHADOW_BERRY_JELLY, EndItems.SWEET_BERRY_JELLY); - TagHelper.addTag(protein, EndItems.END_FISH_RAW, EndItems.END_FISH_COOKED); - TagHelper.addTag(sweets, EndItems.SHADOW_BERRY_JELLY, EndItems.SWEET_BERRY_JELLY); + TagHelper.addTag( + fats, + EndItems.END_FISH_RAW, + EndItems.END_FISH_COOKED + ); + TagHelper.addTag( + fruit, + EndItems.SHADOW_BERRY_RAW, + EndItems.SHADOW_BERRY_COOKED, + EndItems.BLOSSOM_BERRY, + EndItems.SHADOW_BERRY_JELLY, + EndItems.SWEET_BERRY_JELLY, + EndItems.BLOSSOM_BERRY_JELLY, + EndItems.AMBER_ROOT_RAW, + EndItems.CHORUS_MUSHROOM_RAW, + EndItems.CHORUS_MUSHROOM_COOKED, + EndItems.BOLUX_MUSHROOM_COOKED + ); + TagHelper.addTag( + protein, + EndItems.END_FISH_RAW, + EndItems.END_FISH_COOKED, + EndItems.CHORUS_MUSHROOM_COOKED, + EndItems.BOLUX_MUSHROOM_COOKED, + EndItems.CAVE_PUMPKIN_PIE + ); + TagHelper.addTag( + sweets, + EndItems.SHADOW_BERRY_JELLY, + EndItems.SWEET_BERRY_JELLY, + EndItems.BLOSSOM_BERRY_JELLY, + EndItems.CAVE_PUMPKIN_PIE + ); } } diff --git a/src/main/java/ru/betterend/interfaces/BreakableItem.java b/src/main/java/ru/betterend/interfaces/BreakableItem.java deleted file mode 100644 index 7af4687b..00000000 --- a/src/main/java/ru/betterend/interfaces/BreakableItem.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.betterend.interfaces; - -public interface BreakableItem { - void registerBrokenItem(); -} diff --git a/src/main/java/ru/betterend/interfaces/MobEffectApplier.java b/src/main/java/ru/betterend/interfaces/MobEffectApplier.java new file mode 100644 index 00000000..7aee65f6 --- /dev/null +++ b/src/main/java/ru/betterend/interfaces/MobEffectApplier.java @@ -0,0 +1,7 @@ +package ru.betterend.interfaces; + +import net.minecraft.world.entity.LivingEntity; + +public interface MobEffectApplier { + void applyEffect(LivingEntity owner); +} diff --git a/src/main/java/ru/betterend/interfaces/MultiModelItem.java b/src/main/java/ru/betterend/interfaces/MultiModelItem.java new file mode 100644 index 00000000..9d0cbe59 --- /dev/null +++ b/src/main/java/ru/betterend/interfaces/MultiModelItem.java @@ -0,0 +1,18 @@ +package ru.betterend.interfaces; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import ru.betterend.registry.EndItems; + +public interface MultiModelItem { + @Environment(EnvType.CLIENT) + void registerModelPredicate(); + + static void register() { + EndItems.getModItems().forEach(item -> { + if (item instanceof MultiModelItem) { + ((MultiModelItem) item).registerModelPredicate(); + } + }); + } +} diff --git a/src/main/java/ru/betterend/item/ArmoredElytra.java b/src/main/java/ru/betterend/item/ArmoredElytra.java index cb2e5218..6c2189e5 100644 --- a/src/main/java/ru/betterend/item/ArmoredElytra.java +++ b/src/main/java/ru/betterend/item/ArmoredElytra.java @@ -2,18 +2,14 @@ package ru.betterend.item; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.item.v1.EquipmentSlotProvider; import net.fabricmc.fabric.api.object.builder.v1.client.model.FabricModelPredicateProviderRegistry; -import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.item.*; import ru.betterend.BetterEnd; -import ru.betterend.interfaces.BreakableItem; -import ru.betterend.patterns.ModelProvider; -import ru.betterend.patterns.Patterns; +import ru.betterend.interfaces.MultiModelItem; import ru.betterend.registry.EndItems; import java.util.UUID; diff --git a/src/main/java/ru/betterend/item/CrystaliteArmor.java b/src/main/java/ru/betterend/item/CrystaliteArmor.java new file mode 100644 index 00000000..26a26698 --- /dev/null +++ b/src/main/java/ru/betterend/item/CrystaliteArmor.java @@ -0,0 +1,75 @@ +package ru.betterend.item; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Style; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import ru.betterend.effects.EndStatusEffects; +import ru.betterend.item.material.EndArmorMaterial; +import ru.betterend.registry.EndItems; + +public class CrystaliteArmor extends EndArmorItem { + + protected final static TranslatableComponent CHEST_DESC; + protected final static TranslatableComponent BOOTS_DESC; + + public CrystaliteArmor(EquipmentSlot equipmentSlot, Properties settings) { + super(EndArmorMaterial.CRYSTALITE, equipmentSlot, settings); + } + + public static boolean hasFullSet(LivingEntity owner) { + for (ItemStack armorStack : owner.getArmorSlots()) { + if (!(armorStack.getItem() instanceof CrystaliteArmor)) { + return false; + } + } + return true; + } + + public static void applySetEffect(LivingEntity owner) { + owner.addEffect(new MobEffectInstance(EndStatusEffects.CRYSTALITE_HEALTH_REGEN)); + } + + @Environment(EnvType.CLIENT) + public static void registerTooltips() { + ItemTooltipCallback.EVENT.register((stack, context, lines) -> { + if (stack.getItem() instanceof CrystaliteArmor) { + boolean hasSet = false; + Player owner = Minecraft.getInstance().player; + if (owner != null) { + hasSet = hasFullSet(owner); + } + + TranslatableComponent setDesc = new TranslatableComponent("tooltip.armor.crystalite_set"); + setDesc.setStyle(Style.EMPTY.applyFormats(hasSet ? ChatFormatting.BLUE : ChatFormatting.DARK_GRAY, ChatFormatting.ITALIC)); + lines.add(TextComponent.EMPTY); + lines.add(setDesc); + + if (stack.getItem() == EndItems.CRYSTALITE_CHESTPLATE) { + lines.add(1, TextComponent.EMPTY); + lines.add(2, CHEST_DESC); + } else if (stack.getItem() == EndItems.CRYSTALITE_BOOTS) { + lines.add(1, TextComponent.EMPTY); + lines.add(2, BOOTS_DESC); + } + } + }); + } + + static { + Style descStyle = Style.EMPTY.applyFormats(ChatFormatting.DARK_AQUA, ChatFormatting.ITALIC); + CHEST_DESC = new TranslatableComponent("tooltip.armor.crystalite_chest"); + CHEST_DESC.setStyle(descStyle); + BOOTS_DESC = new TranslatableComponent("tooltip.armor.crystalite_boots"); + BOOTS_DESC.setStyle(descStyle); + } +} diff --git a/src/main/java/ru/betterend/item/CrystaliteBoots.java b/src/main/java/ru/betterend/item/CrystaliteBoots.java new file mode 100644 index 00000000..03e0e797 --- /dev/null +++ b/src/main/java/ru/betterend/item/CrystaliteBoots.java @@ -0,0 +1,21 @@ +package ru.betterend.item; + +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.Rarity; +import ru.betterend.effects.EndStatusEffects; +import ru.betterend.interfaces.MobEffectApplier; +import ru.betterend.registry.EndItems; + +public class CrystaliteBoots extends CrystaliteArmor implements MobEffectApplier { + + public CrystaliteBoots() { + super(EquipmentSlot.FEET, EndItems.makeItemSettings().rarity(Rarity.RARE)); + } + + @Override + public void applyEffect(LivingEntity owner) { + owner.addEffect(new MobEffectInstance(EndStatusEffects.CRYSTALITE_MOVE_SPEED)); + } +} diff --git a/src/main/java/ru/betterend/item/CrystaliteChestplate.java b/src/main/java/ru/betterend/item/CrystaliteChestplate.java new file mode 100644 index 00000000..3c55deb0 --- /dev/null +++ b/src/main/java/ru/betterend/item/CrystaliteChestplate.java @@ -0,0 +1,21 @@ +package ru.betterend.item; + +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.Rarity; +import ru.betterend.effects.EndStatusEffects; +import ru.betterend.interfaces.MobEffectApplier; +import ru.betterend.registry.EndItems; + +public class CrystaliteChestplate extends CrystaliteArmor implements MobEffectApplier { + + public CrystaliteChestplate() { + super(EquipmentSlot.CHEST, EndItems.makeItemSettings().rarity(Rarity.RARE)); + } + + @Override + public void applyEffect(LivingEntity owner) { + owner.addEffect(new MobEffectInstance(EndStatusEffects.CRYSTALITE_DIG_SPEED)); + } +} diff --git a/src/main/java/ru/betterend/item/CrystaliteHelmet.java b/src/main/java/ru/betterend/item/CrystaliteHelmet.java new file mode 100644 index 00000000..1231afeb --- /dev/null +++ b/src/main/java/ru/betterend/item/CrystaliteHelmet.java @@ -0,0 +1,18 @@ +package ru.betterend.item; + +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.item.Rarity; +import ru.betterend.registry.EndAttributes; +import ru.betterend.registry.EndItems; + +import java.util.UUID; + +public class CrystaliteHelmet extends CrystaliteArmor { + + public CrystaliteHelmet() { + super(EquipmentSlot.HEAD, EndItems.makeItemSettings().rarity(Rarity.RARE)); + UUID uuid = ARMOR_MODIFIER_UUID_PER_SLOT[EquipmentSlot.HEAD.getIndex()]; + addAttributeModifier(EndAttributes.BLINDNESS_RESISTANCE, new AttributeModifier(uuid, "Helmet blindness resistance", 1.0, AttributeModifier.Operation.ADDITION)); + } +} diff --git a/src/main/java/ru/betterend/item/CrystaliteLeggings.java b/src/main/java/ru/betterend/item/CrystaliteLeggings.java new file mode 100644 index 00000000..fafccec3 --- /dev/null +++ b/src/main/java/ru/betterend/item/CrystaliteLeggings.java @@ -0,0 +1,18 @@ +package ru.betterend.item; + +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.item.Rarity; +import ru.betterend.registry.EndItems; + +import java.util.UUID; + +public class CrystaliteLeggings extends CrystaliteArmor { + + public CrystaliteLeggings() { + super(EquipmentSlot.LEGS, EndItems.makeItemSettings().rarity(Rarity.RARE)); + UUID uuid = ARMOR_MODIFIER_UUID_PER_SLOT[EquipmentSlot.LEGS.getIndex()]; + addAttributeModifier(Attributes.MAX_HEALTH, new AttributeModifier(uuid, "Armor health boost", 4.0, AttributeModifier.Operation.ADDITION)); + } +} diff --git a/src/main/java/ru/betterend/item/EndArmorItem.java b/src/main/java/ru/betterend/item/EndArmorItem.java index d76a71a7..b842c112 100644 --- a/src/main/java/ru/betterend/item/EndArmorItem.java +++ b/src/main/java/ru/betterend/item/EndArmorItem.java @@ -1,25 +1,19 @@ package ru.betterend.item; -import java.util.UUID; - import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; - -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.item.ArmorItem; import net.minecraft.world.item.ArmorMaterial; -import net.minecraft.world.item.Item; -import ru.betterend.mixin.common.ArmorItemAccessor; -import ru.betterend.patterns.ModelProvider; +import ru.betterend.patterns.Patterned; import ru.betterend.patterns.Patterns; -public class EndArmorItem extends ArmorItem implements ModelProvider { +import java.util.UUID; + +public class EndArmorItem extends ArmorItem implements Patterned { protected static final UUID[] ARMOR_MODIFIER_UUID_PER_SLOT = new UUID[] { UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), @@ -54,7 +48,7 @@ public class EndArmorItem extends ArmorItem implements ModelProvider { } @Override - public String getModelString(String name) { + public String getModelPattern(String name) { return Patterns.createItemGenerated(name); } } diff --git a/src/main/java/ru/betterend/item/EndAttribute.java b/src/main/java/ru/betterend/item/EndAttribute.java new file mode 100644 index 00000000..7ddc0bb8 --- /dev/null +++ b/src/main/java/ru/betterend/item/EndAttribute.java @@ -0,0 +1,10 @@ +package ru.betterend.item; + +import net.minecraft.world.entity.ai.attributes.Attribute; + +public class EndAttribute extends Attribute { + + public EndAttribute(String description, double value) { + super(description, value); + } +} diff --git a/src/main/java/ru/betterend/item/EndBucketItem.java b/src/main/java/ru/betterend/item/EndBucketItem.java index 9d079838..bbfff0d4 100644 --- a/src/main/java/ru/betterend/item/EndBucketItem.java +++ b/src/main/java/ru/betterend/item/EndBucketItem.java @@ -1,18 +1,19 @@ package ru.betterend.item; -import net.minecraft.world.item.BucketItem; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.FishBucketItem; import net.minecraft.world.level.material.Fluids; -import ru.betterend.patterns.ModelProvider; +import ru.betterend.patterns.Patterned; import ru.betterend.patterns.Patterns; import ru.betterend.registry.EndItems; -public class EndBucketItem extends BucketItem implements ModelProvider { - public EndBucketItem() { - super(Fluids.WATER, EndItems.makeItemSettings().stacksTo(1)); +public class EndBucketItem extends FishBucketItem implements Patterned { + public EndBucketItem(EntityType type) { + super(type, Fluids.WATER, EndItems.makeItemSettings().stacksTo(1)); } @Override - public String getModelString(String name) { + public String getModelPattern(String name) { return Patterns.createJson(Patterns.ITEM_GENERATED, name); } } diff --git a/src/main/java/ru/betterend/mixin/client/ArmorStandRendererMixin.java b/src/main/java/ru/betterend/mixin/client/ArmorStandRendererMixin.java new file mode 100644 index 00000000..d3e11b1a --- /dev/null +++ b/src/main/java/ru/betterend/mixin/client/ArmorStandRendererMixin.java @@ -0,0 +1,26 @@ +package ru.betterend.mixin.client; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.model.ArmorStandArmorModel; +import net.minecraft.client.renderer.entity.ArmorStandRenderer; +import net.minecraft.client.renderer.entity.EntityRenderDispatcher; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.world.entity.decoration.ArmorStand; +import ru.betterend.client.render.ArmoredElytraLayer; + +@Mixin(ArmorStandRenderer.class) +public abstract class ArmorStandRendererMixin extends LivingEntityRenderer { + + public ArmorStandRendererMixin(EntityRenderDispatcher entityRenderDispatcher, ArmorStandArmorModel entityModel, float f) { + super(entityRenderDispatcher, entityModel, f); + } + + @Inject(method = "*", at = @At("TAIL")) + public void be_addCustomLayer(EntityRenderDispatcher entityRenderDispatcher, CallbackInfo info) { + addLayer(new ArmoredElytraLayer<>(this)); + } +} diff --git a/src/main/java/ru/betterend/mixin/client/HumanoidMobRendererMixin.java b/src/main/java/ru/betterend/mixin/client/HumanoidMobRendererMixin.java new file mode 100644 index 00000000..cc034cd5 --- /dev/null +++ b/src/main/java/ru/betterend/mixin/client/HumanoidMobRendererMixin.java @@ -0,0 +1,26 @@ +package ru.betterend.mixin.client; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.renderer.entity.EntityRenderDispatcher; +import net.minecraft.client.renderer.entity.HumanoidMobRenderer; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.world.entity.Mob; +import ru.betterend.client.render.ArmoredElytraLayer; + +@Mixin(HumanoidMobRenderer.class) +public abstract class HumanoidMobRendererMixin> extends MobRenderer { + + public HumanoidMobRendererMixin(EntityRenderDispatcher entityRenderDispatcher, M entityModel, float f) { + super(entityRenderDispatcher, entityModel, f); + } + + @Inject(method = "*", at = @At("TAIL")) + public void be_addCustomLayer(EntityRenderDispatcher entityRenderDispatcher, M humanoidModel, float f, float g, float h, float i, CallbackInfo info) { + addLayer(new ArmoredElytraLayer<>(this)); + } +} diff --git a/src/main/java/ru/betterend/mixin/client/PlayerRendererMixin.java b/src/main/java/ru/betterend/mixin/client/PlayerRendererMixin.java index 557b0699..d435dd52 100644 --- a/src/main/java/ru/betterend/mixin/client/PlayerRendererMixin.java +++ b/src/main/java/ru/betterend/mixin/client/PlayerRendererMixin.java @@ -21,6 +21,6 @@ public abstract class PlayerRendererMixin extends LivingEntityRenderer(PlayerRenderer.class.cast(this))); + addLayer(new ArmoredElytraLayer<>(this)); } } diff --git a/src/main/java/ru/betterend/mixin/common/ArmorItemAccessor.java b/src/main/java/ru/betterend/mixin/common/ArmorItemAccessor.java deleted file mode 100644 index efd97bf5..00000000 --- a/src/main/java/ru/betterend/mixin/common/ArmorItemAccessor.java +++ /dev/null @@ -1,24 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.UUID; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import com.google.common.collect.Multimap; - -import net.minecraft.world.entity.ai.attributes.Attribute; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; -import net.minecraft.world.item.ArmorItem; - -@Mixin(ArmorItem.class) -public interface ArmorItemAccessor { - @Accessor("ARMOR_MODIFIER_UUID_PER_SLOT") - UUID[] be_getModifiers(); - - @Accessor("defaultModifiers") - Multimap be_getDefaultModifiers(); - - @Accessor("defaultModifiers") - void be_setDefaultModifiers(Multimap attributeModifiers); -} diff --git a/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java b/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java index 9733e648..d67df70b 100644 --- a/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java +++ b/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java @@ -1,13 +1,17 @@ package ru.betterend.mixin.common; +import java.lang.reflect.Field; + import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import net.minecraft.core.BlockPos; +import net.minecraft.util.BitStorage; import net.minecraft.util.Mth; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.chunk.ChunkBiomeContainer; +import ru.betterend.BetterEnd; import ru.betterend.interfaces.IBiomeArray; @Mixin(ChunkBiomeContainer.class) @@ -34,6 +38,42 @@ public class ChunkBiomeContainerMixin implements IBiomeArray { int biomeY = pos.getY() >> 2; int biomeZ = pos.getZ() >> 2; int index = be_getArrayIndex(biomeX, biomeY, biomeZ); + + if (BetterEnd.hasHydrogen()) { + try { + ChunkBiomeContainer self = (ChunkBiomeContainer) (Object) this; + BitStorage storage = be_getHydrogenStorage(self); + Biome[] palette = be_getHydrogenPalette(self); + int paletteIndex = be_getHydrogenPaletteIndex(biome, palette); + if (paletteIndex == -1) { + Biome[] newPalette = new Biome[palette.length + 1]; + System.arraycopy(palette, 0, newPalette, 0, palette.length); + paletteIndex = palette.length; + palette = newPalette; + palette[paletteIndex] = biome; + be_setHydrogenPalette(self, palette); + } + try { + storage.set(index, paletteIndex); + } + catch (Exception e) { + int size = storage.getSize(); + int bits = Mth.ceillog2(palette.length); + BitStorage newStorage = new BitStorage(bits, size); + for (int i = 0; i < size; i++) { + newStorage.set(i, storage.get(i)); + } + storage = newStorage; + storage.set(index, paletteIndex); + be_setHydrogenStorage(self, storage); + } + } + catch (Exception e) { + BetterEnd.LOGGER.warning(e.getLocalizedMessage()); + } + return; + } + biomes[index] = biome; } @@ -43,4 +83,37 @@ public class ChunkBiomeContainerMixin implements IBiomeArray { int k = biomeZ & HORIZONTAL_MASK; return j << WIDTH_BITS + WIDTH_BITS | k << WIDTH_BITS | i; } + + private Field be_getField(String name) throws Exception { + Field field = ChunkBiomeContainer.class.getDeclaredField(name); + field.setAccessible(true); + return field; + } + + private BitStorage be_getHydrogenStorage(ChunkBiomeContainer container) throws Exception { + return (BitStorage) be_getField("intArray").get(container); + } + + private Biome[] be_getHydrogenPalette(ChunkBiomeContainer container) throws Exception { + return (Biome[]) be_getField("palette").get(container); + } + + private int be_getHydrogenPaletteIndex(Biome biome, Biome[] palette) { + int index = -1; + for (int i = 0; i < palette.length; i++) { + if (palette[i] == biome) { + index = i; + break; + } + } + return index; + } + + private void be_setHydrogenPalette(ChunkBiomeContainer container, Biome[] palette) throws Exception { + be_getField("palette").set(container, palette); + } + + private void be_setHydrogenStorage(ChunkBiomeContainer container, BitStorage storage) throws Exception { + be_getField("intArray").set(container, storage); + } } diff --git a/src/main/java/ru/betterend/mixin/common/EndDragonFightMixin.java b/src/main/java/ru/betterend/mixin/common/EndDragonFightMixin.java new file mode 100644 index 00000000..43755a47 --- /dev/null +++ b/src/main/java/ru/betterend/mixin/common/EndDragonFightMixin.java @@ -0,0 +1,100 @@ +package ru.betterend.mixin.common; + +import java.util.List; + +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.google.common.collect.Lists; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.boss.enderdragon.EndCrystal; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.pattern.BlockPattern; +import net.minecraft.world.level.dimension.end.DragonRespawnAnimation; +import net.minecraft.world.level.dimension.end.EndDragonFight; +import net.minecraft.world.phys.AABB; +import ru.betterend.util.BlocksHelper; +import ru.betterend.world.generator.GeneratorOptions; + +@Mixin(EndDragonFight.class) +public class EndDragonFightMixin { + @Shadow + private DragonRespawnAnimation respawnStage; + @Shadow + private boolean dragonKilled; + @Shadow + private BlockPos portalLocation; + @Final + @Shadow + private static Logger LOGGER; + @Final + @Shadow + private ServerLevel level; + + @Shadow + private BlockPattern.BlockPatternMatch findExitPortal() { + return null; + } + + @Shadow + private void spawnExitPortal(boolean bl) {} + + @Shadow + private void respawnDragon(List list) {} + + @Inject(method = "tryRespawn", at = @At("HEAD"), cancellable = true) + private void be_tryRespawnDragon(CallbackInfo info) { + if (GeneratorOptions.replacePortal() && GeneratorOptions.hasDragonFights() && this.dragonKilled && this.respawnStage == null) { + BlockPos blockPos = portalLocation; + if (blockPos == null) { + LOGGER.debug("Tried to respawn, but need to find the portal first."); + BlockPattern.BlockPatternMatch blockPatternMatch = this.findExitPortal(); + if (blockPatternMatch == null) { + LOGGER.debug("Couldn't find a portal, so we made one."); + spawnExitPortal(true); + } + else { + LOGGER.debug("Found the exit portal & temporarily using it."); + } + + blockPos = portalLocation; + } + + List crystals = Lists.newArrayList(); + BlockPos center = GeneratorOptions.getPortalPos().above(5); + for (Direction dir : BlocksHelper.HORIZONTAL) { + BlockPos central = center.relative(dir, 4); + List crystalList = level.getEntitiesOfClass(EndCrystal.class, new AABB(central.below(10).south().west(), central.above(10).north().east())); + + int count = crystalList.size(); + for (int n = 0; n < count; n++) { + EndCrystal crystal = crystalList.get(n); + if (!level.getBlockState(crystal.blockPosition().below()).is(Blocks.BEDROCK)) { + crystalList.remove(n); + count--; + n--; + } + } + + if (crystalList.isEmpty()) { + info.cancel(); + return; + } + + crystals.addAll(crystalList); + } + + LOGGER.debug("Found all crystals, respawning dragon."); + respawnDragon(crystals); + info.cancel(); + } + } +} diff --git a/src/main/java/ru/betterend/mixin/common/EndPodiumFeatureMixin.java b/src/main/java/ru/betterend/mixin/common/EndPodiumFeatureMixin.java index e96ded09..33a1ebc6 100644 --- a/src/main/java/ru/betterend/mixin/common/EndPodiumFeatureMixin.java +++ b/src/main/java/ru/betterend/mixin/common/EndPodiumFeatureMixin.java @@ -14,6 +14,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.nbt.NbtUtils; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.levelgen.Heightmap.Types; import net.minecraft.world.level.levelgen.feature.EndPodiumFeature; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; @@ -40,7 +41,7 @@ public class EndPodiumFeatureMixin { blockPos = be_updatePos(blockPos, world); StructureTemplate structure = StructureHelper.readStructure(BetterEnd.makeID(active ? "portal/end_portal_active" : "portal/end_portal_inactive")); BlockPos size = structure.getSize(); - blockPos = blockPos.offset(-(size.getX() >> 1), -3, -(size.getZ() >> 1)); + blockPos = blockPos.offset(-(size.getX() >> 1), -1, -(size.getZ() >> 1)); structure.placeInWorldChunk(world, blockPos, new StructurePlaceSettings(), random); info.setReturnValue(true); info.cancel(); @@ -56,7 +57,7 @@ public class EndPodiumFeatureMixin { if (GeneratorOptions.useNewGenerator()) { BlockPos pos = GeneratorOptions.getPortalPos(); if (pos.equals(BlockPos.ZERO)) { - int y = world.getChunk(blockPos).getHeight(Types.WORLD_SURFACE, blockPos.getX(), blockPos.getZ()); + int y = world.getChunk(0, 0, ChunkStatus.FULL).getHeight(Types.WORLD_SURFACE, blockPos.getX(), blockPos.getZ()); if (y < 1) { y = 65; } diff --git a/src/main/java/ru/betterend/mixin/common/EndSpikeMixin.java b/src/main/java/ru/betterend/mixin/common/EndSpikeMixin.java new file mode 100644 index 00000000..8132558f --- /dev/null +++ b/src/main/java/ru/betterend/mixin/common/EndSpikeMixin.java @@ -0,0 +1,43 @@ +package ru.betterend.mixin.common; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.levelgen.feature.SpikeFeature.EndSpike; +import ru.betterend.util.WorldDataUtil; +import ru.betterend.world.generator.GeneratorOptions; + +@Mixin(EndSpike.class) +public class EndSpikeMixin { + @Final + @Shadow + private int height; + + @Inject(method = "getHeight", at = @At("HEAD"), cancellable = true) + private void be_getSpikeHeight(CallbackInfoReturnable info) { + if (!GeneratorOptions.isDirectSpikeHeight()) { + int x = getCenterX(); + int z = getCenterZ(); + String pillarID = String.format("%d_%d", x, z); + CompoundTag pillar = WorldDataUtil.getCompoundTag("pillars"); + int minY = pillar.contains(pillarID) ? pillar.getInt(pillarID) : 65; + int maxY = minY + height - 54; + info.setReturnValue(maxY); + } + } + + @Shadow + public int getCenterX() { + return 0; + } + + @Shadow + public int getCenterZ() { + return 0; + } +} diff --git a/src/main/java/ru/betterend/mixin/common/LivingEntityMixin.java b/src/main/java/ru/betterend/mixin/common/LivingEntityMixin.java index 35cc80c6..a82ff6c1 100644 --- a/src/main/java/ru/betterend/mixin/common/LivingEntityMixin.java +++ b/src/main/java/ru/betterend/mixin/common/LivingEntityMixin.java @@ -1,7 +1,22 @@ package ru.betterend.mixin.common; -import java.util.Collection; - +import net.minecraft.sounds.SoundEvent; +import net.minecraft.util.Mth; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.AttributeMap; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.animal.FlyingAnimal; +import net.minecraft.world.item.ElytraItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -10,26 +25,12 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.sounds.SoundEvent; -import net.minecraft.util.Mth; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffects; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.MoverType; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.animal.FlyingAnimal; -import net.minecraft.world.item.ElytraItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.phys.Vec3; +import ru.betterend.interfaces.MobEffectApplier; import ru.betterend.item.ArmoredElytra; +import ru.betterend.item.CrystaliteArmor; +import ru.betterend.registry.EndAttributes; + +import java.util.Collection; @Mixin(LivingEntity.class) public abstract class LivingEntityMixin extends Entity { @@ -56,8 +57,38 @@ public abstract class LivingEntityMixin extends Entity { @Shadow public abstract boolean isFallFlying(); + @Shadow + public abstract AttributeMap getAttributes(); + private Entity lastAttacker; + @Inject(method = "createLivingAttributes", at = @At("RETURN"), cancellable = true) + private static void be_addLivingAttributes(CallbackInfoReturnable info) { + EndAttributes.addLivingEntityAttributes(info.getReturnValue()); + } + + @Inject(method = "tickEffects", at = @At("HEAD")) + protected void be_applyEffects(CallbackInfo info) { + if (!level.isClientSide()) { + LivingEntity owner = LivingEntity.class.cast(this); + if (CrystaliteArmor.hasFullSet(owner)) { + CrystaliteArmor.applySetEffect(owner); + } + getArmorSlots().forEach(itemStack -> { + if (itemStack.getItem() instanceof MobEffectApplier) { + ((MobEffectApplier) itemStack.getItem()).applyEffect(owner); + } + }); + } + } + + @Inject(method = "canBeAffected", at = @At("HEAD"), cancellable = true) + public void be_canBeAffected(MobEffectInstance mobEffectInstance, CallbackInfoReturnable info) { + if (mobEffectInstance.getEffect() == MobEffects.BLINDNESS && getAttributes().getValue(EndAttributes.BLINDNESS_RESISTANCE) > 0.0) { + info.setReturnValue(false); + } + } + @Inject(method = "hurt", at = @At("HEAD")) public void be_hurt(DamageSource source, float amount, CallbackInfoReturnable info) { this.lastAttacker = source.getEntity(); @@ -80,9 +111,8 @@ public abstract class LivingEntityMixin extends Entity { if (isFlying && !onGround && !isPassenger() && !hasEffect(MobEffects.LEVITATION)) { if (ElytraItem.isFlyEnabled(itemStack)) { if ((fallFlyTicks + 1) % 20 == 0) { - itemStack.hurtAndBreak(1, LivingEntity.class.cast(this), (livingEntity) -> { - livingEntity.broadcastBreakEvent(EquipmentSlot.CHEST); - }); + itemStack.hurtAndBreak(1, LivingEntity.class.cast(this), + livingEntity -> livingEntity.broadcastBreakEvent(EquipmentSlot.CHEST)); } isFlying = true; } else { diff --git a/src/main/java/ru/betterend/mixin/common/ServerLevelMixin.java b/src/main/java/ru/betterend/mixin/common/ServerLevelMixin.java index ee5c0d69..32364b5f 100644 --- a/src/main/java/ru/betterend/mixin/common/ServerLevelMixin.java +++ b/src/main/java/ru/betterend/mixin/common/ServerLevelMixin.java @@ -4,10 +4,12 @@ import java.io.File; import java.util.List; import java.util.Locale; import java.util.concurrent.Executor; +import java.util.function.Supplier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -17,35 +19,47 @@ import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.level.CustomSpawner; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.ServerLevelData; +import net.minecraft.world.level.storage.WritableLevelData; import ru.betterend.BetterEnd; +import ru.betterend.registry.EndBiomes; +import ru.betterend.registry.EndBlocks; import ru.betterend.util.DataFixerUtil; import ru.betterend.util.WorldDataUtil; import ru.betterend.world.generator.GeneratorOptions; @Mixin(ServerLevel.class) -public class ServerLevelMixin { - private static final int DEV_VERSION = be_getVersionInt("63.63.63"); - private static final int FIX_VERSION = DEV_VERSION; - private static String lastWorld = null; +public abstract class ServerLevelMixin extends Level { + private static final int BE_DEV_VERSION = be_getVersionInt("63.63.63"); + private static final int BE_FIX_VERSION = BE_DEV_VERSION; + private static String be_lastWorld = null; + + protected ServerLevelMixin(WritableLevelData writableLevelData, ResourceKey resourceKey, DimensionType dimensionType, Supplier supplier, boolean bl, boolean bl2, long l) { + super(writableLevelData, resourceKey, dimensionType, supplier, bl, bl2, l); + } @Inject(method = "*", at = @At("TAIL")) private void be_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorageSource.LevelStorageAccess session, ServerLevelData properties, ResourceKey registryKey, DimensionType dimensionType, ChunkProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List list, boolean bl, CallbackInfo info) { - if (lastWorld != null && lastWorld.equals(session.getLevelId())) { + if (be_lastWorld != null && be_lastWorld.equals(session.getLevelId())) { return; } - lastWorld = session.getLevelId(); + be_lastWorld = session.getLevelId(); ServerLevel world = ServerLevel.class.cast(this); + EndBiomes.onWorldLoad(world.getSeed()); File dir = session.getDimensionPath(world.dimension()); if (!new File(dir, "level.dat").exists()) { dir = dir.getParentFile(); @@ -53,7 +67,7 @@ public class ServerLevelMixin { File data = new File(dir, "data/betterend_data.nbt"); ModMetadata meta = FabricLoader.getInstance().getModContainer(BetterEnd.MOD_ID).get().getMetadata(); - int version = BetterEnd.isDevEnvironment() ? DEV_VERSION : be_getVersionInt(meta.getVersion().toString()); + int version = BetterEnd.isDevEnvironment() ? BE_DEV_VERSION : be_getVersionInt(meta.getVersion().toString()); WorldDataUtil.load(data); CompoundTag root = WorldDataUtil.getRootTag(); @@ -61,7 +75,7 @@ public class ServerLevelMixin { GeneratorOptions.setPortalPos(NbtUtils.readBlockPos(root.getCompound("portal"))); if (dataVersion < version) { - if (version < FIX_VERSION) { + if (version < BE_FIX_VERSION) { DataFixerUtil.fixData(data.getParentFile()); } root.putString("version", be_getVersionString(version)); @@ -79,6 +93,23 @@ public class ServerLevelMixin { } } + @ModifyArg( + method = "tickChunk", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z" + ) + ) + private BlockState be_modifyTickState(BlockPos pos, BlockState state) { + if (state.is(Blocks.ICE)) { + ResourceLocation biome = EndBiomes.getBiomeID(getBiome(pos)); + if (biome.getNamespace().equals(BetterEnd.MOD_ID)) { + state = EndBlocks.EMERALD_ICE.defaultBlockState(); + } + } + return state; + } + private static int be_getVersionInt(String version) { if (version.isEmpty()) { return 0; diff --git a/src/main/java/ru/betterend/mixin/common/SpikeFeatureMixin.java b/src/main/java/ru/betterend/mixin/common/SpikeFeatureMixin.java index 699b1250..218a0be0 100644 --- a/src/main/java/ru/betterend/mixin/common/SpikeFeatureMixin.java +++ b/src/main/java/ru/betterend/mixin/common/SpikeFeatureMixin.java @@ -63,6 +63,7 @@ public class SpikeFeatureMixin { minY = world.getChunk(x >> 4, z >> 4).getHeight(Types.WORLD_SURFACE, x & 15, z); } + GeneratorOptions.setDirectSpikeHeight(); int maxY = minY + spike.getHeight() - 64; if (GeneratorOptions.replacePillars() && be_radiusInRange(radius)) { diff --git a/src/main/java/ru/betterend/recipe/AnvilRecipes.java b/src/main/java/ru/betterend/recipe/AnvilRecipes.java index 0e110e83..c6c09ead 100644 --- a/src/main/java/ru/betterend/recipe/AnvilRecipes.java +++ b/src/main/java/ru/betterend/recipe/AnvilRecipes.java @@ -63,5 +63,12 @@ public class AnvilRecipes { .setToolLevel(4) .setDamage(6) .build(); + AnvilRecipe.Builder.create("aeternium_forged_plate") + .setInput(EndItems.AETERNIUM_INGOT) + .setOutput(EndItems.AETERNIUM_FORGED_PLATE) + .setAnvilLevel(anvilLevel) + .setToolLevel(4) + .setDamage(6) + .build(); } } diff --git a/src/main/java/ru/betterend/recipe/CraftingRecipes.java b/src/main/java/ru/betterend/recipe/CraftingRecipes.java index 288fd16e..12fb9e86 100644 --- a/src/main/java/ru/betterend/recipe/CraftingRecipes.java +++ b/src/main/java/ru/betterend/recipe/CraftingRecipes.java @@ -101,19 +101,27 @@ public class CraftingRecipes { GridRecipe.make("petal_white_dye", Items.WHITE_DYE).setList("#").addMaterial('#', EndItems.HYDRALUX_PETAL).build(); GridRecipe.make("sweet_berry_jelly", EndItems.SWEET_BERRY_JELLY) - .setList("JWSB") - .addMaterial('J', EndItems.GELATINE) - .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) - .addMaterial('S', Items.SUGAR).addMaterial('B', Items.SWEET_BERRIES) - .build(); + .setList("JWSB") + .addMaterial('J', EndItems.GELATINE) + .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) + .addMaterial('S', Items.SUGAR).addMaterial('B', Items.SWEET_BERRIES) + .build(); GridRecipe.make("shadow_berry_jelly", EndItems.SHADOW_BERRY_JELLY) - .setList("JWSB") - .addMaterial('J', EndItems.GELATINE) - .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) - .addMaterial('S', Items.SUGAR) - .addMaterial('B', EndItems.SHADOW_BERRY_COOKED) - .build(); + .setList("JWSB") + .addMaterial('J', EndItems.GELATINE) + .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) + .addMaterial('S', Items.SUGAR) + .addMaterial('B', EndItems.SHADOW_BERRY_COOKED) + .build(); + + GridRecipe.make("shadow_berry_jelly", EndItems.BLOSSOM_BERRY_JELLY) + .setList("JWSB") + .addMaterial('J', EndItems.GELATINE) + .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) + .addMaterial('S', Items.SUGAR) + .addMaterial('B', EndItems.BLOSSOM_BERRY) + .build(); GridRecipe.make("sulphur_gunpowder", Items.GUNPOWDER).setList("SCB").addMaterial('S', EndItems.CRYSTALLINE_SULPHUR).addMaterial('C', Items.COAL, Items.CHARCOAL).addMaterial('B', Items.BONE_MEAL).build(); @@ -188,11 +196,12 @@ public class CraftingRecipes { registerHammer("diamond", Items.DIAMOND, EndItems.DIAMOND_HAMMER); GridRecipe.make("charcoal_block", EndBlocks.CHARCOAL_BLOCK).setShape("###", "###", "###").addMaterial('#', Items.CHARCOAL).build(); + GridRecipe.make("charcoal_from_block", Items.CHARCOAL).setOutputCount(9).setList("#").addMaterial('#', EndBlocks.CHARCOAL_BLOCK).build(); GridRecipe.make("end_stone_furnace", EndBlocks.END_STONE_FURNACE).setShape("###", "# #", "###").addMaterial('#', Blocks.END_STONE).build(); GridRecipe.make("filalux_lantern", EndBlocks.FILALUX_LANTERN).setShape("###", "###", "###").addMaterial('#', EndBlocks.FILALUX).build(); GridRecipe.make("silk_moth_hive", EndBlocks.SILK_MOTH_HIVE).setShape("#L#", "LML", "#L#").addMaterial('#', EndBlocks.TENANEA.planks).addMaterial('L', EndBlocks.TENANEA_LEAVES).addMaterial('M', EndItems.SILK_MOTH_MATRIX).build(); - GridRecipe.make("cave_pumpkin_pie", EndItems.CAVE_PUMPKIN_PIE).setShape(" B ", "BPB", " B ").addMaterial('P', EndBlocks.CAVE_PUMPKIN).addMaterial('B', EndItems.BLOSSOM_BERRY, EndItems.SHADOW_BERRY_RAW).build(); + GridRecipe.make("cave_pumpkin_pie", EndItems.CAVE_PUMPKIN_PIE).setShape("SBS", "BPB", "SBS").addMaterial('P', EndBlocks.CAVE_PUMPKIN).addMaterial('B', EndItems.BLOSSOM_BERRY, EndItems.SHADOW_BERRY_RAW).addMaterial('S', Items.SUGAR).build(); GridRecipe.make("cave_pumpkin_seeds", EndBlocks.CAVE_PUMPKIN_SEED).setOutputCount(4).setList("#").addMaterial('#', EndBlocks.CAVE_PUMPKIN).build(); GridRecipe.make("neon_cactus_block", EndBlocks.NEON_CACTUS_BLOCK).setShape("##", "##").addMaterial('#', EndBlocks.NEON_CACTUS).build(); @@ -202,7 +211,7 @@ public class CraftingRecipes { GridRecipe.make("tag_smith_table", Blocks.SMITHING_TABLE).setShape("II", "##", "##").addMaterial('#', ItemTags.PLANKS).addMaterial('I', EndTags.IRON_INGOTS).build(); GridRecipe.make("tag_cauldron", Blocks.CAULDRON).setShape("I I", "I I", "III").addMaterial('I', EndTags.IRON_INGOTS).build(); GridRecipe.make("tag_hopper", Blocks.HOPPER).setShape("I I", "ICI", " I ").addMaterial('I', EndTags.IRON_INGOTS).addMaterial('C', EndTags.ITEM_CHEST).build(); - GridRecipe.make("tag_piston", Blocks.PISTON).setShape("WWW", "CIC", "CDC").addMaterial('I', EndTags.IRON_INGOTS).addMaterial('D', Items.REDSTONE).addMaterial('C', Items.COBBLESTONE).build(); + GridRecipe.make("tag_piston", Blocks.PISTON).setShape("WWW", "CIC", "CDC").addMaterial('I', EndTags.IRON_INGOTS).addMaterial('D', Items.REDSTONE).addMaterial('C', Items.COBBLESTONE).addMaterial('W', ItemTags.PLANKS).build(); GridRecipe.make("tag_rail", Blocks.RAIL).setShape("I I", "ISI", "I I").addMaterial('I', EndTags.IRON_INGOTS).addMaterial('S', Items.STICK).build(); GridRecipe.make("tag_stonecutter", Blocks.STONECUTTER).setShape(" I ", "SSS").addMaterial('I', EndTags.IRON_INGOTS).addMaterial('S', Items.STONE).build(); @@ -210,6 +219,8 @@ public class CraftingRecipes { GridRecipe.make("tag_compass", Items.COMPASS).setShape(" I ", "IDI", " I ").addMaterial('I', EndTags.IRON_INGOTS).addMaterial('D', Items.REDSTONE).build(); GridRecipe.make("tag_minecart", Items.MINECART).setShape("I I", "III").addMaterial('I', EndTags.IRON_INGOTS).build(); GridRecipe.make("tag_shield", Items.SHIELD).setShape("WIW", "WWW", " W ").addMaterial('I', EndTags.IRON_INGOTS).addMaterial('W', ItemTags.PLANKS).build(); + + GridRecipe.make("sugar_from_root", Items.SUGAR).setList("###").addMaterial('#', EndItems.AMBER_ROOT_RAW).build(); } private static void registerLantern(String name, Block lantern, Block slab) { diff --git a/src/main/java/ru/betterend/recipe/SmithingRecipes.java b/src/main/java/ru/betterend/recipe/SmithingRecipes.java index 4f1117c2..6222e4a3 100644 --- a/src/main/java/ru/betterend/recipe/SmithingRecipes.java +++ b/src/main/java/ru/betterend/recipe/SmithingRecipes.java @@ -54,22 +54,22 @@ public class SmithingRecipes { SmithingTableRecipe.create("aeternium_helmet") .setResult(EndItems.AETERNIUM_HELMET) .setBase(EndBlocks.TERMINITE.helmet) - .setAddition(EndItems.AETERNIUM_INGOT) + .setAddition(EndItems.AETERNIUM_FORGED_PLATE) .build(); SmithingTableRecipe.create("aeternium_chestplate") .setResult(EndItems.AETERNIUM_CHESTPLATE) .setBase(EndBlocks.TERMINITE.chestplate) - .setAddition(EndItems.AETERNIUM_INGOT) + .setAddition(EndItems.AETERNIUM_FORGED_PLATE) .build(); SmithingTableRecipe.create("aeternium_leggings") .setResult(EndItems.AETERNIUM_LEGGINGS) .setBase(EndBlocks.TERMINITE.leggings) - .setAddition(EndItems.AETERNIUM_INGOT) + .setAddition(EndItems.AETERNIUM_FORGED_PLATE) .build(); SmithingTableRecipe.create("aeternium_boots") .setResult(EndItems.AETERNIUM_BOOTS) .setBase(EndBlocks.TERMINITE.boots) - .setAddition(EndItems.AETERNIUM_INGOT) + .setAddition(EndItems.AETERNIUM_FORGED_PLATE) .build(); SmithingTableRecipe.create("thallasium_anvil_updrade") @@ -80,7 +80,7 @@ public class SmithingRecipes { SmithingTableRecipe.create("terminite_anvil_updrade") .setResult(EndBlocks.AETERNIUM_ANVIL) .setBase(EndBlocks.TERMINITE.anvil) - .setAddition(EndBlocks.AETERNIUM_BLOCK) + .setAddition(EndItems.AETERNIUM_INGOT) .build(); SmithingTableRecipe.create("armored_elytra") diff --git a/src/main/java/ru/betterend/registry/EndAttributes.java b/src/main/java/ru/betterend/registry/EndAttributes.java new file mode 100644 index 00000000..95d2dda4 --- /dev/null +++ b/src/main/java/ru/betterend/registry/EndAttributes.java @@ -0,0 +1,21 @@ +package ru.betterend.registry; + +import net.minecraft.core.Registry; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import ru.betterend.BetterEnd; +import ru.betterend.item.EndAttribute; + +public class EndAttributes { + public final static Attribute BLINDNESS_RESISTANCE = registerAttribute("generic.blindness_resistance", 0.0, true); + + public static Attribute registerAttribute(String name, double value, boolean syncable) { + return Registry.register(Registry.ATTRIBUTE, BetterEnd.makeID(name), new EndAttribute("attribute.name." + name, value).setSyncable(syncable)); + } + + public static AttributeSupplier.Builder addLivingEntityAttributes(AttributeSupplier.Builder builder) { + return builder.add(EndAttributes.BLINDNESS_RESISTANCE); + } +} + + diff --git a/src/main/java/ru/betterend/registry/EndBiomes.java b/src/main/java/ru/betterend/registry/EndBiomes.java index cf48844a..5001dbc6 100644 --- a/src/main/java/ru/betterend/registry/EndBiomes.java +++ b/src/main/java/ru/betterend/registry/EndBiomes.java @@ -5,7 +5,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.Set; import com.google.common.collect.Lists; @@ -58,8 +57,10 @@ import ru.betterend.world.biome.land.PaintedMountainsBiome; import ru.betterend.world.biome.land.ShadowForestBiome; import ru.betterend.world.biome.land.SulphurSpringsBiome; import ru.betterend.world.biome.land.UmbrellaJungleBiome; +import ru.betterend.world.generator.BiomeMap; import ru.betterend.world.generator.BiomePicker; import ru.betterend.world.generator.BiomeType; +import ru.betterend.world.generator.GeneratorOptions; public class EndBiomes { private static final HashMap ID_MAP = Maps.newHashMap(); @@ -74,6 +75,7 @@ public class EndBiomes { private static final JsonObject EMPTY_JSON = new JsonObject(); private static Registry biomeRegistry; + private static BiomeMap caveBiomeMap; // Vanilla Land public static final EndBiome END = registerBiome(Biomes.THE_END, BiomeType.LAND, 1F); @@ -118,6 +120,12 @@ public class EndBiomes { CAVE_BIOMES.rebuild(); } + public static void onWorldLoad(long seed) { + if (caveBiomeMap == null || caveBiomeMap.getSeed() != seed) { + caveBiomeMap = new BiomeMap(seed, GeneratorOptions.getBiomeSizeCaves(), CAVE_BIOMES); + } + } + public static void mutateRegistry(Registry biomeRegistry) { EndBiomes.biomeRegistry = biomeRegistry; @@ -222,7 +230,7 @@ public class EndBiomes { * @param server - {@link MinecraftServer} */ public static void initRegistry(MinecraftServer server) { - if (biomeRegistry == null) { + if (biomeRegistry == null || biomeRegistry == BuiltinRegistries.BIOME) { biomeRegistry = server.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); } } @@ -439,8 +447,8 @@ public class EndBiomes { return biome; } - public static EndCaveBiome getCaveBiome(Random random) { - return (EndCaveBiome) CAVE_BIOMES.getBiome(random); + public static EndCaveBiome getCaveBiome(int x, int z) { + return (EndCaveBiome) caveBiomeMap.getBiome(x, z); } public static boolean hasBiome(ResourceLocation biomeID) { diff --git a/src/main/java/ru/betterend/registry/EndBlocks.java b/src/main/java/ru/betterend/registry/EndBlocks.java index aa3ee5d0..48ae11b0 100644 --- a/src/main/java/ru/betterend/registry/EndBlocks.java +++ b/src/main/java/ru/betterend/registry/EndBlocks.java @@ -148,7 +148,7 @@ public class EndBlocks { public static final Block JELLYSHROOM_CAP_PURPLE = registerBlock("jellyshroom_cap_purple", new JellyshroomCapBlock(217, 142, 255, 164, 0, 255)); public static final WoodenMaterial JELLYSHROOM = new WoodenMaterial("jellyshroom", MaterialColor.COLOR_PURPLE, MaterialColor.COLOR_LIGHT_BLUE); - public static final Block LUCERNIA_SAPLING = registerBlock("lucernia_sapling", new TenaneaSaplingBlock()); + public static final Block LUCERNIA_SAPLING = registerBlock("lucernia_sapling", new LucerniaSaplingBlock()); public static final Block LUCERNIA_LEAVES = registerBlock("lucernia_leaves", new EndLeavesBlock(LUCERNIA_SAPLING, MaterialColor.COLOR_ORANGE)); public static final Block LUCERNIA_OUTER_LEAVES = registerBlock("lucernia_outer_leaves", new FurBlock(LUCERNIA_SAPLING, 32)); public static final WoodenMaterial LUCERNIA = new WoodenMaterial("lucernia", MaterialColor.COLOR_ORANGE, MaterialColor.COLOR_ORANGE); diff --git a/src/main/java/ru/betterend/registry/EndFeatures.java b/src/main/java/ru/betterend/registry/EndFeatures.java index 30337086..708fe2cb 100644 --- a/src/main/java/ru/betterend/registry/EndFeatures.java +++ b/src/main/java/ru/betterend/registry/EndFeatures.java @@ -257,7 +257,7 @@ public class EndFeatures { addFeature(ENDER_ORE, features); addFeature(CRASHED_SHIP, features); - if (EndBiomes.getBiome(id).hasCaves()) { + if (EndBiomes.getBiome(id).hasCaves() && !EndBiomes.VOID_BIOMES.containsImmutable(id)) { addFeature(ROUND_CAVE, features); addFeature(TUNEL_CAVE, features); } diff --git a/src/main/java/ru/betterend/registry/EndItems.java b/src/main/java/ru/betterend/registry/EndItems.java index 0deb0668..388ceddf 100644 --- a/src/main/java/ru/betterend/registry/EndItems.java +++ b/src/main/java/ru/betterend/registry/EndItems.java @@ -4,6 +4,7 @@ import java.util.List; import com.google.common.collect.Lists; +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; import net.minecraft.core.BlockSource; import net.minecraft.core.Direction; @@ -21,7 +22,6 @@ import net.minecraft.world.food.FoodProperties; import net.minecraft.world.food.Foods; import net.minecraft.world.item.ArmorItem; import net.minecraft.world.item.Item; -import net.minecraft.world.item.Item.Properties; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.Rarity; @@ -33,9 +33,7 @@ import net.minecraft.world.item.Tiers; import net.minecraft.world.level.block.DispenserBlock; import ru.betterend.BetterEnd; import ru.betterend.config.Configs; -import ru.betterend.interfaces.BreakableItem; import ru.betterend.item.*; -import ru.betterend.item.ModelProviderItem; import ru.betterend.item.material.EndArmorMaterial; import ru.betterend.item.material.EndToolMaterial; import ru.betterend.item.tool.EndAxeItem; @@ -55,6 +53,7 @@ public class EndItems { public final static Item ENDER_DUST = registerItem("ender_dust"); public final static Item ENDER_SHARD = registerItem("ender_shard"); public final static Item AETERNIUM_INGOT = registerItem("aeternium_ingot"); + public final static Item AETERNIUM_FORGED_PLATE = registerItem("aeternium_forged_plate"); public final static Item END_LILY_LEAF = registerItem("end_lily_leaf"); public final static Item END_LILY_LEAF_DRIED = registerItem("end_lily_leaf_dried"); public final static Item CRYSTAL_SHARDS = registerItem("crystal_shards"); @@ -73,18 +72,21 @@ public class EndItems { public final static Item SILK_MOTH_MATRIX = registerItem("silk_moth_matrix"); // Music Discs - public final static Item MUSIC_DISC_STRANGE_AND_ALIEN = registerDisc("music_disc_strange_and_alien", 0, EndSounds.STRANGE_AND_ALIEN); + public final static Item MUSIC_DISC_STRANGE_AND_ALIEN = registerDisc("music_disc_strange_and_alien", 0, EndSounds.RECORD_STRANGE_AND_ALIEN); + public final static Item MUSIC_DISC_GRASPING_AT_STARS = registerDisc("music_disc_grasping_at_stars", 0, EndSounds.RECORD_GRASPING_AT_STARS); + public final static Item MUSIC_DISC_ENDSEEKER = registerDisc("music_disc_endseeker", 0, EndSounds.RECORD_ENDSEEKER); + public final static Item MUSIC_DISC_EO_DRACONA = registerDisc("music_disc_eo_dracona", 0, EndSounds.RECORD_EO_DRACONA); // Armor // public static final Item AETERNIUM_HELMET = registerItem("aeternium_helmet", new EndArmorItem(EndArmorMaterial.AETERNIUM, EquipmentSlot.HEAD, makeItemSettings().fireResistant())); public static final Item AETERNIUM_CHESTPLATE = registerItem("aeternium_chestplate", new EndArmorItem(EndArmorMaterial.AETERNIUM, EquipmentSlot.CHEST, makeItemSettings().fireResistant())); public static final Item AETERNIUM_LEGGINGS = registerItem("aeternium_leggings", new EndArmorItem(EndArmorMaterial.AETERNIUM, EquipmentSlot.LEGS, makeItemSettings().fireResistant())); public static final Item AETERNIUM_BOOTS = registerItem("aeternium_boots", new EndArmorItem(EndArmorMaterial.AETERNIUM, EquipmentSlot.FEET, makeItemSettings().fireResistant())); - public static final Item CRYSTALITE_HELMET = registerItem("crystalite_helmet", new EndArmorItem(EndArmorMaterial.CRYSTALITE, EquipmentSlot.HEAD, makeItemSettings().rarity(Rarity.UNCOMMON))); - public static final Item CRYSTALITE_CHESTPLATE = registerItem("crystalite_chestplate", new EndArmorItem(EndArmorMaterial.CRYSTALITE, EquipmentSlot.CHEST, makeItemSettings().rarity(Rarity.UNCOMMON))); - public static final Item CRYSTALITE_LEGGINGS = registerItem("crystalite_leggings", new EndArmorItem(EndArmorMaterial.CRYSTALITE, EquipmentSlot.LEGS, makeItemSettings().rarity(Rarity.UNCOMMON))); - public static final Item CRYSTALITE_BOOTS = registerItem("crystalite_boots", new EndArmorItem(EndArmorMaterial.CRYSTALITE, EquipmentSlot.FEET, makeItemSettings().rarity(Rarity.UNCOMMON))); - public static final Item ARMORED_ELYTRA = registerItem("elytra_armored", new ArmoredElytra("elytra_armored", AETERNIUM_INGOT, 700, 0.96D, true)); + public static final Item CRYSTALITE_HELMET = registerItem("crystalite_helmet", new CrystaliteHelmet()); + public static final Item CRYSTALITE_CHESTPLATE = registerItem("crystalite_chestplate", new CrystaliteChestplate()); + public static final Item CRYSTALITE_LEGGINGS = registerItem("crystalite_leggings", new CrystaliteLeggings()); + public static final Item CRYSTALITE_BOOTS = registerItem("crystalite_boots", new CrystaliteBoots()); + public static final Item ARMORED_ELYTRA = registerItem("elytra_armored", new ArmoredElytra("elytra_armored", EndArmorMaterial.AETERNIUM, Items.PHANTOM_MEMBRANE, 900, 0.96D, true)); // Tools // public static final TieredItem AETERNIUM_SHOVEL = registerTool("aeternium_shovel", new EndShovelItem(EndToolMaterial.AETERNIUM, 1.5F, -3.0F, makeItemSettings().fireResistant())); @@ -114,10 +116,11 @@ public class EndItems { public final static Item SHADOW_BERRY_COOKED = registerFood("shadow_berry_cooked", 6, 0.7F); public final static Item END_FISH_RAW = registerFood("end_fish_raw", Foods.SALMON); public final static Item END_FISH_COOKED = registerFood("end_fish_cooked", Foods.COOKED_SALMON); - public final static Item BUCKET_END_FISH = registerItem("bucket_end_fish", new EndBucketItem()); - public final static Item BUCKET_CUBOZOA = registerItem("bucket_cubozoa", new EndBucketItem()); - public final static Item SWEET_BERRY_JELLY = registerFood("sweet_berry_jelly", 6, 0.75F); - public final static Item SHADOW_BERRY_JELLY = registerFood("shadow_berry_jelly", 7, 0.75F, new MobEffectInstance(MobEffects.NIGHT_VISION, 400)); + public final static Item BUCKET_END_FISH = registerItem("bucket_end_fish", new EndBucketItem(EndEntities.END_FISH)); + public final static Item BUCKET_CUBOZOA = registerItem("bucket_cubozoa", new EndBucketItem(EndEntities.CUBOZOA)); + public final static Item SWEET_BERRY_JELLY = registerFood("sweet_berry_jelly", 8, 0.7F); + public final static Item SHADOW_BERRY_JELLY = registerFood("shadow_berry_jelly", 6, 0.8F, new MobEffectInstance(MobEffects.NIGHT_VISION, 400)); + public final static Item BLOSSOM_BERRY_JELLY = registerFood("blossom_berry_jelly", 8, 0.7F); public final static Item BLOSSOM_BERRY = registerFood("blossom_berry", Foods.APPLE); public final static Item AMBER_ROOT_RAW = registerFood("amber_root_raw", 2, 0.8F); public final static Item CHORUS_MUSHROOM_RAW = registerFood("chorus_mushroom_raw", 3, 0.5F); @@ -129,11 +132,11 @@ public class EndItems { public final static Item UMBRELLA_CLUSTER_JUICE = registerDrink("umbrella_cluster_juice", 5, 0.7F); public static Item registerDisc(String name, int power, SoundEvent sound) { - return registerItem(BetterEnd.makeID(name), new ModelProviderDiscItem(power, sound, makeItemSettings())); + return registerItem(BetterEnd.makeID(name), new PatternedDiscItem(power, sound, makeItemSettings())); } public static Item registerItem(String name) { - return registerItem(BetterEnd.makeID(name), new ModelProviderItem(makeItemSettings())); + return registerItem(BetterEnd.makeID(name), new PatternedItem(makeItemSettings())); } public static Item registerItem(String name, Item item) { @@ -148,9 +151,6 @@ public class EndItems { return item; } registerItem(id, item, MOD_ITEMS); - if (item instanceof BreakableItem) { - ((BreakableItem) item).registerBrokenItem(); - } return item; } @@ -222,7 +222,7 @@ public class EndItems { } public static Item registerFood(String name, FoodProperties foodComponent) { - return registerItem(name, new ModelProviderItem(makeItemSettings().food(foodComponent))); + return registerItem(name, new PatternedItem(makeItemSettings().food(foodComponent))); } public static Item registerDrink(String name) { @@ -238,12 +238,14 @@ public class EndItems { return registerDrink(name, builder.build()); } - public static Properties makeItemSettings() { - return new Item.Properties().tab(CreativeTabs.TAB_ITEMS); + public static FabricItemSettings makeItemSettings() { + FabricItemSettings properties = new FabricItemSettings(); + return (FabricItemSettings) properties.tab(CreativeTabs.TAB_ITEMS); } - public static Properties makeBlockItemSettings() { - return new Item.Properties().tab(CreativeTabs.TAB_BLOCKS); + public static FabricItemSettings makeBlockItemSettings() { + FabricItemSettings properties = new FabricItemSettings(); + return (FabricItemSettings) properties.tab(CreativeTabs.TAB_BLOCKS); } public static void register() {} diff --git a/src/main/java/ru/betterend/registry/EndSounds.java b/src/main/java/ru/betterend/registry/EndSounds.java index 7110cd17..c0ecf7eb 100644 --- a/src/main/java/ru/betterend/registry/EndSounds.java +++ b/src/main/java/ru/betterend/registry/EndSounds.java @@ -10,6 +10,7 @@ public class EndSounds { public static final SoundEvent MUSIC_WATER = register("music", "water"); public static final SoundEvent MUSIC_DARK = register("music", "dark"); public static final SoundEvent MUSIC_OPENSPACE = register("music", "openspace"); + public static final SoundEvent MUSIC_CAVES = register("music", "caves"); // Ambient public static final SoundEvent AMBIENT_FOGGY_MUSHROOMLAND = register("ambient", "foggy_mushroomland"); @@ -21,6 +22,7 @@ public class EndSounds { public static final SoundEvent AMBIENT_SULPHUR_SPRINGS = register("ambient", "sulphur_springs"); public static final SoundEvent AMBIENT_UMBRELLA_JUNGLE = register("ambient", "umbrella_jungle"); public static final SoundEvent AMBIENT_GLOWING_GRASSLANDS = register("ambient", "glowing_grasslands"); + public static final SoundEvent AMBIENT_CAVES = register("ambient", "caves"); // Entity public static final SoundEvent ENTITY_DRAGONFLY = register("entity", "dragonfly"); @@ -29,7 +31,10 @@ public class EndSounds { public static final SoundEvent ENTITY_SHADOW_WALKER_DEATH = register("entity", "shadow_walker_death"); // Records - public static final SoundEvent STRANGE_AND_ALIEN = register("record", "strange_and_alien"); + public static final SoundEvent RECORD_STRANGE_AND_ALIEN = register("record", "strange_and_alien"); + public static final SoundEvent RECORD_GRASPING_AT_STARS = register("record", "grasping_at_stars"); + public static final SoundEvent RECORD_ENDSEEKER = register("record", "endseeker"); + public static final SoundEvent RECORD_EO_DRACONA = register("record", "eo_dracona"); public static void register() {} diff --git a/src/main/java/ru/betterend/registry/EndTags.java b/src/main/java/ru/betterend/registry/EndTags.java index 92aaedb5..a429015b 100644 --- a/src/main/java/ru/betterend/registry/EndTags.java +++ b/src/main/java/ru/betterend/registry/EndTags.java @@ -151,7 +151,7 @@ public class EndTags { TagHelper.addTag(EndTags.DRAGON_IMMUNE, EndBlocks.ENDER_ORE, EndBlocks.ETERNAL_PEDESTAL, EndBlocks.FLAVOLITE_RUNED_ETERNAL, EndBlocks.FLAVOLITE_RUNED); TagHelper.addTag(EndTags.IRON_INGOTS, Items.IRON_INGOT); - TagHelper.addTag(EndTags.IRON_INGOTS, EndBlocks.TERMINITE.ingot); + TagHelper.addTag(EndTags.IRON_INGOTS, EndBlocks.THALLASIUM.ingot); } public static void addSurfaceBlock(Block block) { diff --git a/src/main/java/ru/betterend/util/LootTableUtil.java b/src/main/java/ru/betterend/util/LootTableUtil.java index c3867a2c..1b8cb09d 100644 --- a/src/main/java/ru/betterend/util/LootTableUtil.java +++ b/src/main/java/ru/betterend/util/LootTableUtil.java @@ -19,7 +19,15 @@ public class LootTableUtil { builder.setRolls(RandomValueBounds.between(0, 5)); builder.withCondition(LootItemRandomChanceCondition.randomChance(0.5f).build()); builder.withEntry(LootItem.lootTableItem(Items.GHAST_TEAR).build()); + supplier.withPool(builder); + + builder = FabricLootPoolBuilder.builder(); + builder.setRolls(RandomValueBounds.between(0, 5)); + builder.withCondition(LootItemRandomChanceCondition.randomChance(0.1f).build()); builder.withEntry(LootItem.lootTableItem(EndItems.MUSIC_DISC_STRANGE_AND_ALIEN).build()); + builder.withEntry(LootItem.lootTableItem(EndItems.MUSIC_DISC_GRASPING_AT_STARS).build()); + builder.withEntry(LootItem.lootTableItem(EndItems.MUSIC_DISC_ENDSEEKER).build()); + builder.withEntry(LootItem.lootTableItem(EndItems.MUSIC_DISC_EO_DRACONA).build()); supplier.withPool(builder); } }); diff --git a/src/main/java/ru/betterend/world/biome/BiomeDefinition.java b/src/main/java/ru/betterend/world/biome/BiomeDefinition.java index 0da55eba..585ba53b 100644 --- a/src/main/java/ru/betterend/world/biome/BiomeDefinition.java +++ b/src/main/java/ru/betterend/world/biome/BiomeDefinition.java @@ -68,6 +68,7 @@ public class BiomeDefinition { private float genChance = 1F; private boolean hasCaves = true; private boolean isCaveBiome = false; + private float temperature = 1F; private ConfiguredSurfaceBuilder surface; @@ -117,6 +118,11 @@ public class BiomeDefinition { this.depth = depth; return this; } + + public BiomeDefinition setTemperature(float temperature) { + this.temperature = temperature; + return this; + } public BiomeDefinition addMobSpawn(EntityType type, int weight, int minGroupSize, int maxGroupSize) { ResourceLocation eID = Registry.ENTITY_TYPE.getKey(type); @@ -263,7 +269,7 @@ public class BiomeDefinition { .biomeCategory(isCaveBiome ? BiomeCategory.NONE : BiomeCategory.THEEND) .depth(depth) .scale(0.2F) - .temperature(2.0F) + .temperature(temperature) .downfall(0.0F) .specialEffects(effects.build()) .mobSpawnSettings(spawnSettings.build()) diff --git a/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java b/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java index f90945e3..55fc7b74 100644 --- a/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java +++ b/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java @@ -11,9 +11,11 @@ public class BiomeIceStarfield extends EndBiome { public BiomeIceStarfield() { super(new BiomeDefinition("ice_starfield") .setFogColor(224, 245, 254) + .setTemperature(0F) .setFogDensity(2.2F) .setFoliageColor(193, 244, 244) .setGenChance(0.25F) + .setCaves(false) .setParticles(EndParticles.SNOWFLAKE, 0.002F) .addStructureFeature(EndStructures.GIANT_ICE_STAR) .addFeature(EndFeatures.ICE_STAR) diff --git a/src/main/java/ru/betterend/world/biome/cave/EmptyAuroraCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/EmptyAuroraCaveBiome.java index 93fb0624..eb5d1120 100644 --- a/src/main/java/ru/betterend/world/biome/cave/EmptyAuroraCaveBiome.java +++ b/src/main/java/ru/betterend/world/biome/cave/EmptyAuroraCaveBiome.java @@ -2,7 +2,6 @@ package ru.betterend.world.biome.cave; import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; import ru.betterend.world.biome.BiomeDefinition; public class EmptyAuroraCaveBiome extends EndCaveBiome { @@ -12,7 +11,6 @@ public class EmptyAuroraCaveBiome extends EndCaveBiome { .setFogDensity(2.0F) .setPlantsColor(108, 25, 46) .setWaterAndFogColor(186, 77, 237) - .setMusic(EndSounds.MUSIC_FOREST) .setParticles(EndParticles.GLOWING_SPHERE, 0.001F)); this.addFloorFeature(EndFeatures.BIG_AURORA_CRYSTAL, 1); diff --git a/src/main/java/ru/betterend/world/biome/cave/EmptyEndCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/EmptyEndCaveBiome.java index 4976fed1..9ed57309 100644 --- a/src/main/java/ru/betterend/world/biome/cave/EmptyEndCaveBiome.java +++ b/src/main/java/ru/betterend/world/biome/cave/EmptyEndCaveBiome.java @@ -1,15 +1,11 @@ package ru.betterend.world.biome.cave; import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndSounds; import ru.betterend.world.biome.BiomeDefinition; public class EmptyEndCaveBiome extends EndCaveBiome { public EmptyEndCaveBiome() { - super(new BiomeDefinition("empty_end_cave") - .setFogDensity(2.0F) - .setMusic(EndSounds.MUSIC_FOREST)); - + super(new BiomeDefinition("empty_end_cave").setFogDensity(2.0F)); this.addFloorFeature(EndFeatures.END_STONE_STALAGMITE, 1); this.addCeilFeature(EndFeatures.END_STONE_STALACTITE, 1); } diff --git a/src/main/java/ru/betterend/world/biome/cave/EmptySmaragdantCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/EmptySmaragdantCaveBiome.java index ed5ed762..3e262482 100644 --- a/src/main/java/ru/betterend/world/biome/cave/EmptySmaragdantCaveBiome.java +++ b/src/main/java/ru/betterend/world/biome/cave/EmptySmaragdantCaveBiome.java @@ -2,7 +2,6 @@ package ru.betterend.world.biome.cave; import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; import ru.betterend.world.biome.BiomeDefinition; public class EmptySmaragdantCaveBiome extends EndCaveBiome { @@ -12,7 +11,6 @@ public class EmptySmaragdantCaveBiome extends EndCaveBiome { .setFogDensity(2.0F) .setPlantsColor(0, 131, 145) .setWaterAndFogColor(31, 167, 212) - .setMusic(EndSounds.MUSIC_FOREST) .setParticles(EndParticles.SMARAGDANT, 0.001F)); this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL, 1); diff --git a/src/main/java/ru/betterend/world/biome/cave/EndCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/EndCaveBiome.java index 3f25a5bb..a90c8dfd 100644 --- a/src/main/java/ru/betterend/world/biome/cave/EndCaveBiome.java +++ b/src/main/java/ru/betterend/world/biome/cave/EndCaveBiome.java @@ -7,6 +7,7 @@ import net.minecraft.world.entity.ai.behavior.WeightedList; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.feature.Feature; import ru.betterend.registry.EndBiomes; +import ru.betterend.registry.EndSounds; import ru.betterend.world.biome.BiomeDefinition; import ru.betterend.world.biome.EndBiome; import ru.betterend.world.features.EndFeature; @@ -26,6 +27,8 @@ public class EndCaveBiome extends EndBiome { new CaveChunkPopulatorFeature(() -> (EndCaveBiome) EndBiomes.getBiome(definition.getID())) ); definition.addFeature(feature).setCaveBiome(); + definition.setMusic(EndSounds.MUSIC_CAVES); + definition.setLoop(EndSounds.AMBIENT_CAVES); return definition; } diff --git a/src/main/java/ru/betterend/world/biome/cave/JadeCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/JadeCaveBiome.java index d399695d..f50d2bcc 100644 --- a/src/main/java/ru/betterend/world/biome/cave/JadeCaveBiome.java +++ b/src/main/java/ru/betterend/world/biome/cave/JadeCaveBiome.java @@ -5,7 +5,6 @@ import net.minecraft.util.Mth; import net.minecraft.world.level.block.state.BlockState; import ru.betterend.noise.OpenSimplexNoise; import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndSounds; import ru.betterend.world.biome.BiomeDefinition; public class JadeCaveBiome extends EndCaveBiome { @@ -18,7 +17,6 @@ public class JadeCaveBiome extends EndCaveBiome { .setFogColor(118, 150, 112) .setFogDensity(2.0F) .setWaterAndFogColor(95, 223, 255) - .setMusic(EndSounds.MUSIC_FOREST) ); JADE[0] = EndBlocks.VIRID_JADESTONE.stone.defaultBlockState(); JADE[1] = EndBlocks.AZURE_JADESTONE.stone.defaultBlockState(); diff --git a/src/main/java/ru/betterend/world/biome/cave/LushAuroraCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/LushAuroraCaveBiome.java index 52ff7f1b..d8c3c1e2 100644 --- a/src/main/java/ru/betterend/world/biome/cave/LushAuroraCaveBiome.java +++ b/src/main/java/ru/betterend/world/biome/cave/LushAuroraCaveBiome.java @@ -7,7 +7,6 @@ import ru.betterend.blocks.BlockProperties.TripleShape; import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; import ru.betterend.world.biome.BiomeDefinition; public class LushAuroraCaveBiome extends EndCaveBiome { @@ -17,7 +16,6 @@ public class LushAuroraCaveBiome extends EndCaveBiome { .setFogDensity(2.0F) .setPlantsColor(108, 25, 46) .setWaterAndFogColor(186, 77, 237) - .setMusic(EndSounds.MUSIC_FOREST) .setParticles(EndParticles.GLOWING_SPHERE, 0.001F) .setSurface(EndBlocks.CAVE_MOSS)); diff --git a/src/main/java/ru/betterend/world/biome/cave/LushSmaragdantCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/LushSmaragdantCaveBiome.java index c9a40749..0997c6fa 100644 --- a/src/main/java/ru/betterend/world/biome/cave/LushSmaragdantCaveBiome.java +++ b/src/main/java/ru/betterend/world/biome/cave/LushSmaragdantCaveBiome.java @@ -3,7 +3,6 @@ package ru.betterend.world.biome.cave; import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; import ru.betterend.world.biome.BiomeDefinition; public class LushSmaragdantCaveBiome extends EndCaveBiome { @@ -13,7 +12,6 @@ public class LushSmaragdantCaveBiome extends EndCaveBiome { .setFogDensity(2.0F) .setPlantsColor(0, 131, 145) .setWaterAndFogColor(31, 167, 212) - .setMusic(EndSounds.MUSIC_FOREST) .setParticles(EndParticles.SMARAGDANT, 0.001F) .setSurface(EndBlocks.CAVE_MOSS)); diff --git a/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java b/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java index 08e502a1..238520a5 100644 --- a/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java +++ b/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java @@ -13,7 +13,6 @@ public class PaintedMountainsBiome extends EndBiome { super(new BiomeDefinition("painted_mountains") .setFogColor(226, 239, 168) .setFogDensity(2) - .setCaves(false) .setWaterAndFogColor(192, 180, 131) .setMusic(EndSounds.MUSIC_OPENSPACE) .setLoop(EndSounds.AMBIENT_DUST_WASTELANDS) diff --git a/src/main/java/ru/betterend/world/features/terrain/ObsidianPillarBasementFeature.java b/src/main/java/ru/betterend/world/features/terrain/ObsidianPillarBasementFeature.java index 66d1bc3d..91826d46 100644 --- a/src/main/java/ru/betterend/world/features/terrain/ObsidianPillarBasementFeature.java +++ b/src/main/java/ru/betterend/world/features/terrain/ObsidianPillarBasementFeature.java @@ -26,18 +26,15 @@ import ru.betterend.world.features.DefaultFeature; public class ObsidianPillarBasementFeature extends DefaultFeature { @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - pos = getPosOnSurface(world, - new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16))); + public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { + pos = getPosOnSurface(world, new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16))); if (!world.getBlockState(pos.below(5)).is(EndTags.GEN_TERRAIN)) { return false; } float height = MHelper.randRange(10F, 35F, random); float radius = MHelper.randRange(2F, 5F, random); - SDF pillar = new SDFCappedCone().setRadius1(radius).setRadius2(radius).setHeight(height * 0.5F) - .setBlock(Blocks.OBSIDIAN); + SDF pillar = new SDFCappedCone().setRadius1(radius).setRadius2(radius).setHeight(height * 0.5F).setBlock(Blocks.OBSIDIAN); pillar = new SDFTranslate().setTranslate(0, height * 0.5F - 3, 0).setSource(pillar); SDF cut = new SDFFlatland().setBlock(Blocks.OBSIDIAN); OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); @@ -52,7 +49,6 @@ public class ObsidianPillarBasementFeature extends DefaultFeature { vec = MHelper.randomHorizontal(random); angle = random.nextFloat() * 0.2F; pillar = new SDFRotation().setRotation(vec, angle).setSource(pillar); - BlockState mossy = EndBlocks.MOSSY_OBSIDIAN.defaultBlockState(); pillar.addPostProcess((info) -> { if (info.getStateUp().isAir() && random.nextFloat() > 0.1F) { @@ -60,8 +56,7 @@ public class ObsidianPillarBasementFeature extends DefaultFeature { } return info.getState(); }).setReplaceFunction((state) -> { - return state.getMaterial().isReplaceable() || state.is(EndTags.GEN_TERRAIN) - || state.getMaterial().equals(Material.PLANT); + return state.getMaterial().isReplaceable() || state.is(EndTags.GEN_TERRAIN) || state.getMaterial().equals(Material.PLANT); }).fillRecursive(world, pos); return true; diff --git a/src/main/java/ru/betterend/world/features/terrain/caves/EndCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/caves/EndCaveFeature.java index 9af35a84..1e789d6c 100644 --- a/src/main/java/ru/betterend/world/features/terrain/caves/EndCaveFeature.java +++ b/src/main/java/ru/betterend/world/features/terrain/caves/EndCaveFeature.java @@ -51,7 +51,7 @@ public abstract class EndCaveFeature extends DefaultFeature { return false; } - EndCaveBiome biome = EndBiomes.getCaveBiome(random); + EndCaveBiome biome = EndBiomes.getCaveBiome(pos.getX(), pos.getZ()); Set caveBlocks = generate(world, center, radius, random); if (!caveBlocks.isEmpty()) { if (biome != null) { @@ -88,7 +88,9 @@ public abstract class EndCaveFeature extends DefaultFeature { protected void placeFloor(WorldGenLevel world, EndCaveBiome biome, Set floorPositions, Random random, BlockState surfaceBlock) { float density = biome.getFloorDensity(); floorPositions.forEach((pos) -> { - BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); + if (!surfaceBlock.is(Blocks.END_STONE)) { + BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); + } if (density > 0 && random.nextFloat() <= density) { Feature feature = biome.getFloorFeature(random); if (feature != null) { diff --git a/src/main/java/ru/betterend/world/features/terrain/caves/TunelCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/caves/TunelCaveFeature.java index c414c6a0..023e2fd2 100644 --- a/src/main/java/ru/betterend/world/features/terrain/caves/TunelCaveFeature.java +++ b/src/main/java/ru/betterend/world/features/terrain/caves/TunelCaveFeature.java @@ -1,16 +1,21 @@ package ru.betterend.world.features.terrain.caves; +import java.util.Map; import java.util.Random; import java.util.Set; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; import net.minecraft.util.Mth; import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap.Types; import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import ru.betterend.noise.OpenSimplexNoise; @@ -20,12 +25,14 @@ import ru.betterend.util.BlocksHelper; import ru.betterend.world.biome.cave.EndCaveBiome; public class TunelCaveFeature extends EndCaveFeature { - private static final OpenSimplexNoise BIOME_NOISE_X = new OpenSimplexNoise("biome_noise_x".hashCode()); - private static final OpenSimplexNoise BIOME_NOISE_Z = new OpenSimplexNoise("biome_noise_z".hashCode()); - private Set generate(WorldGenLevel world, BlockPos center, Random random) { - int x1 = (center.getX() >> 4) << 4; - int z1 = (center.getZ() >> 4) << 4; + int cx = center.getX() >> 4; + int cz = center.getZ() >> 4; + if ((long) cx * (long) cx + (long) cz + (long) cz < 256) { + return Sets.newHashSet(); + } + int x1 = cx << 4; + int z1 = cz << 4; int x2 = x1 + 16; int z2 = z1 + 16; int y2 = world.getHeight(); @@ -43,12 +50,19 @@ public class TunelCaveFeature extends EndCaveFeature { for (int y = 0; y < y2; y++) { pos.setY(y); float val = Mth.abs((float) noiseH.eval(x * 0.02, y * 0.01, z * 0.02)); - float vert = Mth.sin((y + (float) noiseV.eval(x * 0.01, z * 0.01) * 20) * 0.1F) * 0.9F;//Mth.abs(y - 50 + (float) noiseV.eval(x * 0.01, z * 0.01) * 20) * 0.1F; + float vert = Mth.sin((y + (float) noiseV.eval(x * 0.01, z * 0.01) * 20) * 0.1F) * 0.9F; float dist = (float) noiseD.eval(x * 0.1, y * 0.1, z * 0.1) * 0.12F; vert *= vert; - if (val + vert + dist < 0.15 && world.getBlockState(pos).is(EndTags.GEN_TERRAIN)) { + if (val + vert + dist < 0.15 && world.getBlockState(pos).is(EndTags.GEN_TERRAIN) && noWaterNear(world, pos)) { BlocksHelper.setWithoutUpdate(world, pos, AIR); positions.add(pos.immutable()); + int height = world.getHeight(Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); + if (height < pos.getY() + 4) { + while (pos.getY() < height && noWaterNear(world, pos)) { + pos.setY(pos.getY() + 1); + BlocksHelper.setWithoutUpdate(world, pos, AIR); + } + } } } } @@ -56,6 +70,23 @@ public class TunelCaveFeature extends EndCaveFeature { return positions; } + private boolean noWaterNear(WorldGenLevel world, BlockPos pos) { + BlockPos above1 = pos.above(); + BlockPos above2 = pos.above(2); + if (!world.getFluidState(above1).isEmpty() || !world.getFluidState(above2).isEmpty()) { + return false; + } + for (Direction dir: BlocksHelper.HORIZONTAL) { + if (!world.getFluidState(above1.relative(dir)).isEmpty()) { + return false; + } + if (!world.getFluidState(above2.relative(dir)).isEmpty()) { + return false; + } + } + return true; + } + @Override public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { if (pos.getX() * pos.getX() + pos.getZ() * pos.getZ() <= 2500) { @@ -65,50 +96,63 @@ public class TunelCaveFeature extends EndCaveFeature { if (biomeMissingCaves(world, pos)) { return false; } - - EndCaveBiome biome = EndBiomes.getCaveBiome(random); - Set preCaveBlocks = generate(world, pos, random); - Set caveBlocks = mutateBlocks(preCaveBlocks); - if (!caveBlocks.isEmpty()) { - if (biome != null) { - setBiomes(world, biome, caveBlocks); - Set floorPositions = Sets.newHashSet(); - Set ceilPositions = Sets.newHashSet(); - MutableBlockPos mut = new MutableBlockPos(); - caveBlocks.forEach((bpos) -> { - mut.set(bpos); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - mut.setY(bpos.getY() - 1); - if (world.getBlockState(mut).is(EndTags.GEN_TERRAIN)) { - floorPositions.add(mut.immutable()); - } - mut.setY(bpos.getY() + 1); - if (world.getBlockState(mut).is(EndTags.GEN_TERRAIN)) { - ceilPositions.add(mut.immutable()); - } - } - }); - BlockState surfaceBlock = biome.getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - placeFloor(world, biome, floorPositions, random, surfaceBlock); - placeCeil(world, biome, ceilPositions, random); - placeWalls(world, biome, caveBlocks, random); - } - fixBlocks(world, preCaveBlocks); + + Set caveBlocks = generate(world, pos, random); + if (caveBlocks.isEmpty()) { + return false; } - - return true; - } - - private Set mutateBlocks(Set caveBlocks) { - Set result = Sets.newHashSet(); - caveBlocks.forEach(pos -> { - int dx = pos.getX() + (int) (BIOME_NOISE_X.eval(pos.getX() * 0.2, pos.getZ() * 0.2) * 5); - int dz = pos.getZ() + (int) (BIOME_NOISE_Z.eval(pos.getX() * 0.2, pos.getZ() * 0.2) * 5); - if ((dx >> 4) == (pos.getX() >> 4) && (dz >> 4) == (pos.getZ() >> 4)) { - result.add(pos); + + Map> floorSets = Maps.newHashMap(); + Map> ceilSets = Maps.newHashMap(); + MutableBlockPos mut = new MutableBlockPos(); + Set remove = Sets.newHashSet(); + caveBlocks.forEach((bpos) -> { + mut.set(bpos); + EndCaveBiome bio = EndBiomes.getCaveBiome(bpos.getX(), bpos.getZ()); + int height = world.getHeight(Types.WORLD_SURFACE, bpos.getX(), bpos.getZ()); + if (mut.getY() >= height) { + remove.add(bpos); + } + else if (world.getBlockState(mut).getMaterial().isReplaceable()) { + mut.setY(bpos.getY() - 1); + if (world.getBlockState(mut).is(EndTags.GEN_TERRAIN)) { + Set floorPositions = floorSets.get(bio); + if (floorPositions == null) { + floorPositions = Sets.newHashSet(); + floorSets.put(bio, floorPositions); + } + floorPositions.add(mut.immutable()); + } + mut.setY(bpos.getY() + 1); + if (world.getBlockState(mut).is(EndTags.GEN_TERRAIN)) { + Set ceilPositions = ceilSets.get(bio); + if (ceilPositions == null) { + ceilPositions = Sets.newHashSet(); + ceilSets.put(bio, ceilPositions); + } + ceilPositions.add(mut.immutable()); + } + setBiome(world, bpos, bio); } }); - return result; + caveBlocks.removeAll(remove); + + if (caveBlocks.isEmpty()) { + return true; + } + + floorSets.forEach((biome, floorPositions) -> { + BlockState surfaceBlock = biome.getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); + placeFloor(world, biome, floorPositions, random, surfaceBlock); + }); + ceilSets.forEach((biome, ceilPositions) -> { + placeCeil(world, biome, ceilPositions, random); + }); + EndCaveBiome biome = EndBiomes.getCaveBiome(pos.getX(), pos.getZ()); + placeWalls(world, biome, caveBlocks, random); + fixBlocks(world, caveBlocks); + + return true; } @Override @@ -120,7 +164,9 @@ public class TunelCaveFeature extends EndCaveFeature { protected void placeFloor(WorldGenLevel world, EndCaveBiome biome, Set floorPositions, Random random, BlockState surfaceBlock) { float density = biome.getFloorDensity() * 0.2F; floorPositions.forEach((pos) -> { - BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); + if (!surfaceBlock.is(Blocks.END_STONE)) { + BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); + } if (density > 0 && random.nextFloat() <= density) { Feature feature = biome.getFloorFeature(random); if (feature != null) { diff --git a/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java b/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java index ff86b727..167035c1 100644 --- a/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java +++ b/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java @@ -95,6 +95,9 @@ public class BetterEndBiomeSource extends BiomeSource { endBiome = mapLand.getBiome(biomeX << 2, biomeZ << 2); } else { + if (!GeneratorOptions.noRingVoid() && dist <= 65536L) { + return barrens; + } endBiome = mapVoid.getBiome(biomeX << 2, biomeZ << 2); } } diff --git a/src/main/java/ru/betterend/world/generator/BiomeMap.java b/src/main/java/ru/betterend/world/generator/BiomeMap.java index 1aa8c3c8..6ba91b73 100644 --- a/src/main/java/ru/betterend/world/generator/BiomeMap.java +++ b/src/main/java/ru/betterend/world/generator/BiomeMap.java @@ -20,6 +20,7 @@ public class BiomeMap { private final OpenSimplexNoise noiseX; private final OpenSimplexNoise noiseZ; private final BiomePicker picker; + private final long seed; public BiomeMap(long seed, int size, BiomePicker picker) { maps.clear(); @@ -30,6 +31,11 @@ public class BiomeMap { depth = (int) Math.ceil(Math.log(size) / Math.log(2)) - 2; this.size = 1 << depth; this.picker = picker; + this.seed = seed; + } + + public long getSeed() { + return seed; } public void clearCache() { diff --git a/src/main/java/ru/betterend/world/generator/GeneratorOptions.java b/src/main/java/ru/betterend/world/generator/GeneratorOptions.java index 5c7f6c2d..346dd2a7 100644 --- a/src/main/java/ru/betterend/world/generator/GeneratorOptions.java +++ b/src/main/java/ru/betterend/world/generator/GeneratorOptions.java @@ -7,6 +7,7 @@ import ru.betterend.config.Configs; public class GeneratorOptions { private static int biomeSizeLand; private static int biomeSizeVoid; + private static int biomeSizeCaves; private static boolean hasPortal; private static boolean hasPillars; private static boolean hasDragonFights; @@ -28,10 +29,12 @@ public class GeneratorOptions { private static boolean replacePillars; private static long islandDistBlock; private static int islandDistChunk; + private static boolean directSpikeHeight; public static void init() { biomeSizeLand = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeLand", 256); biomeSizeVoid = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeVoid", 256); + biomeSizeCaves = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeCaves", 32); hasPortal = Configs.GENERATOR_CONFIG.getBoolean("portal", "hasPortal", true); hasPillars = Configs.GENERATOR_CONFIG.getBoolean("spikes", "hasSpikes", true); hasDragonFights = Configs.GENERATOR_CONFIG.getBooleanRoot("hasDragonFights", true); @@ -66,6 +69,10 @@ public class GeneratorOptions { public static int getBiomeSizeVoid() { return Mth.clamp(biomeSizeVoid, 1, 8192); } + + public static int getBiomeSizeCaves() { + return Mth.clamp(biomeSizeCaves, 1, 8192); + } public static boolean hasPortal() { return hasPortal; @@ -142,4 +149,14 @@ public class GeneratorOptions { public static int getIslandDistChunk() { return islandDistChunk; } + + public static void setDirectSpikeHeight() { + directSpikeHeight = true; + } + + public static boolean isDirectSpikeHeight() { + boolean height = directSpikeHeight; + directSpikeHeight = false; + return height; + } } diff --git a/src/main/java/ru/betterend/world/structures/features/EternalPortalStructure.java b/src/main/java/ru/betterend/world/structures/features/EternalPortalStructure.java index 5cb3dcc9..700dc03a 100644 --- a/src/main/java/ru/betterend/world/structures/features/EternalPortalStructure.java +++ b/src/main/java/ru/betterend/world/structures/features/EternalPortalStructure.java @@ -26,25 +26,25 @@ public class EternalPortalStructure extends FeatureBaseStructure { private static final StructureTemplate STRUCTURE = StructureHelper.readStructure(STRUCTURE_ID); @Override - protected boolean shouldStartAt(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long worldSeed, WorldgenRandom chunkRandom, int chunkX, int chunkZ, Biome biome, ChunkPos chunkPos, NoneFeatureConfiguration featureConfig) { - long x = chunkPos.x; - long z = chunkPos.z; - if (x * x + z * z < 10000) { + protected boolean isFeatureChunk(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long worldSeed, WorldgenRandom chunkRandom, int chunkX, int chunkZ, Biome biome, ChunkPos chunkPos, NoneFeatureConfiguration featureConfig) { + long x = (long) chunkPos.x * (long) chunkPos.x; + long z = (long) chunkPos.z * (long) chunkPos.z; + if (x + z < 1024L) { return false; } if (chunkGenerator.getBaseHeight((chunkX << 4) | 8, (chunkZ << 4) | 8, Heightmap.Types.WORLD_SURFACE_WG) < 10) { return false; } - return super.shouldStartAt(chunkGenerator, biomeSource, worldSeed, chunkRandom, chunkX, chunkZ, biome, chunkPos, featureConfig); + return super.isFeatureChunk(chunkGenerator, biomeSource, worldSeed, chunkRandom, chunkX, chunkZ, biome, chunkPos, featureConfig); } @Override public StructureFeature.StructureStartFactory getStartFactory() { - return SDFStructureStart::new; + return PortalStructureStart::new; } - public static class SDFStructureStart extends StructureStart { - public SDFStructureStart(StructureFeature feature, int chunkX, int chunkZ, BoundingBox box, int references, long seed) { + public static class PortalStructureStart extends StructureStart { + public PortalStructureStart(StructureFeature feature, int chunkX, int chunkZ, BoundingBox box, int references, long seed) { super(feature, chunkX, chunkZ, box, references, seed); } diff --git a/src/main/java/ru/betterend/world/structures/features/FeatureBaseStructure.java b/src/main/java/ru/betterend/world/structures/features/FeatureBaseStructure.java index a3986e2f..219ec6f5 100644 --- a/src/main/java/ru/betterend/world/structures/features/FeatureBaseStructure.java +++ b/src/main/java/ru/betterend/world/structures/features/FeatureBaseStructure.java @@ -21,7 +21,8 @@ public abstract class FeatureBaseStructure extends StructureFeature= 20; } diff --git a/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java b/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java index 9cf35d99..8131efac 100644 --- a/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java +++ b/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java @@ -48,7 +48,7 @@ public class NBTPiece extends BasePiece { @Override protected void addAdditionalSaveData(CompoundTag tag) { - tag.putString("id", structureID.toString()); + tag.putString("structureID", structureID.toString()); tag.putInt("rotation", rotation.ordinal()); tag.putInt("mirror", mirror.ordinal()); tag.putInt("erosion", erosion); @@ -58,7 +58,7 @@ public class NBTPiece extends BasePiece { @Override protected void fromNbt(CompoundTag tag) { - structureID = new ResourceLocation(tag.getString("id")); + structureID = new ResourceLocation(tag.getString("structureID")); rotation = Rotation.values()[tag.getInt("rotation")]; mirror = Mirror.values()[tag.getInt("mirror")]; erosion = tag.getInt("erosion"); diff --git a/src/main/resources/assets/betterend/lang/en_us.json b/src/main/resources/assets/betterend/lang/en_us.json index 5aab07ea..7c4b8d02 100644 --- a/src/main/resources/assets/betterend/lang/en_us.json +++ b/src/main/resources/assets/betterend/lang/en_us.json @@ -506,7 +506,7 @@ "block.betterend.vent_bubble_column": "Vent Bubble Column", "block.betterend.respawn_obelisk": "Respawn Obelisk", "message.betterend.set_spawn": "\u00A7b\u00A7lYour spawn point is set here", - "message.betterend.fail_spawn": "\u00A7c\u00A7lYour need to hold 6 Amber Gems to set your spawn point", + "message.betterend.fail_spawn": "\u00A7c\u00A7lYou need to hold 6 Amber Gems to set your spawn point", "block.betterend.dragon_tree_composter": "Dragon Tree Composter", "block.betterend.end_lotus_composter": "End Lotus Composter", @@ -821,6 +821,12 @@ "item.betterend.music_disc_strange_and_alien": "§bMusic Disc§r", "item.betterend.music_disc_strange_and_alien.desc": "§5Firel§r - §fStrange And Alien§r", + "item.betterend.music_disc_grasping_at_stars": "§bMusic Disc§r", + "item.betterend.music_disc_grasping_at_stars.desc": "§5Firel§r - §fGrasping At Stars§r", + "item.betterend.music_disc_endseeker": "§bMusic Disc§r", + "item.betterend.music_disc_endseeker.desc": "§5Firel§r - §fEndseeker§r", + "item.betterend.music_disc_eo_dracona": "§bMusic Disc§r", + "item.betterend.music_disc_eo_dracona.desc": "§5Firel§r - §fEo Dracona§r", "block.betterend.hydralux_petal_block_amber": "Amber Petal Block", "block.betterend.hydralux_petal_block_beige": "Beige Petal Block", @@ -855,5 +861,15 @@ "block.betterend.neon_cactus_block": "Neon Cactus Block", "block.betterend.neon_cactus_slab": "Neon Cactus Slab", "block.betterend.neon_cactus_stairs": "Neon Cactus Stairs", - "biome.betterend.jade_cave": "Jade Cave" + "biome.betterend.jade_cave": "Jade Cave", + "item.betterend.blossom_berry_jelly": "Blossom Berry Jelly", + "item.betterend.aeternium_forged_plate": "Aeternium Forged Plate", + "item.betterend.terminite_forged_plate": "Terminite Forged Plate", + "item.betterend.thallasium_forged_plate": "Thallasium Forged Plate", + + "attribute.name.generic.blindness_resistance": "Blindness Resistance", + + "tooltip.armor.crystalite_set": "Set bonus: Regeneration I", + "tooltip.armor.crystalite_chest": "Effect: Dig Speed I", + "tooltip.armor.crystalite_boots": "Effect: Swiftness I" } diff --git a/src/main/resources/assets/betterend/lang/ru_ru.json b/src/main/resources/assets/betterend/lang/ru_ru.json index 0e550b66..c45162ae 100644 --- a/src/main/resources/assets/betterend/lang/ru_ru.json +++ b/src/main/resources/assets/betterend/lang/ru_ru.json @@ -840,6 +840,9 @@ "item.betterend.cave_pumpkin_pie": "Пирог из пещерной тыквы", "item.betterend.music_disc_strange_and_alien": "§bПластинка§r", + "item.betterend.music_disc_grasping_at_stars": "§bПластинка§r", + "item.betterend.music_disc_endseeker": "§bПластинка§r", + "item.betterend.music_disc_eo_dracona": "§bПластинка§r", "block.betterend.hydralux_petal_block_amber": "Янтарный блок лепестков", "block.betterend.hydralux_petal_block_beige": "Бежевый блок лепестков", @@ -874,5 +877,15 @@ "block.betterend.neon_cactus_block": "Блок неонового кактуса", "block.betterend.neon_cactus_slab": "Плита из неонового кактуса", "block.betterend.neon_cactus_stairs": "Ступени из неонового кактуса", - "biome.betterend.jade_cave": "Нефритовая пещера" + "biome.betterend.jade_cave": "Нефритовая пещера", + "item.betterend.blossom_berry_jelly": "Желе из цветущей ягоды", + "item.betterend.aeternium_forged_plate": "Этериевая кованная пластина", + "item.betterend.terminite_forged_plate": "Терминитовая кованная пластина", + "item.betterend.thallasium_forged_plate": "Талласиевая кованная пластина", + + "attribute.name.generic.blindness_resistance": "Сопротивление ослеплению", + + "tooltip.armor.crystalite_set": "Бонус сета: Регенерация I", + "tooltip.armor.crystalite_chest": "Эффект: Ускорение I", + "tooltip.armor.crystalite_boots": "Эффект: Стремительность I" } \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/item/elytra_armored.json b/src/main/resources/assets/betterend/models/item/elytra_armored.json new file mode 100644 index 00000000..a59c580f --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/elytra_armored.json @@ -0,0 +1,14 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "betterend:item/elytra_armored" + }, + "overrides": [ + { + "predicate": { + "broken": 1 + }, + "model": "betterend:item/elytra_armored_broken" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/item/elytra_armored_broken.json b/src/main/resources/assets/betterend/models/item/elytra_armored_broken.json new file mode 100644 index 00000000..cf30b22a --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/elytra_armored_broken.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "betterend:item/elytra_armored_broken" + } +} diff --git a/src/main/resources/assets/betterend/sounds.json b/src/main/resources/assets/betterend/sounds.json index 03913530..b85d3dab 100644 --- a/src/main/resources/assets/betterend/sounds.json +++ b/src/main/resources/assets/betterend/sounds.json @@ -99,6 +99,31 @@ } ] }, + "betterend.music.caves": { + "category": "music", + "sounds": [ + { + "name": "betterend:music/godmode-future_rennaisance", + "volume": 0.1, + "stream": false + }, + { + "name": "betterend:music/futuremono-moonrise", + "volume": 0.1, + "stream": false + }, + { + "name": "betterend:music/emmit_fenn-wander", + "volume": 0.1, + "stream": false + }, + { + "name": "betterend:music/corbyn_kites-orbit", + "volume": 0.1, + "stream": false + } + ] + }, "betterend.ambient.foggy_mushroomland": { "category": "ambient", @@ -184,6 +209,16 @@ } ] }, + "betterend.ambient.caves": { + "category": "ambient", + "sounds": [ + { + "name": "betterend:ambient/caves", + "volume": 0.5, + "stream": false + } + ] + }, "betterend.entity.dragonfly": { "category": "entity", @@ -242,5 +277,32 @@ "stream": false } ] + }, + "betterend.record.grasping_at_stars": { + "category": "record", + "sounds": [ + { + "name": "betterend:records/firel-grasping_at_stars", + "stream": false + } + ] + }, + "betterend.record.endseeker": { + "category": "record", + "sounds": [ + { + "name": "betterend:records/firel-endseeker", + "stream": false + } + ] + }, + "betterend.record.eo_dracona": { + "category": "record", + "sounds": [ + { + "name": "betterend:records/firel-eo_dracona", + "stream": false + } + ] } } diff --git a/src/main/resources/assets/betterend/sounds/ambient/caves.ogg b/src/main/resources/assets/betterend/sounds/ambient/caves.ogg new file mode 100644 index 00000000..e68412e4 Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/ambient/caves.ogg differ diff --git a/src/main/resources/assets/betterend/sounds/music/corbyn_kites-orbit.ogg b/src/main/resources/assets/betterend/sounds/music/corbyn_kites-orbit.ogg new file mode 100644 index 00000000..6bc10162 Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/music/corbyn_kites-orbit.ogg differ diff --git a/src/main/resources/assets/betterend/sounds/music/emmit_fenn-wander.ogg b/src/main/resources/assets/betterend/sounds/music/emmit_fenn-wander.ogg new file mode 100644 index 00000000..8827bce7 Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/music/emmit_fenn-wander.ogg differ diff --git a/src/main/resources/assets/betterend/sounds/music/futuremono-moonrise.ogg b/src/main/resources/assets/betterend/sounds/music/futuremono-moonrise.ogg new file mode 100644 index 00000000..32f9257c Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/music/futuremono-moonrise.ogg differ diff --git a/src/main/resources/assets/betterend/sounds/music/godmode-future_rennaisance.ogg b/src/main/resources/assets/betterend/sounds/music/godmode-future_rennaisance.ogg new file mode 100644 index 00000000..9936c3a1 Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/music/godmode-future_rennaisance.ogg differ diff --git a/src/main/resources/assets/betterend/sounds/records/firel-endseeker.ogg b/src/main/resources/assets/betterend/sounds/records/firel-endseeker.ogg new file mode 100644 index 00000000..5dd20bc8 Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/records/firel-endseeker.ogg differ diff --git a/src/main/resources/assets/betterend/sounds/records/firel-eo_dracona.ogg b/src/main/resources/assets/betterend/sounds/records/firel-eo_dracona.ogg new file mode 100644 index 00000000..4b26bcda Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/records/firel-eo_dracona.ogg differ diff --git a/src/main/resources/assets/betterend/sounds/records/firel-grasping_at_stars.ogg b/src/main/resources/assets/betterend/sounds/records/firel-grasping_at_stars.ogg new file mode 100644 index 00000000..c81a8069 Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/records/firel-grasping_at_stars.ogg differ diff --git a/src/main/resources/assets/betterend/textures/entity/elytra_armored.png b/src/main/resources/assets/betterend/textures/entity/elytra_armored.png index c5540b5d..4fb41886 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/elytra_armored.png and b/src/main/resources/assets/betterend/textures/entity/elytra_armored.png differ diff --git a/src/main/resources/assets/betterend/textures/item/aeternium_forged_plate.png b/src/main/resources/assets/betterend/textures/item/aeternium_forged_plate.png new file mode 100644 index 00000000..3ffd9a9a Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/aeternium_forged_plate.png differ diff --git a/src/main/resources/assets/betterend/textures/item/blossom_berry_jelly.png b/src/main/resources/assets/betterend/textures/item/blossom_berry_jelly.png new file mode 100644 index 00000000..d09b7c25 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/blossom_berry_jelly.png differ diff --git a/src/main/resources/assets/betterend/textures/item/elytra_armored.png b/src/main/resources/assets/betterend/textures/item/elytra_armored.png index 3d13a928..f8dfb88b 100644 Binary files a/src/main/resources/assets/betterend/textures/item/elytra_armored.png and b/src/main/resources/assets/betterend/textures/item/elytra_armored.png differ diff --git a/src/main/resources/assets/betterend/textures/item/elytra_armored_broken.png b/src/main/resources/assets/betterend/textures/item/elytra_armored_broken.png new file mode 100644 index 00000000..fe2de9a2 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/elytra_armored_broken.png differ diff --git a/src/main/resources/assets/betterend/textures/item/music_disc_endseeker.png b/src/main/resources/assets/betterend/textures/item/music_disc_endseeker.png new file mode 100644 index 00000000..8c4ab480 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/music_disc_endseeker.png differ diff --git a/src/main/resources/assets/betterend/textures/item/music_disc_eo_dracona.png b/src/main/resources/assets/betterend/textures/item/music_disc_eo_dracona.png new file mode 100644 index 00000000..a4a91c3f Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/music_disc_eo_dracona.png differ diff --git a/src/main/resources/assets/betterend/textures/item/music_disc_grasping_at_stars.png b/src/main/resources/assets/betterend/textures/item/music_disc_grasping_at_stars.png new file mode 100644 index 00000000..7d607c5b Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/music_disc_grasping_at_stars.png differ diff --git a/src/main/resources/assets/betterend/textures/item/sweet_berry_jelly.png b/src/main/resources/assets/betterend/textures/item/sweet_berry_jelly.png index 916b3363..4e2ff978 100644 Binary files a/src/main/resources/assets/betterend/textures/item/sweet_berry_jelly.png and b/src/main/resources/assets/betterend/textures/item/sweet_berry_jelly.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_forged_plate.png b/src/main/resources/assets/betterend/textures/item/terminite_forged_plate.png new file mode 100644 index 00000000..5b203bbe Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/terminite_forged_plate.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_forged_plate.png b/src/main/resources/assets/betterend/textures/item/thallasium_forged_plate.png new file mode 100644 index 00000000..2be7008f Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/thallasium_forged_plate.png differ diff --git a/src/main/resources/betterend.mixins.client.json b/src/main/resources/betterend.mixins.client.json index de7b097c..be0ed49a 100644 --- a/src/main/resources/betterend.mixins.client.json +++ b/src/main/resources/betterend.mixins.client.json @@ -8,6 +8,8 @@ "ClientPlayNetworkHandlerMixin", "NamespaceResourceManagerMixin", "EnchantingTableBlockMixin", + "HumanoidMobRendererMixin", + "ArmorStandRendererMixin", "BackgroundRendererMixin", "ClientRecipeBookMixin", "ModelVariantMapMixin", diff --git a/src/main/resources/betterend.mixins.common.json b/src/main/resources/betterend.mixins.common.json index 1225e6e1..5ce12bbf 100644 --- a/src/main/resources/betterend.mixins.common.json +++ b/src/main/resources/betterend.mixins.common.json @@ -18,10 +18,10 @@ "RecipeManagerAccessor", "EnchantmentMenuMixin", "MinecraftServerMixin", + "EndDragonFightMixin", "BlockBehaviourMixin", "DimensionTypeMixin", "RecipeManagerMixin", - "ArmorItemAccessor", "BoneMealItemMixin", "CraftingMenuMixin", "LivingEntityMixin", @@ -33,6 +33,7 @@ "AnvilMenuMixin", "TagLoaderMixin", "EnderManMixin", + "EndSpikeMixin", "MonsterMixin", "EntityMixin", "PlayerMixin", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 315cf94c..c3da285a 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -43,9 +43,9 @@ ], "depends": { - "fabricloader": ">=0.10.0", - "fabric": ">=0.29.0", - "minecraft": ">=1.16.3" + "fabricloader": ">=0.11.0", + "fabric": ">=0.32.0", + "minecraft": ">=1.16.4" }, "suggests": { "byg": ">=1.1.3",