diff options
Diffstat (limited to 'src/main/java/moe/nea/funnyteleporters')
10 files changed, 270 insertions, 1 deletions
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..cb27621 100644 --- a/src/main/java/moe/nea/funnyteleporters/FunnyDropTableProvider.java +++ b/src/main/java/moe/nea/funnyteleporters/FunnyDropTableProvider.java @@ -14,5 +14,7 @@ public class FunnyDropTableProvider extends FabricBlockLootTableProvider { @Override public void generate() { addDrop(FunnyRegistry.COLOURED_CHEST); + addDrop(FunnyRegistry.ENDER_PEARL_BLOCK); + addDrop(FunnyRegistry.TELEPORTER); } } diff --git a/src/main/java/moe/nea/funnyteleporters/FunnyRecipeProvider.java b/src/main/java/moe/nea/funnyteleporters/FunnyRecipeProvider.java index 5b7ee14..a3023a7 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,32 @@ 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); } } diff --git a/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java b/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java index 498adf5..c42f4e4 100644 --- a/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java +++ b/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java @@ -1,12 +1,16 @@ 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 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 +21,23 @@ 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 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))); + private static <T> ComponentType<T> registerComponentType(String name, Codec<T> codec) { + return Registry.register(Registries.DATA_COMPONENT_TYPE, FunnyTeleporters.id(name), ComponentType.<T>builder().codec(codec).build()); + } private static <T extends BlockEntity> BlockEntityType<T> registerBlockEntity(String name, BlockEntityType.Builder<T> builder) { var be = Registry.register(Registries.BLOCK_ENTITY_TYPE, @@ -29,6 +48,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..a43babd 100644 --- a/src/main/java/moe/nea/funnyteleporters/FunnyTagGenerator.java +++ b/src/main/java/moe/nea/funnyteleporters/FunnyTagGenerator.java @@ -15,6 +15,10 @@ 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)); + 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..e24a819 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/FunnyTranslationProvider.java @@ -0,0 +1,21 @@ +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.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..a12037e --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterBlock.java @@ -0,0 +1,41 @@ +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.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.SEA_LANTERN.getDefaultState(); + } + + 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..1c23576 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterBlockEntity.java @@ -0,0 +1,87 @@ +package moe.nea.funnyteleporters; + +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.DataResult; +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.NbtElement; +import net.minecraft.nbt.NbtOps; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.server.world.ServerWorld; +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.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) { + if (incomingEntities.remove(entity)) { + trackedEntities.remove(entity); + continue; + } + if (!trackedEntities.contains(entity)) { + performTeleport(entity); + } + } + trackedEntities = newEntities; + } + + @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(); + } + } + } + + Set<Entity> trackedEntities = new HashSet<>(); + Set<Entity> incomingEntities = new HashSet<>(); + @Nullable TeleporterDestination destination; + + void performTeleport(Entity subject) { + if (destination == null) return; + var sourceWorld = subject.getWorld(); + var destinationWorld = destination.getDestinationWorld((ServerWorld) sourceWorld); + if (destinationWorld == null) return; + var destinationBE = destinationWorld.getBlockEntity(destination.blockPos()); + if (!(destinationBE instanceof TeleporterBlockEntity be)) { + return; + } + be.incomingEntities.add(subject); + var destPos = destination.blockPos().up().toBottomCenterPos(); + subject.teleport(destinationWorld, destPos.x, destPos.y, destPos.z, Set.of(), subject.getYaw(), subject.getPitch()); + } +} 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..d47ae1f --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterDestination.java @@ -0,0 +1,20 @@ +package moe.nea.funnyteleporters; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public record TeleporterDestination( + RegistryKey<World> target, + BlockPos blockPos +) { + 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/TeleporterWand.java b/src/main/java/moe/nea/funnyteleporters/TeleporterWand.java new file mode 100644 index 0000000..96ed941 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/TeleporterWand.java @@ -0,0 +1,42 @@ +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) { + if (context.getWorld().getBlockState(context.getBlockPos()).getBlock() == 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 = context.getStack().get(FunnyRegistry.TELEPORTER_DESTINATION); + be.markDirty(); + if (context.getPlayer() != null) { + context.getPlayer().sendMessage(Text.literal("Set new target destination to wand.")); + } + } + return ActionResult.SUCCESS_NO_ITEM_USED; + } + return super.useOnBlock(context); + } +} |