diff options
Diffstat (limited to 'src/main')
33 files changed, 1070 insertions, 8 deletions
diff --git a/src/main/generated/assets/funny-teleporters/lang/en_us.json b/src/main/generated/assets/funny-teleporters/lang/en_us.json new file mode 100644 index 0000000..2be8500 --- /dev/null +++ b/src/main/generated/assets/funny-teleporters/lang/en_us.json @@ -0,0 +1,7 @@ +{ + "block.funny-teleporters.coloured_chest": "Colored Chest", + "block.funny-teleporters.ender_pearl_block": "Block of Ender Pearl", + "block.funny-teleporters.teleporter": "Teleporter", + "block.funny-teleporters.teleporter_nexus": "Teleporter Nexus", + "item.funny-teleporters.teleporter_wand": "Teleporter Wand" +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/advancement/recipes/building_blocks/ender_pearl_block.json b/src/main/generated/data/funny-teleporters/advancement/recipes/building_blocks/ender_pearl_block.json new file mode 100644 index 0000000..808f17f --- /dev/null +++ b/src/main/generated/data/funny-teleporters/advancement/recipes/building_blocks/ender_pearl_block.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_ender_pearl": { + "conditions": { + "items": [ + { + "items": "minecraft:ender_pearl" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "funny-teleporters:ender_pearl_block" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_ender_pearl" + ] + ], + "rewards": { + "recipes": [ + "funny-teleporters:ender_pearl_block" + ] + } +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/advancement/recipes/misc/ender_pearl.json b/src/main/generated/data/funny-teleporters/advancement/recipes/misc/ender_pearl.json new file mode 100644 index 0000000..814d3bf --- /dev/null +++ b/src/main/generated/data/funny-teleporters/advancement/recipes/misc/ender_pearl.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_ender_pearl_block": { + "conditions": { + "items": [ + { + "items": "funny-teleporters:ender_pearl_block" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:ender_pearl" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_ender_pearl_block" + ] + ], + "rewards": { + "recipes": [ + "minecraft:ender_pearl" + ] + } +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/advancement/recipes/tools/teleporter_wand.json b/src/main/generated/data/funny-teleporters/advancement/recipes/tools/teleporter_wand.json new file mode 100644 index 0000000..e638f81 --- /dev/null +++ b/src/main/generated/data/funny-teleporters/advancement/recipes/tools/teleporter_wand.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_ender_pearl": { + "conditions": { + "items": [ + { + "items": "minecraft:ender_pearl" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "funny-teleporters:teleporter_wand" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_ender_pearl" + ] + ], + "rewards": { + "recipes": [ + "funny-teleporters:teleporter_wand" + ] + } +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/advancement/recipes/transportation/teleporter.json b/src/main/generated/data/funny-teleporters/advancement/recipes/transportation/teleporter.json new file mode 100644 index 0000000..c2a5ba2 --- /dev/null +++ b/src/main/generated/data/funny-teleporters/advancement/recipes/transportation/teleporter.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_ender_pearl_block": { + "conditions": { + "items": [ + { + "items": "funny-teleporters:ender_pearl_block" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "funny-teleporters:teleporter" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_ender_pearl_block" + ] + ], + "rewards": { + "recipes": [ + "funny-teleporters:teleporter" + ] + } +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/advancement/recipes/transportation/teleporter_nexus.json b/src/main/generated/data/funny-teleporters/advancement/recipes/transportation/teleporter_nexus.json new file mode 100644 index 0000000..08cdac3 --- /dev/null +++ b/src/main/generated/data/funny-teleporters/advancement/recipes/transportation/teleporter_nexus.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_teleporter": { + "conditions": { + "items": [ + { + "items": "funny-teleporters:teleporter" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "funny-teleporters:teleporter_nexus" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_teleporter" + ] + ], + "rewards": { + "recipes": [ + "funny-teleporters:teleporter_nexus" + ] + } +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/loot_table/blocks/ender_pearl_block.json b/src/main/generated/data/funny-teleporters/loot_table/blocks/ender_pearl_block.json new file mode 100644 index 0000000..885ed02 --- /dev/null +++ b/src/main/generated/data/funny-teleporters/loot_table/blocks/ender_pearl_block.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "funny-teleporters:ender_pearl_block" + } + ], + "rolls": 1.0 + } + ] +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/loot_table/blocks/teleporter.json b/src/main/generated/data/funny-teleporters/loot_table/blocks/teleporter.json new file mode 100644 index 0000000..01a4ca5 --- /dev/null +++ b/src/main/generated/data/funny-teleporters/loot_table/blocks/teleporter.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "funny-teleporters:teleporter" + } + ], + "rolls": 1.0 + } + ] +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/loot_table/blocks/teleporter_nexus.json b/src/main/generated/data/funny-teleporters/loot_table/blocks/teleporter_nexus.json new file mode 100644 index 0000000..be31823 --- /dev/null +++ b/src/main/generated/data/funny-teleporters/loot_table/blocks/teleporter_nexus.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "funny-teleporters:teleporter_nexus" + } + ], + "rolls": 1.0 + } + ] +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/recipe/ender_pearl.json b/src/main/generated/data/funny-teleporters/recipe/ender_pearl.json new file mode 100644 index 0000000..2a77678 --- /dev/null +++ b/src/main/generated/data/funny-teleporters/recipe/ender_pearl.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { + "item": "funny-teleporters:ender_pearl_block" + } + ], + "result": { + "count": 9, + "id": "minecraft:ender_pearl" + } +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/recipe/ender_pearl_block.json b/src/main/generated/data/funny-teleporters/recipe/ender_pearl_block.json new file mode 100644 index 0000000..cbeb675 --- /dev/null +++ b/src/main/generated/data/funny-teleporters/recipe/ender_pearl_block.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "e": { + "item": "minecraft:ender_pearl" + } + }, + "pattern": [ + "eee", + "eee", + "eee" + ], + "result": { + "count": 1, + "id": "funny-teleporters:ender_pearl_block" + } +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/recipe/teleporter.json b/src/main/generated/data/funny-teleporters/recipe/teleporter.json new file mode 100644 index 0000000..85fda2d --- /dev/null +++ b/src/main/generated/data/funny-teleporters/recipe/teleporter.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "e": { + "item": "funny-teleporters:ender_pearl_block" + }, + "o": { + "item": "minecraft:obsidian" + } + }, + "pattern": [ + "ooo", + "oeo", + "ooo" + ], + "result": { + "count": 1, + "id": "funny-teleporters:teleporter" + } +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/recipe/teleporter_nexus.json b/src/main/generated/data/funny-teleporters/recipe/teleporter_nexus.json new file mode 100644 index 0000000..651883f --- /dev/null +++ b/src/main/generated/data/funny-teleporters/recipe/teleporter_nexus.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "e": { + "item": "minecraft:enchanting_table" + }, + "p": { + "item": "funny-teleporters:ender_pearl_block" + }, + "t": { + "item": "funny-teleporters:teleporter" + } + }, + "pattern": [ + " e ", + "ptp", + "ttt" + ], + "result": { + "count": 1, + "id": "funny-teleporters:teleporter_nexus" + } +}
\ No newline at end of file diff --git a/src/main/generated/data/funny-teleporters/recipe/teleporter_wand.json b/src/main/generated/data/funny-teleporters/recipe/teleporter_wand.json new file mode 100644 index 0000000..0d92775 --- /dev/null +++ b/src/main/generated/data/funny-teleporters/recipe/teleporter_wand.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "equipment", + "key": { + "e": { + "item": "funny-teleporters:ender_pearl_block" + }, + "r": { + "item": "minecraft:redstone_block" + }, + "s": { + "item": "minecraft:stick" + } + }, + "pattern": [ + " e", + " r ", + "s " + ], + "result": { + "count": 1, + "id": "funny-teleporters:teleporter_wand" + } +}
\ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/block/mineable/hoe.json b/src/main/generated/data/minecraft/tags/block/mineable/hoe.json new file mode 100644 index 0000000..24ba276 --- /dev/null +++ b/src/main/generated/data/minecraft/tags/block/mineable/hoe.json @@ -0,0 +1,5 @@ +{ + "values": [ + "funny-teleporters:ender_pearl_block" + ] +}
\ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/block/mineable/pickaxe.json b/src/main/generated/data/minecraft/tags/block/mineable/pickaxe.json index f126a94..1d36055 100644 --- a/src/main/generated/data/minecraft/tags/block/mineable/pickaxe.json +++ b/src/main/generated/data/minecraft/tags/block/mineable/pickaxe.json @@ -1,5 +1,7 @@ { "values": [ - "funny-teleporters:coloured_chest" + "funny-teleporters:coloured_chest", + "funny-teleporters:teleporter", + "funny-teleporters:teleporter_nexus" ] }
\ No newline at end of file diff --git a/src/main/java/moe/nea/funnyteleporters/ColouredChestViewScreen.java b/src/main/java/moe/nea/funnyteleporters/ColouredChestViewScreen.java index 21d8c8a..4e1a769 100644 --- a/src/main/java/moe/nea/funnyteleporters/ColouredChestViewScreen.java +++ b/src/main/java/moe/nea/funnyteleporters/ColouredChestViewScreen.java @@ -3,7 +3,6 @@ package moe.nea.funnyteleporters; import eu.pb4.sgui.api.ClickType; import eu.pb4.sgui.api.elements.GuiElementInterface; import eu.pb4.sgui.api.gui.SimpleGui; -import net.minecraft.component.DataComponentTypes; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.screen.ScreenHandlerType; @@ -12,7 +11,6 @@ import net.minecraft.screen.slot.SlotActionType; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.DyeColor; -import net.minecraft.util.Unit; import java.util.stream.Collectors; @@ -36,10 +34,7 @@ public class ColouredChestViewScreen extends SimpleGui { void setSlots() { for (int i = 1; i < 9; i++) { - var s = new ItemStack(Items.BLACK_STAINED_GLASS_PANE); - s.set(DataComponentTypes.CUSTOM_NAME, Text.empty()); - s.set(DataComponentTypes.HIDE_TOOLTIP, Unit.INSTANCE); - setSlot(i, s); + setSlot(i, Utils.createBlankBlack()); } setSlot(0, new ItemStack(Items.ARROW)); for (int i = 0; i < 27; i++) { diff --git a/src/main/java/moe/nea/funnyteleporters/FunnyDataGenerator.java b/src/main/java/moe/nea/funnyteleporters/FunnyDataGenerator.java index b4c8b85..8417730 100644 --- a/src/main/java/moe/nea/funnyteleporters/FunnyDataGenerator.java +++ b/src/main/java/moe/nea/funnyteleporters/FunnyDataGenerator.java @@ -10,6 +10,7 @@ public class FunnyDataGenerator implements DataGeneratorEntrypoint { pack.addProvider(FunnyRecipeProvider::new); pack.addProvider(FunnyDropTableProvider::new); pack.addProvider(FunnyTagGenerator::new); + pack.addProvider(FunnyTranslationProvider::new); } } diff --git a/src/main/java/moe/nea/funnyteleporters/FunnyDropTableProvider.java b/src/main/java/moe/nea/funnyteleporters/FunnyDropTableProvider.java index cf2643a..b93424d 100644 --- a/src/main/java/moe/nea/funnyteleporters/FunnyDropTableProvider.java +++ b/src/main/java/moe/nea/funnyteleporters/FunnyDropTableProvider.java @@ -14,5 +14,8 @@ public class FunnyDropTableProvider extends FabricBlockLootTableProvider { @Override public void generate() { addDrop(FunnyRegistry.COLOURED_CHEST); + addDrop(FunnyRegistry.ENDER_PEARL_BLOCK); + addDrop(FunnyRegistry.TELEPORTER); + addDrop(FunnyRegistry.TELEPORTER_NEXUS); } } diff --git a/src/main/java/moe/nea/funnyteleporters/FunnyRecipeProvider.java b/src/main/java/moe/nea/funnyteleporters/FunnyRecipeProvider.java index 5b7ee14..d59eea0 100644 --- a/src/main/java/moe/nea/funnyteleporters/FunnyRecipeProvider.java +++ b/src/main/java/moe/nea/funnyteleporters/FunnyRecipeProvider.java @@ -3,6 +3,7 @@ package moe.nea.funnyteleporters; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; import net.minecraft.item.Items; import net.minecraft.recipe.book.RecipeCategory; @@ -23,5 +24,42 @@ public class FunnyRecipeProvider extends FabricRecipeProvider { .criterion(hasItem(Items.ENDER_CHEST), conditionsFromItem(Items.ENDER_CHEST)) .offerTo(recipeExporter); + ShapedRecipeJsonBuilder.create(RecipeCategory.BUILDING_BLOCKS, FunnyRegistry.ENDER_PEARL_BLOCK) + .pattern("eee").pattern("eee").pattern("eee") + .input('e', Items.ENDER_PEARL) + .criterion(hasItem(Items.ENDER_PEARL), conditionsFromItem(Items.ENDER_PEARL)) + .offerTo(recipeExporter); + + ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, Items.ENDER_PEARL, 9) + .input(FunnyRegistry.ENDER_PEARL_BLOCK) + .criterion(hasItem(FunnyRegistry.ENDER_PEARL_BLOCK), conditionsFromItem(FunnyRegistry.ENDER_PEARL_BLOCK)) + .offerTo(recipeExporter); + ShapedRecipeJsonBuilder.create(RecipeCategory.TRANSPORTATION, FunnyRegistry.TELEPORTER) + .pattern("ooo") + .pattern("oeo") + .pattern("ooo") + .input('o', Items.OBSIDIAN) + .input('e', FunnyRegistry.ENDER_PEARL_BLOCK) + .criterion(hasItem(FunnyRegistry.ENDER_PEARL_BLOCK), conditionsFromItem(FunnyRegistry.ENDER_PEARL_BLOCK)) + .offerTo(recipeExporter); + ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, FunnyRegistry.TELEPORTER_WAND) + .pattern(" e") + .pattern(" r ") + .pattern("s ") + .input('e', FunnyRegistry.ENDER_PEARL_BLOCK) + .input('r', Items.REDSTONE_BLOCK) + .input('s', Items.STICK) + .criterion(hasItem(Items.ENDER_PEARL), conditionsFromItem(Items.ENDER_PEARL)) + .offerTo(recipeExporter); + + ShapedRecipeJsonBuilder.create(RecipeCategory.TRANSPORTATION, FunnyRegistry.TELEPORTER_NEXUS) + .pattern(" e ") + .pattern("ptp") + .pattern("ttt") + .input('e', Items.ENCHANTING_TABLE) + .input('p', FunnyRegistry.ENDER_PEARL_BLOCK) + .input('t', FunnyRegistry.TELEPORTER) + .criterion(hasItem(FunnyRegistry.TELEPORTER), conditionsFromItem(FunnyRegistry.TELEPORTER)) + .offerTo(recipeExporter); } } diff --git a/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java b/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java index 498adf5..2da8233 100644 --- a/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java +++ b/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java @@ -1,12 +1,17 @@ package moe.nea.funnyteleporters; +import com.mojang.serialization.Codec; import eu.pb4.polymer.core.api.block.PolymerBlockUtils; +import eu.pb4.polymer.core.api.block.SimplePolymerBlock; import eu.pb4.polymer.core.api.item.PolymerBlockItem; +import eu.pb4.polymer.rsm.api.RegistrySyncUtils; import net.minecraft.block.AbstractBlock; import net.minecraft.block.Block; +import net.minecraft.block.Blocks; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.piston.PistonBehavior; +import net.minecraft.component.ComponentType; import net.minecraft.item.Item; import net.minecraft.item.Items; import net.minecraft.registry.Registries; @@ -17,8 +22,28 @@ public class FunnyRegistry { public static Block COLOURED_CHEST = registerBlock("coloured_chest", new ColouredChestBlock(AbstractBlock.Settings.create() .pistonBehavior(PistonBehavior.PUSH_ONLY) .strength(50.0F, 1200.0F)), Items.REINFORCED_DEEPSLATE); + public static Block ENDER_PEARL_BLOCK = registerBlock("ender_pearl_block", new SimplePolymerBlock(AbstractBlock.Settings.create() + .strength(10F), Blocks.GREEN_WOOL), Items.GREEN_WOOL); + + public static TeleporterBlock TELEPORTER = registerBlock("teleporter", new TeleporterBlock(AbstractBlock.Settings.create() + .pistonBehavior(PistonBehavior.BLOCK) + .strength(50F, 1200F)), Items.SEA_LANTERN); + + public static TeleporterNexus TELEPORTER_NEXUS = registerBlock("teleporter_nexus", new TeleporterNexus(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.BLOCK).strength(100F, 1200F)), Items.ENCHANTING_TABLE); + + public static ComponentType<TeleporterDestination> TELEPORTER_DESTINATION = registerComponentType("teleporter_destination", TeleporterDestination.CODEC); + + public static BlockEntityType<ColouredChestBlockEntity> COLOURED_CHEST_ENTITY = registerBlockEntity("coloured_chest", BlockEntityType.Builder.create(ColouredChestBlockEntity::new, COLOURED_CHEST)); + public static BlockEntityType<TeleporterBlockEntity> TELEPORTER_ENTITY = registerBlockEntity("teleporter", BlockEntityType.Builder.create(TeleporterBlockEntity::new, TELEPORTER)); + public static TeleporterWand TELEPORTER_WAND = registerItem("teleporter_wand", new TeleporterWand(new Item.Settings().maxCount(1))); + public static BlockEntityType<TeleporterNexusBlockEntity> TELEPORTER_NEXUS_ENTITY = registerBlockEntity("teleporter_nexus", BlockEntityType.Builder.create(TeleporterNexusBlockEntity::new, TELEPORTER_NEXUS)); + private static <T> ComponentType<T> registerComponentType(String name, Codec<T> codec) { + var comp = Registry.register(Registries.DATA_COMPONENT_TYPE, FunnyTeleporters.id(name), ComponentType.<T>builder().codec(codec).build()); + RegistrySyncUtils.setServerEntry(Registries.DATA_COMPONENT_TYPE, comp); + return comp; + } private static <T extends BlockEntity> BlockEntityType<T> registerBlockEntity(String name, BlockEntityType.Builder<T> builder) { var be = Registry.register(Registries.BLOCK_ENTITY_TYPE, @@ -29,6 +54,10 @@ public class FunnyRegistry { return be; } + private static <T extends Item> T registerItem(String name, T item) { + return Registry.register(Registries.ITEM, FunnyTeleporters.id(name), item); + } + private static <T extends Block> T registerBlock(String name, T block, Item blockItem) { var id = Identifier.of(FunnyTeleporters.MOD_ID, name); Registry.register(Registries.ITEM, id, new PolymerBlockItem(block, new Item.Settings(), blockItem)); diff --git a/src/main/java/moe/nea/funnyteleporters/FunnyTagGenerator.java b/src/main/java/moe/nea/funnyteleporters/FunnyTagGenerator.java index 338b8d1..a51e311 100644 --- a/src/main/java/moe/nea/funnyteleporters/FunnyTagGenerator.java +++ b/src/main/java/moe/nea/funnyteleporters/FunnyTagGenerator.java @@ -15,6 +15,11 @@ public class FunnyTagGenerator extends FabricTagProvider.BlockTagProvider { @Override protected void configure(RegistryWrapper.WrapperLookup wrapperLookup) { - getTagBuilder(BlockTags.PICKAXE_MINEABLE).add(Registries.BLOCK.getId(FunnyRegistry.COLOURED_CHEST)); + getTagBuilder(BlockTags.PICKAXE_MINEABLE) + .add(Registries.BLOCK.getId(FunnyRegistry.COLOURED_CHEST)) + .add(Registries.BLOCK.getId(FunnyRegistry.TELEPORTER)) + .add(Registries.BLOCK.getId(FunnyRegistry.TELEPORTER_NEXUS)); + getTagBuilder(BlockTags.HOE_MINEABLE) + .add(Registries.BLOCK.getId(FunnyRegistry.ENDER_PEARL_BLOCK)); } } diff --git a/src/main/java/moe/nea/funnyteleporters/FunnyTranslationProvider.java b/src/main/java/moe/nea/funnyteleporters/FunnyTranslationProvider.java new file mode 100644 index 0000000..4cdc995 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/FunnyTranslationProvider.java @@ -0,0 +1,22 @@ +package moe.nea.funnyteleporters; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider; +import net.minecraft.registry.RegistryWrapper; + +import java.util.concurrent.CompletableFuture; + +public class FunnyTranslationProvider extends FabricLanguageProvider { + protected FunnyTranslationProvider(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) { + super(dataOutput, "en_us", registryLookup); + } + + @Override + public void generateTranslations(RegistryWrapper.WrapperLookup wrapperLookup, TranslationBuilder translationBuilder) { + translationBuilder.add(FunnyRegistry.ENDER_PEARL_BLOCK, "Block of Ender Pearl"); + translationBuilder.add(FunnyRegistry.TELEPORTER, "Teleporter"); + translationBuilder.add(FunnyRegistry.TELEPORTER_NEXUS, "Teleporter Nexus"); + translationBuilder.add(FunnyRegistry.COLOURED_CHEST, "Colored Chest"); + translationBuilder.add(FunnyRegistry.TELEPORTER_WAND, "Teleporter Wand"); + } +} diff --git a/src/main/java/moe/nea/funnyteleporters/TeleporterBlock.java b/src/main/java/moe/nea/funnyteleporters/TeleporterBlock.java new file mode 100644 index 0000000..45d88e8 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterBlock.java @@ -0,0 +1,42 @@ +package moe.nea.funnyteleporters; + +import eu.pb4.polymer.core.api.block.PolymerBlock; +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockEntityProvider; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.RespawnAnchorBlock; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityTicker; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +public class TeleporterBlock extends Block implements PolymerBlock, BlockEntityProvider { + public TeleporterBlock(AbstractBlock.Settings settings) { + super(settings); + } + + @Override + public BlockState getPolymerBlockState(BlockState blockState) { + return Blocks.RESPAWN_ANCHOR.getDefaultState().with(RespawnAnchorBlock.CHARGES, RespawnAnchorBlock.MAX_CHARGES); + } + + public TeleporterBlockEntity getBE(World world, BlockPos pos) { + return ((TeleporterBlockEntity) Objects.requireNonNull(world.getBlockEntity(pos))); + } + + @Override + public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) { + return TeleporterBlockEntity::tick; + } + + @Override + public TeleporterBlockEntity createBlockEntity(BlockPos pos, BlockState state) { + return new TeleporterBlockEntity(pos, state); + } +} diff --git a/src/main/java/moe/nea/funnyteleporters/TeleporterBlockEntity.java b/src/main/java/moe/nea/funnyteleporters/TeleporterBlockEntity.java new file mode 100644 index 0000000..2cc452c --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterBlockEntity.java @@ -0,0 +1,109 @@ +package moe.nea.funnyteleporters; + +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.Entity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtOps; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.util.TypeFilter; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.HashSet; +import java.util.Set; + +public class TeleporterBlockEntity extends BlockEntity { + public TeleporterBlockEntity(BlockPos pos, BlockState state) { + this(FunnyRegistry.TELEPORTER_ENTITY, pos, state); + } + + protected TeleporterBlockEntity(BlockEntityType<? extends TeleporterBlockEntity> type, BlockPos pos, BlockState state) { + super(type, pos, state); + } + + public static <T extends BlockEntity> void tick(World world, BlockPos blockPos, BlockState blockState, T t) { + ((TeleporterBlockEntity) t).doTick(world, blockPos, blockState); + } + + private void doTick(World world, BlockPos blockPos, BlockState blockState) { + var up = blockPos.up(); + var newEntities = new HashSet<>(world.getEntitiesByType(TypeFilter.instanceOf(Entity.class), Box.enclosing(up, up), entity -> true)); + for (Entity entity : newEntities) { + var ref = new Ref(entity); + if (incomingEntities.remove(ref)) { + trackedEntities.remove(entity); + continue; + } + if (!trackedEntities.contains(entity)) { + performTeleport(entity); + } + } + trackedEntities = newEntities; + while (true) { + var ref = (Ref) refQueue.poll(); + if (ref == null) break; + incomingEntities.remove(ref); + } + } + + @Override + protected void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { + super.writeNbt(nbt, registryLookup); + if (destination != null) { + nbt.put("destination", TeleporterDestination.CODEC.encodeStart(NbtOps.INSTANCE, destination).getPartialOrThrow()); + } + } + + @Override + protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { + super.readNbt(nbt, registryLookup); + if (nbt.contains("destination")) { + var result = TeleporterDestination.CODEC.decode(NbtOps.INSTANCE, nbt.getCompound("destination")); + if (result.hasResultOrPartial()) { + destination = result.getPartialOrThrow().getFirst(); + } + } + } + + class Ref extends WeakReference<Entity> { + public Ref(Entity referent) { + super(referent, refQueue); + hash = System.identityHashCode(referent); + } + + int hash; + + @Override + public int hashCode() { + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Ref ref) { + return ref.hash == this.hash && ref.get() == this.get(); + } + return false; + } + } + + private final ReferenceQueue<Entity> refQueue = new ReferenceQueue<>(); + Set<Entity> trackedEntities = new HashSet<>(); + Set<Ref> incomingEntities = new HashSet<>(); + @Nullable TeleporterDestination destination; + + void performTeleport(Entity subject) { + if (destination == null) return; + destination.teleport(subject); + } + + public void addIncoming(Entity subject) { + incomingEntities.add(new Ref(subject)); + } +} diff --git a/src/main/java/moe/nea/funnyteleporters/TeleporterDestination.java b/src/main/java/moe/nea/funnyteleporters/TeleporterDestination.java new file mode 100644 index 0000000..482bc49 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterDestination.java @@ -0,0 +1,62 @@ +package moe.nea.funnyteleporters; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.entity.Entity; +import net.minecraft.item.Item; +import net.minecraft.registry.Registries; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.Identifier; +import net.minecraft.util.dynamic.Codecs; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.jetbrains.annotations.NotNull; + +import java.util.Comparator; +import java.util.Optional; +import java.util.Set; + +public record TeleporterDestination( + RegistryKey<World> target, + BlockPos blockPos +) implements Comparable<TeleporterDestination> { + public static Comparator<TeleporterDestination> COMPARATOR = + Comparator.<TeleporterDestination, Identifier>comparing(it -> it.target().getValue()) + .thenComparing(TeleporterDestination::blockPos); + + @Override + public int compareTo(@NotNull TeleporterDestination o) { + return COMPARATOR.compare(this, o); + } + + public void teleport(Entity subject) { + var sourceWorld = subject.getWorld(); + var destinationWorld = getDestinationWorld((ServerWorld) sourceWorld); + if (destinationWorld == null) return; + var destinationBE = destinationWorld.getBlockEntity(blockPos()); + if (!(destinationBE instanceof TeleporterBlockEntity be)) { + return; + } + be.addIncoming(subject); + var destPos = blockPos().up().toBottomCenterPos(); + subject.teleport(destinationWorld, destPos.x, destPos.y, destPos.z, Set.of(), subject.getYaw(), subject.getPitch()); + } + + public record Labeled(RegistryEntry<Item> item, TeleporterDestination destination, Optional<String> name) { + public static Codec<Labeled> CODEC = RecordCodecBuilder.create(instance -> instance.group( + Registries.ITEM.getEntryCodec().fieldOf("item").forGetter(Labeled::item), + TeleporterDestination.CODEC.fieldOf("destination").forGetter(Labeled::destination), + Codec.STRING.optionalFieldOf("name").forGetter(Labeled::name) + ).apply(instance, Labeled::new)); + } + + public ServerWorld getDestinationWorld(ServerWorld world) { + return world.getServer().getWorld(target); + } + + public static Codec<TeleporterDestination> CODEC = RecordCodecBuilder.create(instance -> instance.group(RegistryKey.createCodec(RegistryKeys.WORLD).fieldOf("dim").forGetter(TeleporterDestination::target), BlockPos.CODEC.fieldOf("pos").forGetter(TeleporterDestination::blockPos)).apply(instance, TeleporterDestination::new)); +} diff --git a/src/main/java/moe/nea/funnyteleporters/TeleporterNexus.java b/src/main/java/moe/nea/funnyteleporters/TeleporterNexus.java new file mode 100644 index 0000000..26c5382 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterNexus.java @@ -0,0 +1,42 @@ +package moe.nea.funnyteleporters; + +import eu.pb4.polymer.core.api.block.PolymerBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockEntityProvider; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.ActionResult; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +public class TeleporterNexus extends Block implements PolymerBlock, BlockEntityProvider { + public TeleporterNexus(Settings settings) { + super(settings); + } + + @Override + public @Nullable TeleporterNexusBlockEntity createBlockEntity(BlockPos pos, BlockState state) { + return new TeleporterNexusBlockEntity(pos, state); + } + + public TeleporterNexusBlockEntity getBE(World world, BlockPos pos) { + return (TeleporterNexusBlockEntity) Objects.requireNonNull(world.getBlockEntity(pos)); + } + + @Override + public BlockState getPolymerBlockState(BlockState blockState) { + return Blocks.ENCHANTING_TABLE.getDefaultState(); + } + + @Override + protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { + new TeleporterNexusScreen(getBE(world, pos), (ServerPlayerEntity) player).open(); + return ActionResult.SUCCESS_NO_ITEM_USED; + } +} diff --git a/src/main/java/moe/nea/funnyteleporters/TeleporterNexusBlockEntity.java b/src/main/java/moe/nea/funnyteleporters/TeleporterNexusBlockEntity.java new file mode 100644 index 0000000..dbc8150 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterNexusBlockEntity.java @@ -0,0 +1,96 @@ +package moe.nea.funnyteleporters; + +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Codec; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.item.Item; +import net.minecraft.item.ItemConvertible; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtOps; +import net.minecraft.registry.Registries; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.math.BlockPos; + +import java.util.Optional; +import java.util.TreeMap; + +public class TeleporterNexusBlockEntity extends BlockEntity { + public TeleporterNexusBlockEntity(BlockPos pos, BlockState state) {this(FunnyRegistry.TELEPORTER_NEXUS_ENTITY, pos, state);} + + protected TeleporterNexusBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) { + super(type, pos, state); + } + + public Optional<String> getName(TeleporterDestination dest) { + var label = destinations.get(dest); + return label != null ? (label.label) : Optional.empty(); + } + + public ItemConvertible getIcon(TeleporterDestination dest) { + var label = destinations.get(dest); + return (label != null ? label.item : getDefaultItem()).value(); + } + + public record Label( + RegistryEntry<Item> item, + Optional<String> label + ) { + } + + public TreeMap<TeleporterDestination, Label> destinations = new TreeMap<>(); + private static final Codec<TreeMap<TeleporterDestination, Label>> DESTINATION_CODEC = + TeleporterDestination.Labeled.CODEC + .listOf() + .xmap( + pairs -> { + var hash = new TreeMap<TeleporterDestination, Label>(); + for (TeleporterDestination.Labeled pair : pairs) { + hash.put(pair.destination(), new Label(pair.item(), pair.name())); + } + return hash; + }, + map -> map.entrySet().stream().map(it -> new TeleporterDestination.Labeled(it.getValue().item(), it.getKey(), it.getValue().label())).toList() + ); + + static RegistryEntry<Item> getDefaultItem() { + return Registries.ITEM.getEntry(Items.ENDER_PEARL); + } + + @Override + protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { + super.readNbt(nbt, registryLookup); + var result = DESTINATION_CODEC.decode(registryLookup.getOps(NbtOps.INSTANCE), nbt.get("destinations")); + result.resultOrPartial().map(Pair::getFirst).ifPresent(it -> destinations = it); + } + + @Override + protected void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { + super.writeNbt(nbt, registryLookup); + nbt.put("destinations", DESTINATION_CODEC.encodeStart(registryLookup.getOps(NbtOps.INSTANCE), destinations).getPartialOrThrow()); + } + + public void addDestination(TeleporterDestination destination) { + destinations.putIfAbsent(destination, new Label(getDefaultItem(), Optional.empty())); + markDirty(); + } + + public void removeDestination(TeleporterDestination destination) { + destinations.remove(destination); + markDirty(); + } + + public void setIcon(TeleporterDestination dest, Item item) { + var entry = Registries.ITEM.getEntry(item); + destinations.compute(dest, (key, old) -> old == null ? new Label(entry, Optional.empty()) : new Label(entry, old.label())); + markDirty(); + } + + public void setName(TeleporterDestination dest, Optional<String> string) { + destinations.compute(dest, (key, old) -> old == null ? new Label(getDefaultItem(), string) : new Label(old.item(), string)); + markDirty(); + } +} diff --git a/src/main/java/moe/nea/funnyteleporters/TeleporterNexusEditorScreen.java b/src/main/java/moe/nea/funnyteleporters/TeleporterNexusEditorScreen.java new file mode 100644 index 0000000..7fe55a6 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterNexusEditorScreen.java @@ -0,0 +1,86 @@ +package moe.nea.funnyteleporters; + +import eu.pb4.sgui.api.ClickType; +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.gui.SimpleGui; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.registry.Registries; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class TeleporterNexusEditorScreen extends SimpleGui { + final TeleporterNexusBlockEntity blockEntity; + final TeleporterDestination dest; + + public TeleporterNexusEditorScreen(TeleporterNexusBlockEntity blockEntity, TeleporterDestination dest, ServerPlayerEntity player) { + super(ScreenHandlerType.GENERIC_9X3, player, false); + this.blockEntity = blockEntity; + this.dest = dest; + setSlots(); + } + + void setSlots() { + setTitle(Text.literal("Set Icon for " + blockEntity.getName(dest).orElse("teleporter"))); + for (int i = 0; i < width * height; i++) { + setSlot(i, Utils.createBlankBlack()); + } + setSlot(4 + 9, + GuiElementBuilder.from(new ItemStack(blockEntity.getIcon(dest))) + .setName(Text.literal("Click item in your inventory to set icon."))); + setSlot(2 + 9, + GuiElementBuilder.from(new ItemStack(Items.OAK_SIGN)) + .setName(Text.literal("Click here to change name")) + .addLoreLine(Text.literal("Click here to set a name for the teleport destination") + .setStyle(Utils.colouredLoreStyle(Formatting.AQUA))) + .setCallback(this::handleNameChange)); + setSlot(9 + 6, + GuiElementBuilder.from(new ItemStack(Items.BARRIER)) + .setName(Text.literal("Delete").withColor(0xFFFF0000)) + .addLoreLine(Text.literal("Shift-Click here to remove this location") + .setStyle(Utils.colouredLoreStyle(Formatting.RED))) + .addLoreLine(Text.literal("from the teleport nexus") + .setStyle(Utils.colouredLoreStyle(Formatting.RED))) + .setCallback(this::handleDelete)); + } + + void handleNameChange() { + new TeleporterNexusNameEditorScreen(this).open(); + } + + void handleDelete(ClickType clickType) { + if (clickType == ClickType.MOUSE_LEFT_SHIFT) { + blockEntity.removeDestination(dest); + back(); + } else { + player.sendMessage(Text.literal("You need to shift click to delete locations.")); + } + } + + @Override + public void onClose() { + back(); + } + + void back() { + new TeleporterNexusScreen(blockEntity, player).open(); + } + + @Override + public boolean onAnyClick(int index, ClickType type, SlotActionType action) { + var slot = getSlotRedirectOrPlayer(index); + if (slot == null) return true; + var stack = slot.getStack(); + if (!stack.isEmpty()) { + blockEntity.setIcon(dest, stack.getItem()); + setSlots(); + if (screenHandler != null) + screenHandler.syncState(); + } + return false; + } +} diff --git a/src/main/java/moe/nea/funnyteleporters/TeleporterNexusNameEditorScreen.java b/src/main/java/moe/nea/funnyteleporters/TeleporterNexusNameEditorScreen.java new file mode 100644 index 0000000..f4d33ea --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterNexusNameEditorScreen.java @@ -0,0 +1,29 @@ +package moe.nea.funnyteleporters; + +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.gui.AnvilInputGui; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.text.Text; + +import java.util.Optional; + +public class TeleporterNexusNameEditorScreen extends AnvilInputGui { + private final TeleporterNexusEditorScreen previous; + + public TeleporterNexusNameEditorScreen(TeleporterNexusEditorScreen previous) { + super(previous.getPlayer(), false); + this.previous = previous; + setTitle(Text.literal("Edit Name")); + setSlot(2, GuiElementBuilder.from(new ItemStack(Items.OAK_SIGN)) + .setName(Text.literal("Click here to save")) + .setCallback(this::save)); + setDefaultInputValue(previous.blockEntity.getName(previous.dest).orElse("")); + } + + void save() { + previous.blockEntity.setName(previous.dest, Optional.of(getInput())); + previous.setSlots(); + previous.open(); + } +} diff --git a/src/main/java/moe/nea/funnyteleporters/TeleporterNexusScreen.java b/src/main/java/moe/nea/funnyteleporters/TeleporterNexusScreen.java new file mode 100644 index 0000000..4a9088e --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterNexusScreen.java @@ -0,0 +1,85 @@ +package moe.nea.funnyteleporters; + +import eu.pb4.sgui.api.ClickType; +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.elements.GuiElementBuilderInterface; +import eu.pb4.sgui.api.gui.SimpleGui; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import java.util.Map; + +public class TeleporterNexusScreen extends SimpleGui { + private final TeleporterNexusBlockEntity blockEntity; + + public TeleporterNexusScreen(TeleporterNexusBlockEntity blockEntity, ServerPlayerEntity player) { + super(ScreenHandlerType.GENERIC_9X6, player, false); + this.blockEntity = blockEntity; + setSlots(); + setTitle(Text.literal("Teleport Nexus")); + } + + int scroll = 0; + + void setSlots() { + for (int i = 0; i < 9; i++) { + setSlot(i, Utils.createBlankBlack()); + setSlot(i + (height - 1) * width, Utils.createBlankBlack()); + } + if (scroll > 0) { + setSlot(0, GuiElementBuilder.from(new ItemStack(Items.ARROW)) + .setName(Text.literal("Previous page")) + .setCallback(() -> scroll(-1))); + } + var it = blockEntity.destinations.entrySet().iterator(); + Utils.skipIt(it, scroll * width * (height - 2)); + for (int i = 1; i < height - 1 && it.hasNext(); i++) { + for (int j = 0; j < width && it.hasNext(); j++) { + int index = i * width + j; + var entry = it.next(); + setSlot(index, getHandlerForEntry(entry)); + } + } + if (it.hasNext()) { + setSlot(1, GuiElementBuilder.from(new ItemStack(Items.ARROW)) + .setName(Text.literal("Next page")) + .setCallback(() -> scroll(1))); + } + } + + void scroll(int offset) { + scroll = Math.max(0, scroll + offset); + setSlots(); + } + + void handleClick(ClickType clickType, TeleporterDestination destination) { + if (clickType == ClickType.MOUSE_RIGHT) { + new TeleporterNexusEditorScreen(blockEntity, destination, player).open(); + return; + } + destination.teleport(player); + close(); + } + + private GuiElementBuilderInterface<?> getHandlerForEntry(Map.Entry<TeleporterDestination, TeleporterNexusBlockEntity.Label> entry) { + var dest = entry.getKey(); + return GuiElementBuilder.from(new ItemStack(entry.getValue().item())) + .setName(Text.literal("Teleport to" + entry.getValue().label().map(it -> " " + it).orElse(""))) + .hideDefaultTooltip() + .addLoreLine(Text.literal(String.format("x: %d, y: %d, z: %d", dest.blockPos().getX(), dest.blockPos().getY(), dest.blockPos().getZ())) + .setStyle(Style.EMPTY.withItalic(false).withColor(Formatting.AQUA))) + .addLoreLine(Text.literal("in " + dest.target().getValue()) + .setStyle(Style.EMPTY.withItalic(false).withColor(Formatting.AQUA))) + .addLoreLine(Text.empty()) + .addLoreLine(Text.literal("Left-Click to teleport.").setStyle(Style.EMPTY.withItalic(false).withColor(Formatting.GRAY))) + .addLoreLine(Text.literal("Right-Click to edit item.").setStyle(Style.EMPTY.withItalic(false).withColor(Formatting.GRAY))) + .setCallback(clickType -> handleClick(clickType, dest)); + } +} diff --git a/src/main/java/moe/nea/funnyteleporters/TeleporterWand.java b/src/main/java/moe/nea/funnyteleporters/TeleporterWand.java new file mode 100644 index 0000000..fa379b4 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterWand.java @@ -0,0 +1,50 @@ +package moe.nea.funnyteleporters; + +import eu.pb4.polymer.core.api.item.PolymerItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.item.Items; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import org.jetbrains.annotations.Nullable; + +public class TeleporterWand extends Item implements PolymerItem { + public TeleporterWand(Settings settings) { + super(settings); + } + + @Override + public Item getPolymerItem(ItemStack itemStack, @Nullable ServerPlayerEntity serverPlayerEntity) { + return Items.CYAN_BANNER; + } + + @Override + public ActionResult useOnBlock(ItemUsageContext context) { + var destination = context.getStack().get(FunnyRegistry.TELEPORTER_DESTINATION); + var block = context.getWorld().getBlockState(context.getBlockPos()).getBlock(); + if (block == FunnyRegistry.TELEPORTER_NEXUS && destination != null) { + var nexus = FunnyRegistry.TELEPORTER_NEXUS.getBE(context.getWorld(), context.getBlockPos()); + if (context.getPlayer() != null) + context.getPlayer().sendMessage(Text.literal("Saved destination from wand into nexus.")); + nexus.addDestination(destination); + } + if (block == FunnyRegistry.TELEPORTER) { + if (context.getPlayer() != null && context.getPlayer().isSneaking()) { + context.getStack().set(FunnyRegistry.TELEPORTER_DESTINATION, new TeleporterDestination(context.getWorld().getRegistryKey(), context.getBlockPos())); + context.getPlayer().sendMessage(Text.literal("Saved teleport destination to wand.")); + } else { + var be = FunnyRegistry.TELEPORTER.getBE(context.getWorld(), context.getBlockPos()); + // TODO: check for empty destination + be.destination = destination; + be.markDirty(); + if (context.getPlayer() != null) { + context.getPlayer().sendMessage(Text.literal("Set new target destination from wand.")); + } + } + return ActionResult.SUCCESS_NO_ITEM_USED; + } + return super.useOnBlock(context); + } +} diff --git a/src/main/java/moe/nea/funnyteleporters/Utils.java b/src/main/java/moe/nea/funnyteleporters/Utils.java new file mode 100644 index 0000000..b0a1649 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/Utils.java @@ -0,0 +1,34 @@ +package moe.nea.funnyteleporters; + +import net.minecraft.component.DataComponentTypes; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Unit; + +import java.util.Iterator; + +public class Utils { + public static ItemStack createBlankBlack() { + var s = new ItemStack(Items.BLACK_STAINED_GLASS_PANE); + s.set(DataComponentTypes.CUSTOM_NAME, Text.empty()); + s.set(DataComponentTypes.HIDE_TOOLTIP, Unit.INSTANCE); + return s; + } + + public static void skipIt(Iterator<?> it, int skipCount) { + for (; skipCount > 0 && it.hasNext(); skipCount--) { + it.next(); + } + } + + public static Style emptyLoreStyle() { + return Style.EMPTY.withItalic(false); + } + + public static Style colouredLoreStyle(Formatting formatting) { + return emptyLoreStyle().withColor(formatting); + } +} |