summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/generated/assets/funny-teleporters/lang/en_us.json7
-rw-r--r--src/main/generated/data/funny-teleporters/advancement/recipes/building_blocks/ender_pearl_block.json32
-rw-r--r--src/main/generated/data/funny-teleporters/advancement/recipes/misc/ender_pearl.json32
-rw-r--r--src/main/generated/data/funny-teleporters/advancement/recipes/tools/teleporter_wand.json32
-rw-r--r--src/main/generated/data/funny-teleporters/advancement/recipes/transportation/teleporter.json32
-rw-r--r--src/main/generated/data/funny-teleporters/advancement/recipes/transportation/teleporter_nexus.json32
-rw-r--r--src/main/generated/data/funny-teleporters/loot_table/blocks/ender_pearl_block.json20
-rw-r--r--src/main/generated/data/funny-teleporters/loot_table/blocks/teleporter.json20
-rw-r--r--src/main/generated/data/funny-teleporters/loot_table/blocks/teleporter_nexus.json20
-rw-r--r--src/main/generated/data/funny-teleporters/recipe/ender_pearl.json13
-rw-r--r--src/main/generated/data/funny-teleporters/recipe/ender_pearl_block.json18
-rw-r--r--src/main/generated/data/funny-teleporters/recipe/teleporter.json21
-rw-r--r--src/main/generated/data/funny-teleporters/recipe/teleporter_nexus.json24
-rw-r--r--src/main/generated/data/funny-teleporters/recipe/teleporter_wand.json24
-rw-r--r--src/main/generated/data/minecraft/tags/block/mineable/hoe.json5
-rw-r--r--src/main/generated/data/minecraft/tags/block/mineable/pickaxe.json4
-rw-r--r--src/main/java/moe/nea/funnyteleporters/ColouredChestViewScreen.java7
-rw-r--r--src/main/java/moe/nea/funnyteleporters/FunnyDataGenerator.java1
-rw-r--r--src/main/java/moe/nea/funnyteleporters/FunnyDropTableProvider.java3
-rw-r--r--src/main/java/moe/nea/funnyteleporters/FunnyRecipeProvider.java38
-rw-r--r--src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java29
-rw-r--r--src/main/java/moe/nea/funnyteleporters/FunnyTagGenerator.java7
-rw-r--r--src/main/java/moe/nea/funnyteleporters/FunnyTranslationProvider.java22
-rw-r--r--src/main/java/moe/nea/funnyteleporters/TeleporterBlock.java42
-rw-r--r--src/main/java/moe/nea/funnyteleporters/TeleporterBlockEntity.java109
-rw-r--r--src/main/java/moe/nea/funnyteleporters/TeleporterDestination.java62
-rw-r--r--src/main/java/moe/nea/funnyteleporters/TeleporterNexus.java42
-rw-r--r--src/main/java/moe/nea/funnyteleporters/TeleporterNexusBlockEntity.java96
-rw-r--r--src/main/java/moe/nea/funnyteleporters/TeleporterNexusEditorScreen.java86
-rw-r--r--src/main/java/moe/nea/funnyteleporters/TeleporterNexusNameEditorScreen.java29
-rw-r--r--src/main/java/moe/nea/funnyteleporters/TeleporterNexusScreen.java85
-rw-r--r--src/main/java/moe/nea/funnyteleporters/TeleporterWand.java50
-rw-r--r--src/main/java/moe/nea/funnyteleporters/Utils.java34
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);
+ }
+}