diff --git a/src/main/java/org/dimdev/annotatednbt/AnnotatedNbt.java b/src/main/java/org/dimdev/annotatednbt/AnnotatedNbt.java index 6c3b9278..e69a5bdc 100644 --- a/src/main/java/org/dimdev/annotatednbt/AnnotatedNbt.java +++ b/src/main/java/org/dimdev/annotatednbt/AnnotatedNbt.java @@ -1,10 +1,15 @@ package org.dimdev.annotatednbt; +import com.google.gson.Gson; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.JsonOps; +import net.minecraft.datafixer.NbtOps; import net.minecraft.nbt.CompoundTag; -import org.dimdev.dimdoors.rift.registry.PlayerRiftPointer; +import net.minecraft.nbt.Tag; import org.dimdev.util.RotatedLocation; public final class AnnotatedNbt { + public static Gson gson = new Gson(); public static T deserialize(Class rotatedLocationClass, CompoundTag tag) { return null; // TODO } @@ -28,4 +33,12 @@ public final class AnnotatedNbt { public static CompoundTag toTag(Object playerRiftPointer, CompoundTag nbt) { return null; } + + public static Tag toTag(Object obj) { + return new Dynamic<>(JsonOps.INSTANCE, gson.toJsonTree(obj)).convert(NbtOps.INSTANCE).getValue(); + } + + public static Object fromTag(Class clazz, Tag nbt) { + return gson.fromJson(new Dynamic<>(NbtOps.INSTANCE, nbt).convert(JsonOps.INSTANCE).getValue(), clazz); + } } diff --git a/src/main/java/org/dimdev/dimdoors/DimensionalDoorsClientInitializer.java b/src/main/java/org/dimdev/dimdoors/DimensionalDoorsClientInitializer.java new file mode 100644 index 00000000..0433ad5b --- /dev/null +++ b/src/main/java/org/dimdev/dimdoors/DimensionalDoorsClientInitializer.java @@ -0,0 +1,98 @@ +package org.dimdev.dimdoors; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; +import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; +import net.minecraft.block.Block; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.texture.Sprite; +import net.minecraft.client.texture.SpriteAtlasTexture; +import net.minecraft.fluid.Fluid; +import net.minecraft.fluid.FluidState; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourceType; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.BlockRenderView; +import org.dimdev.dimdoors.block.ModBlocks; +import org.dimdev.dimdoors.fluid.ModFluids; + +import java.util.function.Function; + +public class DimensionalDoorsClientInitializer implements ClientModInitializer { + @Override + public void onInitializeClient() { + putCutout(ModBlocks.OAK_DIMENSIONAL_DOOR); + putCutout(ModBlocks.GOLD_DIMENSIONAL_DOOR); + putCutout(ModBlocks.IRON_DIMENSIONAL_DOOR); + putCutout(ModBlocks.OAK_DIMENSIONAL_TRAPDOOR); + putCutout(ModBlocks.QUARTZ_DIMENSIONAL_DOOR); + putCutout(ModBlocks.QUARTZ_DOOR); + + setupFluidRendering(ModFluids.ETERNAL_FLUID, ModFluids.FLOWING_ETERNAL_FLUID, new Identifier("dimdoors:eternal_fluid")); + } + + private void putCutout(Block block) { + BlockRenderLayerMap.INSTANCE.putBlock(block, RenderLayer.getCutout()); + } + + public static void setupFluidRendering(final Fluid still, final Fluid flowing, final Identifier textureFluidId) { + final Identifier stillSpriteId = new Identifier(textureFluidId.getNamespace(), "block/" + textureFluidId.getPath() + "_still"); + final Identifier flowingSpriteId = new Identifier(textureFluidId.getNamespace(), "block/" + textureFluidId.getPath() + "_flow"); + + // If they're not already present, add the sprites to the block atlas + ClientSpriteRegistryCallback.event(SpriteAtlasTexture.BLOCK_ATLAS_TEX).register((atlasTexture, registry) -> { + registry.register(stillSpriteId); + registry.register(flowingSpriteId); + }); + + final Identifier fluidId = Registry.FLUID.getId(still); + final Identifier listenerId = new Identifier(fluidId.getNamespace(), fluidId.getPath() + "_reload_listener"); + + final Sprite[] fluidSprites = { null, null }; + + ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { + @Override + public Identifier getFabricId() + { + return listenerId; + } + + /** + * Get the sprites from the block atlas when resources are reloaded + */ + @Override + public void apply(ResourceManager resourceManager) + { + final Function atlas = MinecraftClient.getInstance().getSpriteAtlas(SpriteAtlasTexture.BLOCK_ATLAS_TEX); + fluidSprites[0] = atlas.apply(stillSpriteId); + fluidSprites[1] = atlas.apply(flowingSpriteId); + } + }); + + // The FluidRenderer gets the sprites and color from a FluidRenderHandler during rendering + final FluidRenderHandler renderHandler = new FluidRenderHandler() { + @Override + public Sprite[] getFluidSprites(BlockRenderView view, BlockPos pos, FluidState state) + { + return fluidSprites; + } + + @Override + public int getFluidColor(BlockRenderView view, BlockPos pos, FluidState state) + { + return 16777215; + } + }; + + FluidRenderHandlerRegistry.INSTANCE.register(still, renderHandler); + FluidRenderHandlerRegistry.INSTANCE.register(flowing, renderHandler); + } + +} diff --git a/src/main/java/org/dimdev/dimdoors/block/ModBlocks.java b/src/main/java/org/dimdev/dimdoors/block/ModBlocks.java index 923c0e63..1dc96102 100644 --- a/src/main/java/org/dimdev/dimdoors/block/ModBlocks.java +++ b/src/main/java/org/dimdev/dimdoors/block/ModBlocks.java @@ -2,19 +2,21 @@ package org.dimdev.dimdoors.block; import net.fabricmc.fabric.api.block.FabricBlockSettings; import net.minecraft.block.Block; +import net.minecraft.block.Blocks; import net.minecraft.block.Material; import net.minecraft.block.MaterialColor; +import net.minecraft.item.Items; import net.minecraft.util.DyeColor; import net.minecraft.util.registry.Registry; public final class ModBlocks { - public static final Block GOLD_DOOR = register("dimdoors:gold_door", new DoorBlock(FabricBlockSettings.of(Material.METAL, MaterialColor.GOLD).build())); - public static final Block QUARTZ_DOOR = register("dimdoors:quartz_door", new DoorBlock(FabricBlockSettings.of(Material.STONE, MaterialColor.QUARTZ).build())); - public static final Block OAK_DIMENSIONAL_DOOR = register("dimdoors:oak_dimensional_door", new DimensionalDoorBlock(FabricBlockSettings.of(Material.WOOD, MaterialColor.WOOD).build())); - public static final Block IRON_DIMENSIONAL_DOOR = register("dimdoors:iron_dimensional_door", new DimensionalDoorBlock(FabricBlockSettings.of(Material.METAL, MaterialColor.IRON).build())); - public static final Block GOLD_DIMENSIONAL_DOOR = register("dimdoors:gold_dimensional_door", new DimensionalDoorBlock(FabricBlockSettings.of(Material.METAL, MaterialColor.GOLD).build())); - public static final Block QUARTZ_DIMENSIONAL_DOOR = register("dimdoors:quartz_dimensional_door", new DimensionalDoorBlock(FabricBlockSettings.of(Material.STONE, MaterialColor.QUARTZ).build())); - public static final Block OAK_DIMENSIONAL_TRAPDOOR = register("dimdoors:wood_dimensional_trapdoor", new DimensionalTrapdoorBlock(FabricBlockSettings.of(Material.WOOD, MaterialColor.WOOD).build())); + public static final Block GOLD_DOOR = register("dimdoors:gold_door", new DoorBlock(FabricBlockSettings.of(Material.METAL, MaterialColor.GOLD).nonOpaque().build())); + public static final Block QUARTZ_DOOR = register("dimdoors:quartz_door", new DoorBlock(FabricBlockSettings.of(Material.STONE, MaterialColor.QUARTZ).nonOpaque().build())); + public static final Block OAK_DIMENSIONAL_DOOR = register("dimdoors:oak_dimensional_door", new DimensionalDoorBlock(FabricBlockSettings.of(Material.WOOD, MaterialColor.WOOD).nonOpaque().build())); + public static final Block IRON_DIMENSIONAL_DOOR = register("dimdoors:iron_dimensional_door", new DimensionalDoorBlock(FabricBlockSettings.of(Material.METAL, MaterialColor.IRON).nonOpaque().build())); + public static final Block GOLD_DIMENSIONAL_DOOR = register("dimdoors:gold_dimensional_door", new DimensionalDoorBlock(FabricBlockSettings.of(Material.METAL, MaterialColor.GOLD).nonOpaque().build())); + public static final Block QUARTZ_DIMENSIONAL_DOOR = register("dimdoors:quartz_dimensional_door", new DimensionalDoorBlock(FabricBlockSettings.of(Material.STONE, MaterialColor.QUARTZ).nonOpaque().build())); + public static final Block OAK_DIMENSIONAL_TRAPDOOR = register("dimdoors:wood_dimensional_trapdoor", new DimensionalTrapdoorBlock(FabricBlockSettings.of(Material.WOOD, MaterialColor.WOOD).nonOpaque().build())); public static final Block DIMENSIONAL_PORTAL = register("dimdoors:dimensional_portal", new DimensionalPortalBlock(FabricBlockSettings.of(Material.AIR).collidable(false).dropsNothing().build())); public static final Block DETACHED_RIFT = register("dimdoors:detached_rift", new DetachedRiftBlock(FabricBlockSettings.of(Material.AIR).nonOpaque().build())); diff --git a/src/main/java/org/dimdev/dimdoors/client/MyRenderLayer.java b/src/main/java/org/dimdev/dimdoors/client/MyRenderLayer.java new file mode 100644 index 00000000..32f1d11f --- /dev/null +++ b/src/main/java/org/dimdev/dimdoors/client/MyRenderLayer.java @@ -0,0 +1,39 @@ +package org.dimdev.dimdoors.client; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.block.BlockRenderType; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.RenderPhase; +import net.minecraft.client.render.VertexFormat; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.util.Identifier; +import org.dimdev.dimdoors.client.tesseract.Tesseract; +import org.lwjgl.opengl.GL11; + +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_DST_COLOR; +import static org.lwjgl.opengl.GL11.GL_ZERO; + +public class MyRenderLayer extends RenderLayer { + public MyRenderLayer(String string, VertexFormat vertexFormat, int i, int j, boolean bl, boolean bl2, Runnable runnable, Runnable runnable2) { + super(string, vertexFormat, i, j, bl, bl2, runnable, runnable2); + } + + public static RenderLayer CRACK = RenderLayer.of("crack", VertexFormats.POSITION_COLOR, GL11.GL_QUADS, 256, MultiPhaseParameters.builder() + .cull(DISABLE_CULLING) + .lightmap(RenderPhase.DISABLE_LIGHTMAP) + .texture(NO_TEXTURE) + .transparency(new Transparency("crack_transparency", () -> { + RenderSystem.enableBlend(); + RenderSystem.blendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); + }, () -> { + RenderSystem.disableBlend(); + RenderSystem.defaultBlendFunc(); + })) + .build(false)); + + public static RenderLayer TESSERACT = RenderLayer.of("tesseract", VertexFormats.POSITION_COLOR_TEXTURE, GL11.GL_QUADS, 256, MultiPhaseParameters.builder() + .cull(DISABLE_CULLING) + .lightmap(RenderPhase.DISABLE_LIGHTMAP) + .texture(new Texture(new Identifier("dimdoors:textures/other/tesseract.png"),false, false)) + .build(false)); +} diff --git a/src/main/java/org/dimdev/dimdoors/client/RiftCrackRenderer.java b/src/main/java/org/dimdev/dimdoors/client/RiftCrackRenderer.java index 4ac1845e..db0115d2 100644 --- a/src/main/java/org/dimdev/dimdoors/client/RiftCrackRenderer.java +++ b/src/main/java/org/dimdev/dimdoors/client/RiftCrackRenderer.java @@ -41,10 +41,6 @@ public final class RiftCrackRenderer { flutters[i] = Math.sin((1F + i / 10F) * time * flutterSpeed) * Math.cos(1F - i / 10F * time * flutterSpeed) * flutterMagnitude; } - // Set color (nearly black, but inverts background) - RenderSystem.color4f(0.08f, 0.08f, 0.08f, .3F); - RenderSystem.blendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); - // Draw the rift for (Point p : poly.points) { // Reduces most overlap between triangles inside the rift's center @@ -60,7 +56,7 @@ public final class RiftCrackRenderer { y *= scale; z *= scale; - vc.vertex(x + xJitter, y + yJitter, z + zJitter); + vc.vertex(x + xJitter, y + yJitter, z + zJitter).color(0.08f, 0.08f, 0.08f, .3f).next(); } } } diff --git a/src/main/java/org/dimdev/dimdoors/fluid/EternalFluid.java b/src/main/java/org/dimdev/dimdoors/fluid/EternalFluid.java index 798d8b5b..f1d11ec4 100644 --- a/src/main/java/org/dimdev/dimdoors/fluid/EternalFluid.java +++ b/src/main/java/org/dimdev/dimdoors/fluid/EternalFluid.java @@ -16,23 +16,24 @@ import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraft.world.WorldView; import org.dimdev.dimdoors.block.ModBlocks; +import org.dimdev.dimdoors.item.ModItems; import java.util.Random; public abstract class EternalFluid extends BaseFluid { @Override public Fluid getFlowing() { - return Fluids.FLOWING_LAVA; + return ModFluids.FLOWING_ETERNAL_FLUID; } @Override public Fluid getStill() { - return Fluids.LAVA; + return ModFluids.ETERNAL_FLUID; } @Override public Item getBucketItem() { - return Items.LAVA_BUCKET; + return ModItems.ETERNAL_FLUID_BUCKET; } @Override @@ -122,7 +123,7 @@ public abstract class EternalFluid extends BaseFluid { return 100000; } - public static class Flowing extends LavaFluid { + public static class Flowing extends EternalFluid { @Override protected void appendProperties(StateManager.Builder builder) { super.appendProperties(builder); @@ -140,7 +141,7 @@ public abstract class EternalFluid extends BaseFluid { } } - public static class Still extends LavaFluid { + public static class Still extends EternalFluid { @Override public int getLevel(FluidState fluidState) { return 8; diff --git a/src/main/java/org/dimdev/dimdoors/item/ModItems.java b/src/main/java/org/dimdev/dimdoors/item/ModItems.java index c41c8f63..00b942dd 100644 --- a/src/main/java/org/dimdev/dimdoors/item/ModItems.java +++ b/src/main/java/org/dimdev/dimdoors/item/ModItems.java @@ -2,13 +2,12 @@ package org.dimdev.dimdoors.item; import net.minecraft.block.Block; import net.minecraft.entity.EquipmentSlot; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemGroup; +import net.minecraft.item.*; import net.minecraft.sound.SoundEvent; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; import org.dimdev.dimdoors.block.ModBlocks; +import org.dimdev.dimdoors.fluid.ModFluids; import org.dimdev.dimdoors.rift.registry.LinkProperties; import org.dimdev.dimdoors.rift.targets.*; import org.dimdev.dimdoors.sound.ModSoundEvents; @@ -18,13 +17,15 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import static org.dimdev.dimdoors.item.ModItemGroups.DIMENSIONAL_DOORS; + public final class ModItems { public static final Item GOLD_DOOR = register(ModBlocks.GOLD_DOOR); public static final Item QUARTZ_DOOR = register(ModBlocks.QUARTZ_DOOR); public static final Item IRON_DIMENSIONAL_DOOR = register(new DimensionalDoorItem( ModBlocks.IRON_DIMENSIONAL_DOOR, - new Item.Settings().group(ModItemGroups.DIMENSIONAL_DOORS).maxCount(1), + new Item.Settings().group(DIMENSIONAL_DOORS).maxCount(1), rift -> { PublicPocketTarget destination = new PublicPocketTarget(); rift.setDestination(destination); @@ -33,7 +34,7 @@ public final class ModItems { public static final Item GOLD_DIMENSIONAL_DOOR = register(new DimensionalDoorItem( ModBlocks.GOLD_DIMENSIONAL_DOOR, - new Item.Settings().group(ModItemGroups.DIMENSIONAL_DOORS).maxCount(1), + new Item.Settings().group(DIMENSIONAL_DOORS).maxCount(1), rift -> { rift.setProperties(LinkProperties.builder() .groups(new HashSet<>(Arrays.asList(0, 1))) @@ -53,7 +54,7 @@ public final class ModItems { public static final Item QUARTZ_DIMENSIONAL_DOOR = register(new DimensionalDoorItem( ModBlocks.QUARTZ_DIMENSIONAL_DOOR, - new Item.Settings().group(ModItemGroups.DIMENSIONAL_DOORS).maxCount(1), + new Item.Settings().group(DIMENSIONAL_DOORS).maxCount(1), rift -> { if (rift.getWorld().dimension instanceof PersonalPocketDimension) { rift.setDestination(new PrivatePocketExitTarget()); // exit @@ -73,7 +74,7 @@ public final class ModItems { public static final Item OAK_DIMENSIONAL_DOOR = register(new DimensionalDoorItem( ModBlocks.OAK_DIMENSIONAL_DOOR, - new Item.Settings().group(ModItemGroups.DIMENSIONAL_DOORS).maxCount(1), + new Item.Settings().group(DIMENSIONAL_DOORS).maxCount(1), rift -> rift.setDestination( RandomTarget .builder() @@ -88,7 +89,7 @@ public final class ModItems { public static final Item OAK_DIMENSIONAL_TRAPDOOR = register(new DimensionalTrapdoorItem( ModBlocks.OAK_DIMENSIONAL_TRAPDOOR, - new Item.Settings().group(ModItemGroups.DIMENSIONAL_DOORS).maxCount(1), + new Item.Settings().group(DIMENSIONAL_DOORS).maxCount(1), rift -> rift.setDestination(new EscapeTarget(false)) )); @@ -126,27 +127,31 @@ public final class ModItems { public static final Item RED_ANCIENT_FABRIC = register(ModBlocks.RED_ANCIENT_FABRIC); public static final Item BLACK_ANCIENT_FABRIC = register(ModBlocks.BLACK_ANCIENT_FABRIC); - public static final Item ETERNAL_FABRIC = register(ModBlocks.ETERNAL_FLUID); - public static final Item UNRAVELLED_FABRIC = register(ModBlocks.UNRAVELLED_FABRIC); + public static final Item ETERNAL_FLUID = register(ModBlocks.ETERNAL_FLUID); + public static final Item UNRAVELLED_FABRIC = register(ModBlocks.UNRAVELLED_FABRIC, DIMENSIONAL_DOORS); - public static final Item MARKING_PLATE = register(ModBlocks.MARKING_PLATE); + public static final Item MARKING_PLATE = register(ModBlocks.MARKING_PLATE, DIMENSIONAL_DOORS); // Dimensional doors - public static final Item WORLD_THREAD = register(new Identifier("dimdoors:world_thread"), new Item(new Item.Settings().group(ModItemGroups.DIMENSIONAL_DOORS))); - public static final Item STABLE_FABRIC = register(new Identifier("dimdoors:stable_fabric"), new Item(new Item.Settings().group(ModItemGroups.DIMENSIONAL_DOORS))); + public static final Item WORLD_THREAD = register(new Identifier("dimdoors:world_thread"), new Item(new Item.Settings().group(DIMENSIONAL_DOORS))); + public static final Item STABLE_FABRIC = register(new Identifier("dimdoors:stable_fabric"), new Item(new Item.Settings().group(DIMENSIONAL_DOORS))); public static final Item RIFT_CONFIGURATION_TOOL = register(new Identifier("dimdoors:rift_configuration_tool"), new RiftConfigurationToolItem()); - public static final Item RIFT_BLADE = register(new Identifier("dimdoors:rift_blade"), new RiftBladeItem(new Item.Settings().maxDamage(100).group(ModItemGroups.DIMENSIONAL_DOORS))); - public static final Item RIFT_REMOVER = register(new Identifier("dimdoors:rift_remover"), new RiftRemoverItem(new Item.Settings().maxCount(1).maxDamage(100).group(ModItemGroups.DIMENSIONAL_DOORS))); - public static final Item RIFT_SIGNATURE = register(new Identifier("dimdoors:rift_signature"), new RiftSignatureItem(new Item.Settings().maxCount(1).maxDamage(1).group(ModItemGroups.DIMENSIONAL_DOORS))); - public static final Item STABILIZED_RIFT_SIGNATURE = register(new Identifier("dimdoors:stabilized_rift_signature"), new StabilizedRiftSignatureItem(new Item.Settings().maxCount(1).maxDamage(20).group(ModItemGroups.DIMENSIONAL_DOORS))); - public static final Item RIFT_STABILIZER = register(new Identifier("dimdoors:rift_stabilizer"), new RiftStabilizerItem(new Item.Settings().maxCount(1).maxDamage(6).group(ModItemGroups.DIMENSIONAL_DOORS))); - public static final Item WORLD_THREAD_HELMET = register(new Identifier("dimdoors:world_thread_helmet"), new WorldThreadArmorItem("world_thread_helmet", EquipmentSlot.HEAD, new Item.Settings())); - public static final Item WORLD_THREAD_CHESTPLATE = register(new Identifier("dimdoors:world_thread_chestplate"), new WorldThreadArmorItem("world_thread_chestplate", EquipmentSlot.CHEST, new Item.Settings())); - public static final Item WORLD_THREAD_LEGGINGS = register(new Identifier("dimdoors:world_thread_leggings"), new WorldThreadArmorItem("world_thread_leggings", EquipmentSlot.LEGS, new Item.Settings())); - public static final Item WORLD_THREAD_BOOTS = register(new Identifier("dimdoors:world_thread_boots"), new WorldThreadArmorItem("world_thread_boots", EquipmentSlot.FEET, new Item.Settings())); - public static final Item CREEPY_RECORD = register(new Identifier("dimdoors:creepy_record"), new MusicDiscItem(10, ModSoundEvents.CREEPY, new Item.Settings().group(ModItemGroups.DIMENSIONAL_DOORS))); - public static final Item WHITE_VOID_RECORD = register(new Identifier("dimdoors:white_void_record"), new MusicDiscItem(10, ModSoundEvents.CREEPY, new Item.Settings().group(ModItemGroups.DIMENSIONAL_DOORS))); + public static final Item RIFT_BLADE = register(new Identifier("dimdoors:rift_blade"), new RiftBladeItem(new Item.Settings().maxDamage(100).group(DIMENSIONAL_DOORS))); + public static final Item RIFT_REMOVER = register(new Identifier("dimdoors:rift_remover"), new RiftRemoverItem(new Item.Settings().maxCount(1).maxDamage(100).group(DIMENSIONAL_DOORS))); + public static final Item RIFT_SIGNATURE = register(new Identifier("dimdoors:rift_signature"), new RiftSignatureItem(new Item.Settings().maxCount(1).maxDamage(1).group(DIMENSIONAL_DOORS))); + public static final Item STABILIZED_RIFT_SIGNATURE = register(new Identifier("dimdoors:stabilized_rift_signature"), new StabilizedRiftSignatureItem(new Item.Settings().maxCount(1).maxDamage(20).group(DIMENSIONAL_DOORS))); + public static final Item RIFT_STABILIZER = register(new Identifier("dimdoors:rift_stabilizer"), new RiftStabilizerItem(new Item.Settings().maxCount(1).maxDamage(6).group(DIMENSIONAL_DOORS))); + + public static final Item WORLD_THREAD_HELMET = register(new Identifier("dimdoors:world_thread_helmet"), new WorldThreadArmorItem(EquipmentSlot.HEAD, new Item.Settings())); + public static final Item WORLD_THREAD_CHESTPLATE = register(new Identifier("dimdoors:world_thread_chestplate"), new WorldThreadArmorItem(EquipmentSlot.CHEST, new Item.Settings())); + public static final Item WORLD_THREAD_LEGGINGS = register(new Identifier("dimdoors:world_thread_leggings"), new WorldThreadArmorItem(EquipmentSlot.LEGS, new Item.Settings())); + public static final Item WORLD_THREAD_BOOTS = register(new Identifier("dimdoors:world_thread_boots"), new WorldThreadArmorItem(EquipmentSlot.FEET, new Item.Settings())); + + public static final Item CREEPY_RECORD = register(new Identifier("dimdoors:creepy_record"), new MusicDiscItem(10, ModSoundEvents.CREEPY, new Item.Settings().group(DIMENSIONAL_DOORS))); + public static final Item WHITE_VOID_RECORD = register(new Identifier("dimdoors:white_void_record"), new MusicDiscItem(10, ModSoundEvents.CREEPY, new Item.Settings().group(DIMENSIONAL_DOORS))); + + public static final Item ETERNAL_FLUID_BUCKET = register(new Identifier("dimdoors:eternal_fluid_bucket"), new BucketItem(ModFluids.ETERNAL_FLUID, new Item.Settings().group(DIMENSIONAL_DOORS).recipeRemainder(Items.BUCKET).maxCount(1))); private static Item register(Block block) { return register(new BlockItem(block, new Item.Settings())); diff --git a/src/main/java/org/dimdev/dimdoors/item/WorldThreadArmorItem.java b/src/main/java/org/dimdev/dimdoors/item/WorldThreadArmorItem.java index 73e86909..b57b2c78 100644 --- a/src/main/java/org/dimdev/dimdoors/item/WorldThreadArmorItem.java +++ b/src/main/java/org/dimdev/dimdoors/item/WorldThreadArmorItem.java @@ -6,6 +6,7 @@ import net.minecraft.item.ArmorMaterial; import net.minecraft.item.Item; import net.minecraft.recipe.Ingredient; import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; public class WorldThreadArmorItem extends ArmorItem { public static final ArmorMaterial MATERIAL = new ArmorMaterial() { @@ -26,7 +27,7 @@ public class WorldThreadArmorItem extends ArmorItem { @Override public SoundEvent getEquipSound() { - return null; + return SoundEvents.ITEM_ARMOR_EQUIP_GENERIC; } @Override @@ -36,7 +37,7 @@ public class WorldThreadArmorItem extends ArmorItem { @Override public String getName() { - return "woven_world_thread"; + return "world_thread"; } @Override @@ -50,7 +51,7 @@ public class WorldThreadArmorItem extends ArmorItem { } }; - public WorldThreadArmorItem(String name, EquipmentSlot equipmentSlot, Item.Settings settings) { + public WorldThreadArmorItem(EquipmentSlot equipmentSlot, Item.Settings settings) { super(MATERIAL, equipmentSlot, settings); } } diff --git a/src/main/java/org/dimdev/dimdoors/world/limbo/LimboDimension.java b/src/main/java/org/dimdev/dimdoors/world/limbo/LimboDimension.java index e5773153..e763220e 100644 --- a/src/main/java/org/dimdev/dimdoors/world/limbo/LimboDimension.java +++ b/src/main/java/org/dimdev/dimdoors/world/limbo/LimboDimension.java @@ -10,6 +10,7 @@ import net.minecraft.world.biome.source.FixedBiomeSourceConfig; import net.minecraft.world.dimension.Dimension; import net.minecraft.world.dimension.DimensionType; import net.minecraft.world.gen.chunk.ChunkGenerator; +import org.dimdev.dimdoors.block.ModBlocks; import org.dimdev.dimdoors.world.ModBiomes; import org.dimdev.dimdoors.world.ModDimensions; @@ -24,6 +25,8 @@ public class LimboDimension extends Dimension { FixedBiomeSourceConfig biomeConfig = BiomeSourceType.FIXED.getConfig(world.getSeed()).setBiome(ModBiomes.LIMBO); FixedBiomeSource biomeSource = BiomeSourceType.FIXED.applyConfig(biomeConfig); LimboChunkGeneratorConfig chunkGeneratorConfig = new LimboChunkGeneratorConfig(); + chunkGeneratorConfig.setDefaultBlock(ModBlocks.UNRAVELLED_FABRIC.getDefaultState()); + chunkGeneratorConfig.setDefaultFluid(ModBlocks.ETERNAL_FLUID.getDefaultState()); return new LimboChunkGenerator(world, biomeSource, chunkGeneratorConfig); } @@ -49,7 +52,7 @@ public class LimboDimension extends Dimension { @Override public Vec3d modifyFogColor(Vec3d vec3d, float f) { - return null; + return new Vec3d(0.2,0.2,0.2); } @Override @@ -59,7 +62,7 @@ public class LimboDimension extends Dimension { @Override public boolean isFogThick(int i, int j) { - return true; + return false; } @Override diff --git a/src/main/java/org/dimdev/gsonnbt/NbtReader.java b/src/main/java/org/dimdev/gsonnbt/NbtReader.java new file mode 100644 index 00000000..87c1e221 --- /dev/null +++ b/src/main/java/org/dimdev/gsonnbt/NbtReader.java @@ -0,0 +1,287 @@ +package org.dimdev.gsonnbt; + +import com.google.gson.*; +import com.google.gson.internal.bind.JsonTreeReader; +import com.google.gson.internal.bind.JsonTreeWriter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import net.minecraft.nbt.*; + +import java.io.IOException; +import java.io.Reader; +import java.util.Iterator; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class NbtReader extends JsonReader { + private static final Reader UNREADABLE_READER = new Reader() { + @Override public int read(char[] buffer, int offset, int count) throws IOException { + throw new AssertionError(); + } + @Override public void close() throws IOException { + throw new AssertionError(); + } + }; + private static final Object SENTINEL_CLOSED = new Object(); + + /* + * The nesting stack. Using a manual array rather than an ArrayList saves 20%. + */ + private Object[] stack = new Object[32]; + private int stackSize = 0; + + /* + * The path members. It corresponds directly to stack: At indices where the + * stack contains an object (EMPTY_OBJECT, DANGLING_NAME or NONEMPTY_OBJECT), + * pathNames contains the name at this scope. Where it contains an array + * (EMPTY_ARRAY, NONEMPTY_ARRAY) pathIndices contains the current index in + * that array. Otherwise the value is undefined, and we take advantage of that + * by incrementing pathIndices when doing so isn't useful. + */ + private String[] pathNames = new String[32]; + private int[] pathIndices = new int[32]; + + public NbtReader(Tag element) { + super(UNREADABLE_READER); + push(element); + } + + @Override public void beginArray() throws IOException { + expect(JsonToken.BEGIN_ARRAY); + ListTag array = (ListTag) peekStack(); + push(array.iterator()); + pathIndices[stackSize - 1] = 0; + } + + @Override public void endArray() throws IOException { + expect(JsonToken.END_ARRAY); + popStack(); // empty iterator + popStack(); // array + if (stackSize > 0) { + pathIndices[stackSize - 1]++; + } + } + + @Override public void beginObject() throws IOException { + expect(JsonToken.BEGIN_OBJECT); + CompoundTag object = (CompoundTag) peekStack(); + push(object.getKeys().stream().collect(Collectors.toMap(Function.identity(), object::getCompound)).entrySet().iterator()); + } + + @Override public void endObject() throws IOException { + expect(JsonToken.END_OBJECT); + popStack(); // empty iterator + popStack(); // object + if (stackSize > 0) { + pathIndices[stackSize - 1]++; + } + } + + @Override public boolean hasNext() throws IOException { + JsonToken token = peek(); + return token != JsonToken.END_OBJECT && token != JsonToken.END_ARRAY; + } + + @Override public JsonToken peek() throws IOException { + if (stackSize == 0) { + return JsonToken.END_DOCUMENT; + } + + Object o = peekStack(); + if (o instanceof Iterator) { + boolean isObject = stack[stackSize - 2] instanceof CompoundTag; + Iterator iterator = (Iterator) o; + if (iterator.hasNext()) { + if (isObject) { + return JsonToken.NAME; + } else { + push(iterator.next()); + return peek(); + } + } else { + return isObject ? JsonToken.END_OBJECT : JsonToken.END_ARRAY; + } + } else if (o instanceof CompoundTag) { + return JsonToken.BEGIN_OBJECT; + } else if (o instanceof ListTag) { + return JsonToken.BEGIN_ARRAY; + } else if (o instanceof AbstractNumberTag) { + if (o instanceof ByteTag) { + if (((ByteTag) o).getByte() == 0 || ((ByteTag) o).getByte() == 1) return JsonToken.BOOLEAN; + } + + return JsonToken.NUMBER; + } else if (o instanceof StringTag) { + return JsonToken.STRING; + } else if (o instanceof EndTag) { + return JsonToken.NULL; + } else if (o == SENTINEL_CLOSED) { + throw new IllegalStateException("JsonReader is closed"); + } else { + System.out.println(o.getClass()); + throw new AssertionError(); + } + } + + private Object peekStack() { + return stack[stackSize - 1]; + } + + private Object popStack() { + Object result = stack[--stackSize]; + stack[stackSize] = null; + return result; + } + + private void expect(JsonToken expected) throws IOException { + if (peek() != expected) { + throw new IllegalStateException( + "Expected " + expected + " but was " + peek() + locationString()); + } + } + + @Override public String nextName() throws IOException { + expect(JsonToken.NAME); + Iterator i = (Iterator) peekStack(); + Map.Entry entry = (Map.Entry) i.next(); + String result = (String) entry.getKey(); + pathNames[stackSize - 1] = result; + push(entry.getValue()); + return result; + } + + @Override public String nextString() throws IOException { + JsonToken token = peek(); + if (token != JsonToken.STRING) { + throw new IllegalStateException( + "Expected " + JsonToken.STRING + " but was " + token + locationString()); + } + String result = ((StringTag) popStack()).asString(); + if (stackSize > 0) { + pathIndices[stackSize - 1]++; + } + return result; + } + + @Override public boolean nextBoolean() throws IOException { + expect(JsonToken.BOOLEAN); + boolean result = ((ByteTag) popStack()).getByte() != 0; + if (stackSize > 0) { + pathIndices[stackSize - 1]++; + } + return result; + } + + @Override public void nextNull() throws IOException { + expect(JsonToken.NULL); + popStack(); + if (stackSize > 0) { + pathIndices[stackSize - 1]++; + } + } + + @Override public double nextDouble() throws IOException { + JsonToken token = peek(); + if (token != JsonToken.NUMBER) { + throw new IllegalStateException( + "Expected " + JsonToken.NUMBER + " but was " + token + locationString()); + } + double result = ((AbstractNumberTag) peekStack()).getDouble(); + if (!isLenient() && (Double.isNaN(result) || Double.isInfinite(result))) { + throw new NumberFormatException("JSON forbids NaN and infinities: " + result); + } + popStack(); + if (stackSize > 0) { + pathIndices[stackSize - 1]++; + } + return result; + } + + @Override public long nextLong() throws IOException { + JsonToken token = peek(); + if (token != JsonToken.NUMBER) { + throw new IllegalStateException( + "Expected " + JsonToken.NUMBER + " but was " + token + locationString()); + } + long result = ((AbstractNumberTag) peekStack()).getLong(); + popStack(); + if (stackSize > 0) { + pathIndices[stackSize - 1]++; + } + return result; + } + + @Override public int nextInt() throws IOException { + JsonToken token = peek(); + if (token != JsonToken.NUMBER) { + throw new IllegalStateException( + "Expected " + JsonToken.NUMBER + " but was " + token + locationString()); + } + int result = ((AbstractNumberTag) peekStack()).getInt(); + popStack(); + if (stackSize > 0) { + pathIndices[stackSize - 1]++; + } + return result; + } + + @Override public void close() throws IOException { + stack = new Object[] { SENTINEL_CLOSED }; + stackSize = 1; + } + + @Override public void skipValue() throws IOException { + if (peek() == JsonToken.NAME) { + nextName(); + pathNames[stackSize - 2] = "null"; + } else { + popStack(); + pathNames[stackSize - 1] = "null"; + } + pathIndices[stackSize - 1]++; + } + + @Override public String toString() { + return getClass().getSimpleName(); + } + + private void push(Object newTop) { + if (stackSize == stack.length) { + Object[] newStack = new Object[stackSize * 2]; + int[] newPathIndices = new int[stackSize * 2]; + String[] newPathNames = new String[stackSize * 2]; + System.arraycopy(stack, 0, newStack, 0, stackSize); + System.arraycopy(pathIndices, 0, newPathIndices, 0, stackSize); + System.arraycopy(pathNames, 0, newPathNames, 0, stackSize); + stack = newStack; + pathIndices = newPathIndices; + pathNames = newPathNames; + } + stack[stackSize++] = newTop; + } + + @Override public String getPath() { + StringBuilder result = new StringBuilder().append('$'); + for (int i = 0; i < stackSize; i++) { + if (stack[i] instanceof CompoundTag) { + if (stack[++i] instanceof Iterator) { + result.append('[').append(pathIndices[i]).append(']'); + } + } else if (stack[i] instanceof ListTag) { + if (stack[++i] instanceof Iterator) { + result.append('.'); + if (pathNames[i] != null) { + result.append(pathNames[i]); + } + } + } + } + return result.toString(); + } + + private String locationString() { + return " at path " + getPath(); + } +} \ No newline at end of file diff --git a/src/main/java/org/dimdev/gsonnbt/NbtWriter.java b/src/main/java/org/dimdev/gsonnbt/NbtWriter.java new file mode 100644 index 00000000..ea39e3f9 --- /dev/null +++ b/src/main/java/org/dimdev/gsonnbt/NbtWriter.java @@ -0,0 +1,189 @@ +package org.dimdev.gsonnbt; + +import com.google.gson.JsonPrimitive; +import com.google.gson.stream.JsonWriter; +import net.minecraft.datafixer.NbtOps; +import net.minecraft.nbt.*; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.List; + +import static net.minecraft.datafixer.NbtOps.INSTANCE; + +public final class NbtWriter extends JsonWriter { + private static final Writer UNWRITABLE_WRITER = new Writer() { + @Override public void write(char[] buffer, int offset, int counter) { + throw new AssertionError(); + } + @Override public void flush() throws IOException {} + @Override public void close() throws IOException {} + }; + /** Added to the top of the stack when this writer is closed to cause following ops to fail. */ + private static final JsonPrimitive SENTINEL_CLOSED = new JsonPrimitive("closed"); + + /** The JsonElements and JsonArrays under modification, outermost to innermost. */ + private final List stack = new ArrayList<>(); + + /** The name for the next JSON object value. If non-null, the top of the stack is a JsonObject. */ + private String pendingName; + + /** the JSON element constructed by this writer. */ + private Tag product = EndTag.INSTANCE; // TODO: is this really what we want?; + + public NbtWriter() { + super(UNWRITABLE_WRITER); + } + + /** + * Returns the top level object produced by this writer. + */ + public Tag get() { + if (!stack.isEmpty()) { + throw new IllegalStateException("Expected one JSON element but was " + stack); + } + return product; + } + + private Tag peek() { + return stack.get(stack.size() - 1); + } + + private void put(Tag value) { + if (pendingName != null) { + if (!(value instanceof EndTag) || getSerializeNulls()) { + Tag element = peek(); + if (element instanceof CompoundTag) { + ((CompoundTag) element).put(pendingName, value); + } else { + throw new IllegalStateException(); + } + } + pendingName = null; + } else if (stack.isEmpty()) { + product = value; + } else { + Tag element = peek(); + if (element instanceof ListTag) { + ((ListTag) element).add(value); + } else { + throw new IllegalStateException(); + } + } + } + + @Override public JsonWriter beginArray() throws IOException { + ListTag array = new ListTag(); + put(array); + stack.add(array); + return this; + } + + @Override public JsonWriter endArray() throws IOException { + if (stack.isEmpty() || pendingName != null) { + throw new IllegalStateException(); + } + Tag element = peek(); + if (element instanceof ListTag) { + stack.remove(stack.size() - 1); + return this; + } + throw new IllegalStateException(); + } + + @Override public JsonWriter beginObject() throws IOException { + CompoundTag object = new CompoundTag(); + put(object); + stack.add(object); + return this; + } + + @Override public JsonWriter endObject() throws IOException { + if (stack.isEmpty() || pendingName != null) { + throw new IllegalStateException(); + } + Tag element = peek(); + if (element instanceof CompoundTag) { + stack.remove(stack.size() - 1); + return this; + } + throw new IllegalStateException(); + } + + @Override public JsonWriter name(String name) throws IOException { + if (stack.isEmpty() || pendingName != null) { + throw new IllegalStateException(); + } + Tag element = peek(); + if (element instanceof CompoundTag) { + pendingName = name; + return this; + } + throw new IllegalStateException(); + } + + @Override public JsonWriter value(String value) throws IOException { + if (value == null) { + return nullValue(); + } + put(INSTANCE.createString(value)); + return this; + } + + @Override public JsonWriter nullValue() throws IOException { + put(EndTag.INSTANCE); + return this; + } + + @Override public JsonWriter value(boolean value) throws IOException { + put(INSTANCE.createByte((byte)(value ? 1 : 0))); + return this; + } + + @Override public JsonWriter value(Boolean value) throws IOException { + value(new Byte((byte)(value ? 1 : 0))); + return this; + } + + @Override public JsonWriter value(double value) throws IOException { + if (!isLenient() && (Double.isNaN(value) || Double.isInfinite(value))) { + throw new IllegalArgumentException("NBT forbids NaN and infinities: " + value); + } + put(INSTANCE.createDouble(value)); + return this; + } + + @Override public JsonWriter value(long value) throws IOException { + put(INSTANCE.createLong(value)); + return this; + } + + @Override public JsonWriter value(Number value) throws IOException { + if (value == null) { + return nullValue(); + } + + if (!isLenient()) { + double d = value.doubleValue(); + if (Double.isNaN(d) || Double.isInfinite(d)) { + throw new IllegalArgumentException("NBT forbids NaN and infinities: " + value); + } + } + + if(value instanceof Byte) put(INSTANCE.createByte(value.byteValue())); + else if(value instanceof Double) put(INSTANCE.createDouble(value.doubleValue())); + else if(value instanceof Float) put(INSTANCE.createFloat(value.floatValue())); + else if(value instanceof Integer) put(INSTANCE.createInt(value.intValue())); + else if(value instanceof Short) put(INSTANCE.createShort(value.shortValue())); + else throw new IllegalArgumentException("NBT does not support " + value.getClass().getName()); + + return this; + } + + @Override public void flush() throws IOException { + } + + @Override public void close() throws IOException { + } +} \ No newline at end of file diff --git a/src/main/java/org/dimdev/util/TeleportUtil.java b/src/main/java/org/dimdev/util/TeleportUtil.java index dd070209..50258b1f 100644 --- a/src/main/java/org/dimdev/util/TeleportUtil.java +++ b/src/main/java/org/dimdev/util/TeleportUtil.java @@ -1,7 +1,10 @@ package org.dimdev.util; +import com.mojang.datafixers.DataFixerUpper; +import com.mojang.datafixers.Dynamic; import net.fabricmc.fabric.api.dimension.v1.FabricDimensions; import net.minecraft.block.pattern.BlockPattern; +import net.minecraft.datafixer.NbtOps; import net.minecraft.entity.Entity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -22,6 +25,7 @@ public final class TeleportUtil { entity.setPos(pos.x, pos.y, pos.z); entity.setYaw(entity.yaw + yawOffset); } else { + FabricDimensions.teleport( entity, dimension, diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 1b1d6ccb..8cd704c2 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -23,6 +23,9 @@ "entrypoints": { "main": [ "org.dimdev.dimdoors.DimensionalDoorsInitializer" + ], + "client": [ + "org.dimdev.dimdoors.DimensionalDoorsClientInitializer" ] }, "mixins": [