From eec2d93a7564374a98edf16cc15520c174e4ac99 Mon Sep 17 00:00:00 2001 From: Waterpicker Date: Fri, 5 May 2023 06:56:03 -0500 Subject: [PATCH] Pushed for haunted --- .../block/DimensionalPortalBlock.java | 81 +++-- .../dimdoors/block/EternalFluidBlock.java | 9 +- .../org/dimdev/dimdoors/block/ModBlocks.java | 213 ++++++------ .../block/door/DimensionalTrapdoorBlock.java | 65 ++-- .../org/dimdev/dimdoors/fluid/ModFluids.java | 5 + .../dimdoors/item/DimensionalEraserItem.java | 51 +++ .../dimdev/dimdoors/item/ItemExtensions.java | 16 + .../dimdev/dimdoors/item/MaskWandItem.java | 65 ++++ .../dimdoors/item/ModArmorMaterials.java | 77 +++++ .../org/dimdev/dimdoors/item/ModItems.java | 314 ++++++++++++++++++ .../dimdev/dimdoors/item/RaycastHelper.java | 40 +++ .../dimdev/dimdoors/item/RiftBladeItem.java | 118 +++++++ .../item/RiftConfigurationToolItem.java | 120 +++++++ .../org/dimdev/dimdoors/item/RiftKeyItem.java | 145 ++++++++ .../dimdev/dimdoors/item/RiftRemoverItem.java | 84 +++++ .../dimdoors/item/RiftSignatureItem.java | 148 +++++++++ .../dimdoors/item/RiftStabilizerItem.java | 71 ++++ .../item/StabilizedRiftSignatureItem.java | 116 +++++++ .../item/component/CounterComponent.java | 34 ++ .../item/door/DimensionalDoorItem.java | 134 ++++++++ .../door/DimensionalDoorItemRegistrar.java | 231 +++++++++++++ .../item/door/DimensionalTrapdoorItem.java | 59 ++++ .../item/door/DoorRiftDataLoader.java | 68 ++++ .../dimdoors/item/door/data/RiftDataList.java | 88 +++++ .../door/data/condition/AllCondition.java | 32 ++ .../data/condition/AlwaysTrueCondition.java | 23 ++ .../door/data/condition/AnyCondition.java | 32 ++ .../item/door/data/condition/Condition.java | 60 ++++ .../door/data/condition/InverseCondition.java | 27 ++ .../data/condition/MultipleCondition.java | 21 ++ .../data/condition/WorldMatchCondition.java | 33 ++ 31 files changed, 2390 insertions(+), 190 deletions(-) create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/DimensionalEraserItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/ItemExtensions.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/MaskWandItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/ModArmorMaterials.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/ModItems.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/RaycastHelper.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/RiftBladeItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/RiftConfigurationToolItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/RiftKeyItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/RiftRemoverItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/RiftSignatureItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/RiftStabilizerItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/StabilizedRiftSignatureItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/component/CounterComponent.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalDoorItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalDoorItemRegistrar.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalTrapdoorItem.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/DoorRiftDataLoader.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/data/RiftDataList.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AllCondition.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AlwaysTrueCondition.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AnyCondition.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/Condition.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/InverseCondition.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/MultipleCondition.java create mode 100644 common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/WorldMatchCondition.java diff --git a/common/src/main/java/org/dimdev/dimdoors/block/DimensionalPortalBlock.java b/common/src/main/java/org/dimdev/dimdoors/block/DimensionalPortalBlock.java index 34f32c43..96737b2b 100644 --- a/common/src/main/java/org/dimdev/dimdoors/block/DimensionalPortalBlock.java +++ b/common/src/main/java/org/dimdev/dimdoors/block/DimensionalPortalBlock.java @@ -1,71 +1,63 @@ package org.dimdev.dimdoors.block; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.Level; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockRenderType; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.HorizontalFacingBlock; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityTicker; -import net.minecraft.block.entity.BlockEntityType; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.core.BlockPos; -import net.minecraft.entity.Entity; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.world.ServerWorld; import net.minecraft.state.StateManager; -import net.minecraft.state.property.DirectionProperty; import net.minecraft.util.BlockMirror; -import net.minecraft.util.BlockRotation; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; import net.minecraft.world.World; -import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; import org.dimdev.dimdoors.block.entity.DetachedRiftBlockEntity; import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; import org.dimdev.dimdoors.block.entity.ModBlockEntityTypes; +import org.jetbrains.annotations.Nullable; // TODO: copy over all the necessary bits from DimensionalDoorBlock public class DimensionalPortalBlock extends Block implements RiftProvider { - public static DirectionProperty FACING = HorizontalFacingBlock.FACING; + public static DirectionProperty FACING = HorizontalDirectionalBlock.FACING; - public DimensionalPortalBlock(Settings settings) { + public DimensionalPortalBlock(BlockBehaviour.Properties settings) { super(settings); - this.setDefaultState(this.stateManager.getDefaultState().with(FACING, Direction.NORTH)); + this.registerDefaultState(this.getStateDefinition().any().setValue(FACING, Direction.NORTH)); } @Override - public EntranceRiftBlockEntity getRift(World world, BlockPos pos, BlockState state) { + public EntranceRiftBlockEntity getRift(Level world, BlockPos pos, BlockState state) { return (EntranceRiftBlockEntity) world.getBlockEntity(pos); } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new EntranceRiftBlockEntity(pos, state); } @Override - public BlockRenderType getRenderType(BlockState state) { - return BlockRenderType.ENTITYBLOCK_ANIMATED; + public RenderShape getRenderShape(BlockState state) { + return RenderShape.ENTITYBLOCK_ANIMATED; } @Override - public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { - if (world.isClient) { + public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (world.isClientSide) { return; } @@ -73,7 +65,7 @@ public class DimensionalPortalBlock extends Block implements RiftProvider builder) { + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(FACING); } @Override - public VoxelShape getRaycastShape(BlockState state, BlockView world, BlockPos pos) { - return VoxelShapes.fullCube(); + public VoxelShape getInteractionShape(BlockState state, BlockGetter world, BlockPos pos) { + return Shapes.block(); } @Environment(EnvType.CLIENT) @@ -109,15 +102,15 @@ public class DimensionalPortalBlock extends Block implements RiftProvider BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { - return Dummy.checkType(type, ModBlockEntityTypes.ENTRANCE_RIFT, DimensionalPortalBlock::portalTick); + public BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType type) { + return Dummy.checkType(type, ModBlockEntityTypes.ENTRANCE_RIFT.get(), DimensionalPortalBlock::portalTick); } private static void portalTick(Level world, BlockPos pos, BlockState state, EntranceRiftBlockEntity e) { diff --git a/common/src/main/java/org/dimdev/dimdoors/block/EternalFluidBlock.java b/common/src/main/java/org/dimdev/dimdoors/block/EternalFluidBlock.java index 215e1571..ce9ca4d7 100644 --- a/common/src/main/java/org/dimdev/dimdoors/block/EternalFluidBlock.java +++ b/common/src/main/java/org/dimdev/dimdoors/block/EternalFluidBlock.java @@ -1,5 +1,7 @@ package org.dimdev.dimdoors.block; +import dev.architectury.core.block.ArchitecturyLiquidBlock; +import dev.architectury.core.fluid.ArchitecturyFlowingFluid; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; @@ -8,17 +10,18 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.world.level.block.LiquidBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; import org.dimdev.dimdoors.api.rift.target.EntityTarget; import org.dimdev.dimdoors.api.util.math.MathUtil; import org.dimdev.dimdoors.entity.limbo.LimboExitReason; import org.dimdev.dimdoors.fluid.ModFluids; import org.dimdev.dimdoors.rift.targets.EscapeTarget; -public class EternalFluidBlock extends LiquidBlock { +public class EternalFluidBlock extends ArchitecturyFlowingFluid { private static final EntityTarget TARGET = new EscapeTarget(true); - public EternalFluidBlock(Block.Settings settings) { - super(ModFluids.ETERNAL_FLUID, settings); + public EternalFluidBlock() { + super(ModFluids.ETERNAL_FLUID); } @Override diff --git a/common/src/main/java/org/dimdev/dimdoors/block/ModBlocks.java b/common/src/main/java/org/dimdev/dimdoors/block/ModBlocks.java index d1ae1f2b..bd377b58 100644 --- a/common/src/main/java/org/dimdev/dimdoors/block/ModBlocks.java +++ b/common/src/main/java/org/dimdev/dimdoors/block/ModBlocks.java @@ -1,8 +1,16 @@ package org.dimdev.dimdoors.block; -import java.util.HashMap; -import java.util.Map; - +import dev.architectury.registry.registries.DeferredRegister; +import dev.architectury.registry.registries.RegistrySupplier; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.minecraft.block.*; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.core.registries.Registries; +import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.DyeColor; import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.state.BlockBehaviour; @@ -10,74 +18,44 @@ import net.minecraft.world.level.block.state.properties.BlockSetType; import net.minecraft.world.level.block.state.properties.WoodType; import net.minecraft.world.level.material.Material; import net.minecraft.world.level.material.MaterialColor; +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.dimdoors.block.door.DimensionalTrapdoorBlock; +import org.dimdev.dimdoors.item.ModItems; import org.dimdev.matrix.Matrix; import org.dimdev.matrix.Registrar; import org.dimdev.matrix.RegistryEntry; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockSetType; -import net.minecraft.block.Blocks; -import net.minecraft.block.ButtonBlock; -import net.minecraft.block.DoorBlock; -import net.minecraft.block.ExperienceDroppingBlock; -import net.minecraft.block.FenceBlock; -import net.minecraft.block.FenceGateBlock; -import net.minecraft.block.LeavesBlock; -import net.minecraft.block.MapColor; -import net.minecraft.block.Material; -import net.minecraft.block.PillarBlock; -import net.minecraft.block.PointedDripstoneBlock; -import net.minecraft.block.SlabBlock; -import net.minecraft.block.StairsBlock; -import net.minecraft.block.TrapdoorBlock; -//<<<<<<< HEAD -import net.minecraft.block.WoodType; -//======= -import net.minecraft.block.WallBlock; -//>>>>>>> 9ba9cc82 (Pushed current datagen stuff I forgot to push.) -import net.minecraft.client.render.RenderLayer; -import net.minecraft.registry.Registries; -import net.minecraft.sound.BlockSoundGroup; -import net.minecraft.util.DyeColor; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; - -import org.dimdev.dimdoors.block.door.DimensionalTrapdoorBlock; - -import static net.minecraft.block.Blocks.CLAY; -import static net.minecraft.block.Blocks.GRAVEL; -import static net.minecraft.block.Blocks.MUD; import static net.minecraft.block.Blocks.OAK_LEAVES; import static net.minecraft.block.Blocks.OAK_SAPLING; import static net.minecraft.block.Blocks.STONE; import static net.minecraft.block.Blocks.WATER; -import static net.minecraft.world.level.block.Blocks.CLAY; -import static net.minecraft.world.level.block.Blocks.GRAVEL; -import static net.minecraft.world.level.block.Blocks.MUD; +import static net.minecraft.world.level.block.Blocks.*; @Registrar(element = Block.class, modid = "dimdoors") public final class ModBlocks { - public static final Map FABRIC_BLOCKS = new HashMap<>(); + public static final Map> FABRIC_BLOCKS = new HashMap>(); - private static final Map ANCIENT_FABRIC_BLOCKS = new HashMap<>(); + private static final Map> ANCIENT_FABRIC_BLOCKS = new HashMap>(); - @RegistryEntry("stone_player") public static final Block STONE_PLAYER = register(new Block(FabricBlockSettings.of(Material.STONE).strength(0.5F).nonOpaque())); + public static final DeferredRegister BLOCKS = DeferredRegister.create(DimensionalDoors.MOD_ID, Registries.BLOCK); - @RegistryEntry("gold_door") public static final Block GOLD_DOOR = register(new DoorBlock(FabricBlockSettings.of(Material.METAL, MapColor.GOLD).strength(5.0F).requiresTool().nonOpaque(), BlockSetType.IRON)); + public static final RegistrySupplier STONE_PLAYER = register("stone_player", () -> new Block(of(Material.STONE).strength(0.5F).noOcclusion())); - @RegistryEntry("stone_door") public static final Block STONE_DOOR = register(new DoorBlock(FabricBlockSettings.of(Material.METAL, MapColor.OAK_TAN).strength(5.0F).requiresTool().nonOpaque(), BlockSetType.IRON)); + public static final RegistrySupplier GOLD_DOOR = register("gold_door", () -> new DoorBlock(of(Material.METAL, MaterialColor.GOLD).strength(5.0F).requiresCorrectToolForDrops().noCollission(), BlockSetType.IRON)); - @RegistryEntry("quartz_door") public static final Block QUARTZ_DOOR = register(new DoorBlock(FabricBlockSettings.of(Material.STONE, MapColor.OFF_WHITE).strength(5.0F).requiresTool().nonOpaque(), BlockSetType.IRON)); + public static final RegistrySupplier STONE_DOOR = register("stone_door", () -> new DoorBlock(of(Material.METAL, MaterialColor.WOOD).strength(5.0F).requiresCorrectToolForDrops().noOcclusion(), BlockSetType.IRON)); - @RegistryEntry("wood_dimensional_trapdoor") public static final Block OAK_DIMENSIONAL_TRAPDOOR = register(new DimensionalTrapdoorBlock(FabricBlockSettings.copyOf(Blocks.OAK_TRAPDOOR).luminance(state -> 10), BlockSetType.OAK)); + public static final RegistrySupplier QUARTZ_DOOR = register("quartz_door", () -> new DoorBlock(of(Material.STONE, MaterialColor.TERRACOTTA_WHITE).strength(5.0F).requiresCorrectToolForDrops().noOcclusion(), BlockSetType.IRON)); - @RegistryEntry("dimensional_portal") public static final Block DIMENSIONAL_PORTAL = register(new DimensionalPortalBlock(FabricBlockSettings.of(Material.AIR).collidable(false).strength(-1.0F, 3600000.0F).nonOpaque().dropsNothing().luminance(blockState -> 10))); + public static final RegistrySupplier OAK_DIMENSIONAL_TRAPDOOR = register("wood_dimensional_trapdoor", () -> new DimensionalTrapdoorBlock(of(Blocks.OAK_TRAPDOOR).lightLevel(state -> 10), BlockSetType.OAK)); - @RegistryEntry("detached_rift") public static final Block DETACHED_RIFT = register(new DetachedRiftBlock(FabricBlockSettings.of(Material.AIR).strength(-1.0F, 3600000.0F).noCollision().nonOpaque())); + public static final RegistrySupplier DIMENSIONAL_PORTAL = register("dimensional_portal", () -> new DimensionalPortalBlock(of(Material.AIR).noCollission().strength(-1.0F, 3600000.0F).noOcclusion().dropsLike(AIR).lightLevel(blockState -> 10))); + + public static final RegistrySupplier DETACHED_RIFT = register("detached_rift", () -> new DetachedRiftBlock(Setti.of(Material.AIR).strength(-1.0F, 3600000.0F).noCollision().nonOpaque())); @RegistryEntry("white_fabric") public static final Block WHITE_FABRIC = registerFabric(DyeColor.WHITE); @@ -143,9 +121,9 @@ public final class ModBlocks { @RegistryEntry("red_ancient_fabric") public static final Block RED_ANCIENT_FABRIC = registerAncientFabric(DyeColor.RED); @RegistryEntry("black_ancient_fabric") public static final Block BLACK_ANCIENT_FABRIC = registerAncientFabric(DyeColor.BLACK); - private static final BlockBehaviour.Properties UNRAVELLED_FABRIC_BLOCK_SETTINGS = BlockBehaviour.Properties.of(Material.STONE, MaterialColor.COLOR_BLACK).randomTicks().lightLevel(state -> 15).strength(0.3F, 0.3F); + private static final BlockBehaviour.Properties UNRAVELLED_FABRIC_BLOCK_SETTINGS = of(Material.STONE, MaterialColor.COLOR_BLACK).randomTicks().lightLevel(state -> 15).strength(0.3F, 0.3F); - @RegistryEntry("eternal_fluid") public static final Block ETERNAL_FLUID = register(new EternalFluidBlock(BlockBehaviour.Properties.of(Material.STONE, MaterialColor.COLOR_RED).lightLevel(state -> 15))); + @RegistryEntry("eternal_fluid") public static final Block ETERNAL_FLUID = register(new EternalFluidBlock(of(Material.STONE, MaterialColor.COLOR_RED).lightLevel(state -> 15))); @RegistryEntry("decayed_block") public static final Block DECAYED_BLOCK = register(new UnravelledFabricBlock(UNRAVELLED_FABRIC_BLOCK_SETTINGS)); @@ -167,29 +145,29 @@ public final class ModBlocks { public static final Block REALITY_SPONGE = new RealitySpongeBlock(UNRAVELLED_FABRIC_BLOCK_SETTINGS); //Decay graph filler. - @RegistryEntry("driftwood_wood") public static final Block DRIFTWOOD_WOOD = new PillarBlock(AbstractBlock.Settings.of(Material.WOOD, MapColor.LIGHT_GRAY).strength(2.0F).sounds(BlockSoundGroup.WOOD)); - @RegistryEntry("driftwood_log") public static final Block DRIFTWOOD_LOG = new PillarBlock(AbstractBlock.Settings.of(Material.WOOD, MapColor.LIGHT_GRAY).strength(2.0F).sounds(BlockSoundGroup.WOOD)); - @RegistryEntry("driftwood_planks") public static final Block DRIFTWOOD_PLANKS = new Block(AbstractBlock.Settings.of(Material.WOOD, MapColor.LIGHT_GRAY).strength(2.0F, 3.0F).sounds(BlockSoundGroup.WOOD)); - @RegistryEntry("driftwood_leaves") public static final Block DRIFTWOOD_LEAVES = new LeavesBlock(AbstractBlock.Settings.copy(OAK_LEAVES)); - @RegistryEntry("driftwood_sapling") public static final Block DRIFTWOOD_SAPLING = new Block(AbstractBlock.Settings.copy(OAK_SAPLING)); - @RegistryEntry("driftwood_fence") public static final Block DRIFTWOOD_FENCE = new FenceBlock(AbstractBlock.Settings.of(Material.WOOD, DRIFTWOOD_PLANKS.getDefaultMapColor()).strength(2.0F, 3.0F).sounds(BlockSoundGroup.WOOD)); - @RegistryEntry("driftwood_gate") public static final Block DRIFTWOOD_GATE = new FenceGateBlock(AbstractBlock.Settings.of(Material.WOOD, DRIFTWOOD_PLANKS.getDefaultMapColor()).strength(2.0F, 3.0F).sounds(BlockSoundGroup.WOOD), WoodType.OAK); // TODO: add driftwood wood type - @RegistryEntry("driftwood_button") public static final Block DRIFTWOOD_BUTTON = new ButtonBlock(AbstractBlock.Settings.of(Material.DECORATION, MapColor.LIGHT_GRAY).noCollision().strength(0.5F), BlockSetType.OAK, 20, true); - @RegistryEntry("driftwood_slab") public static final Block DRIFTWOOD_SLAB = new SlabBlock(AbstractBlock.Settings.of(Material.WOOD, MapColor.LIGHT_GRAY)); - @RegistryEntry("driftwood_stairs") public static final Block DRIFTWOOD_STAIRS = new StairsBlock(DRIFTWOOD_PLANKS.getDefaultState(), AbstractBlock.Settings.of(Material.WOOD, MapColor.LIGHT_GRAY)); - @RegistryEntry("driftwood_door") public static final Block DRIFTWOOD_DOOR = new DoorBlock(AbstractBlock.Settings.of(Material.WOOD, DRIFTWOOD_PLANKS.getDefaultMapColor()).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque(), BlockSetType.OAK); - @RegistryEntry("driftwood_trapdoor") public static final Block DRIFTWOOD_TRAPDOOR = new TrapdoorBlock(AbstractBlock.Settings.of(Material.WOOD, DRIFTWOOD_PLANKS.getDefaultMapColor()).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque().allowsSpawning((state, world, pos, type) -> false), BlockSetType.OAK); + @RegistryEntry("driftwood_wood") public static final Block DRIFTWOOD_WOOD = new PillarBlock(of(Material.WOOD, MapColor.LIGHT_GRAY).strength(2.0F).sounds(BlockSoundGroup.WOOD)); + @RegistryEntry("driftwood_log") public static final Block DRIFTWOOD_LOG = new PillarBlock(of(Material.WOOD, MapColor.LIGHT_GRAY).strength(2.0F).sounds(BlockSoundGroup.WOOD)); + @RegistryEntry("driftwood_planks") public static final Block DRIFTWOOD_PLANKS = new Block(of(Material.WOOD, MapColor.LIGHT_GRAY).strength(2.0F, 3.0F).sounds(BlockSoundGroup.WOOD)); + @RegistryEntry("driftwood_leaves") public static final Block DRIFTWOOD_LEAVES = new LeavesBlock(of(OAK_LEAVES)); + @RegistryEntry("driftwood_sapling") public static final Block DRIFTWOOD_SAPLING = new Block(of(OAK_SAPLING)); + @RegistryEntry("driftwood_fence") public static final Block DRIFTWOOD_FENCE = new FenceBlock(of(Material.WOOD, DRIFTWOOD_PLANKS.getDefaultMapColor()).strength(2.0F, 3.0F).sounds(BlockSoundGroup.WOOD)); + @RegistryEntry("driftwood_gate") public static final Block DRIFTWOOD_GATE = new FenceGateBlock(of(Material.WOOD, DRIFTWOOD_PLANKS.getDefaultMapColor()).strength(2.0F, 3.0F).sounds(BlockSoundGroup.WOOD), WoodType.OAK); // TODO: add driftwood wood type + @RegistryEntry("driftwood_button") public static final Block DRIFTWOOD_BUTTON = new ButtonBlock(of(Material.DECORATION, MapColor.LIGHT_GRAY).noCollision().strength(0.5F), BlockSetType.OAK, 20, true); + @RegistryEntry("driftwood_slab") public static final Block DRIFTWOOD_SLAB = new SlabBlock(of(Material.WOOD, MapColor.LIGHT_GRAY)); + @RegistryEntry("driftwood_stairs") public static final Block DRIFTWOOD_STAIRS = new StairsBlock(DRIFTWOOD_PLANKS.getDefaultState(), of(Material.WOOD, MapColor.LIGHT_GRAY)); + @RegistryEntry("driftwood_door") public static final Block DRIFTWOOD_DOOR = new DoorBlock(of(Material.WOOD, DRIFTWOOD_PLANKS.getDefaultMapColor()).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque(), BlockSetType.OAK); + @RegistryEntry("driftwood_trapdoor") public static final Block DRIFTWOOD_TRAPDOOR = new TrapdoorBlock(of(Material.WOOD, DRIFTWOOD_PLANKS.getDefaultMapColor()).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque().allowsSpawning((state, world, pos, type) -> false), BlockSetType.OAK); - @RegistryEntry("amalgam_block") public static final Block AMALGAM_BLOCK = new Block(AbstractBlock.Settings.of(Material.METAL, MapColor.LIGHT_GRAY).requiresTool().strength(5.0F, 6.0F).sounds(BlockSoundGroup.METAL)); - @RegistryEntry("amalgam_door") public static final Block AMALGAM_DOOR = new DoorBlock(AbstractBlock.Settings.of(Material.METAL, MapColor.LIGHT_GRAY).requiresTool().strength(5.0F).sounds(BlockSoundGroup.METAL).nonOpaque(), BlockSetType.IRON); - @RegistryEntry("amalgam_trapdoor") public static final Block AMALGAM_TRAPDOOR = new TrapdoorBlock(AbstractBlock.Settings.of(Material.METAL).requiresTool().strength(5.0F).sounds(BlockSoundGroup.METAL).nonOpaque().allowsSpawning((state, world, pos, type) -> false), BlockSetType.IRON); - @RegistryEntry("rust") public static final Block RUST = new Block(AbstractBlock.Settings.of(Material.WOOD)); + @RegistryEntry("amalgam_block") public static final Block AMALGAM_BLOCK = new Block(of(Material.METAL, MapColor.LIGHT_GRAY).requiresTool().strength(5.0F, 6.0F).sounds(BlockSoundGroup.METAL)); + @RegistryEntry("amalgam_door") public static final Block AMALGAM_DOOR = new DoorBlock(of(Material.METAL, MapColor.LIGHT_GRAY).requiresTool().strength(5.0F).sounds(BlockSoundGroup.METAL).nonOpaque(), BlockSetType.IRON); + @RegistryEntry("amalgam_trapdoor") public static final Block AMALGAM_TRAPDOOR = new TrapdoorBlock(of(Material.METAL).requiresTool().strength(5.0F).sounds(BlockSoundGroup.METAL).nonOpaque().allowsSpawning((state, world, pos, type) -> false), BlockSetType.IRON); + @RegistryEntry("rust") public static final Block RUST = new Block(of(Material.WOOD)); @RegistryEntry("amalgam_slab") public static final Block AMALGAM_SLAB = createSlab(AMALGAM_BLOCK); @RegistryEntry("amalgam_stairs") public static final Block AMALGAM_STAIRS = createStairs(AMALGAM_BLOCK); - @RegistryEntry("amalgam_ore") public static final Block AMALGAM_ORE = new DropExperienceBlock(BlockBehaviour.Properties.of(Material.STONE).requiresCorrectToolForDrops().strength(3.0F, 3.0F)); + @RegistryEntry("amalgam_ore") public static final Block AMALGAM_ORE = new DropExperienceBlock(of(Material.STONE).requiresCorrectToolForDrops().strength(3.0F, 3.0F)); - @RegistryEntry("clod_ore") public static final Block CLOD_ORE = new Block(BlockBehaviour.Properties.of(Material.WOOD)); - @RegistryEntry("clod_block") public static final Block CLOD_BLOCK = new Block(BlockBehaviour.Properties.of(Material.WOOD)); + @RegistryEntry("clod_ore") public static final Block CLOD_ORE = new Block(of(Material.WOOD)); + @RegistryEntry("clod_block") public static final Block CLOD_BLOCK = new Block(of(Material.WOOD)); @RegistryEntry("gravel_fence") public static final Block GRAVEL_FENCE = createFence(GRAVEL); @RegistryEntry("gravel_gate") public static final Block GRAVEL_GATE = createFenceGate(GRAVEL); @@ -198,7 +176,7 @@ public final class ModBlocks { @RegistryEntry("gravel_stairs") public static final Block GRAVEL_STAIRS = createStairs(GRAVEL); @RegistryEntry("gravel_wall") public static final Block GRAVEL_WALL = createWall(GRAVEL); - @RegistryEntry("dark_sand") public static final Block DARK_SAND = new Block(AbstractBlock.Settings.of(Material.AGGREGATE, MapColor.BLACK).strength(0.5F).sounds(BlockSoundGroup.SAND)); + @RegistryEntry("dark_sand") public static final Block DARK_SAND = new Block(of(Material.AGGREGATE, MapColor.BLACK).strength(0.5F).sounds(BlockSoundGroup.SAND)); @RegistryEntry("dark_sand_fence") public static final Block DARK_SAND_FENCE = createFence(DARK_SAND); @RegistryEntry("dark_sand_gate") public static final Block DARK_SAND_GATE = createFenceGate(DARK_SAND); @RegistryEntry("dark_sand_button") public static final Block DARK_SAND_BUTTON = createButton(DARK_SAND); @@ -245,66 +223,83 @@ public final class ModBlocks { @RegistryEntry("netherrack_stairs") public static final Block NETHERRACK_STAIRS = createStairs(Blocks.NETHERRACK); @RegistryEntry("netherrack_wall") public static final Block NETHERRACK_WALL = createWall(Blocks.NETHERRACK); - @RegistryEntry("unraveled_spike") public static final Block UNRAVELED_SPIKE = new PointedDripstoneBlock(AbstractBlock.Settings.copy(UNRAVELLED_FABRIC).luminance(state -> 0)); //TODO: make this proper class later - @RegistryEntry("gritty_stone") public static final Block GRITTY_STONE = new Block(AbstractBlock.Settings.copy(STONE)); - @RegistryEntry("leak") public static final Block LEAK = new Block(AbstractBlock.Settings.copy(WATER)); + @RegistryEntry("unraveled_spike") public static final Block UNRAVELED_SPIKE = new PointedDripstoneBlock(of(UNRAVELLED_FABRIC).luminance(state -> 0)); //TODO: make this proper class later + @RegistryEntry("gritty_stone") public static final Block GRITTY_STONE = new Block(of(STONE)); + @RegistryEntry("leak") public static final Block LEAK = new Block(of(WATER)); - private static Block register(Block block) { + public static void init() { + BLOCKS.register(); + } + + private static RegistrySupplier registerWithoutTab(String name, Supplier block) { + return BLOCKS.register(name, block); + } + + private static RegistrySupplier registerAncientFabric(DyeColor color) { + RegistrySupplier block = register(color.getSerializedName() + "_ancient_fabric", () -> new AncientFabricBlock(color)); + ANCIENT_FABRIC_BLOCKS.put(color, block); return block; } - private static Block registerAncientFabric(DyeColor color) { - Block block = new AncientFabricBlock(color); - ANCIENT_FABRIC_BLOCKS.put(color, block); - return register(block); - } - - private static Block registerFabric(DyeColor color) { - Block block = new FabricBlock(color); + private static RegistrySupplier registerFabric(DyeColor color) { + RegistrySupplier block = register(color.getSerializedName() + "_fabric", () -> new AncientFabricBlock(color)); FABRIC_BLOCKS.put(color, block); - return register(block); + return block; } - public static void init() { - Matrix.register(ModBlocks.class, Registries.BLOCK); -// DoorDataReader.read(); - } - - @Environment(EnvType.CLIENT) - public static void initClient() { - BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ModBlocks.QUARTZ_DOOR, ModBlocks.GOLD_DOOR); +// @Environment(EnvType.CLIENT) +// public static void initClient() { +// BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ModBlocks.QUARTZ_DOOR, ModBlocks.GOLD_DOOR); // DoorData.DOORS.forEach(door -> BlockRenderLayerMap.INSTANCE.putBlock(door, RenderLayer.getCutout())); - } +// } - public static Block ancientFabricFromDye(DyeColor color) { + public static RegistrySupplier ancientFabricFromDye(DyeColor color) { return ANCIENT_FABRIC_BLOCKS.get(color); } - public static Block fabricFromDye(DyeColor color) { + public static RegistrySupplier fabricFromDye(DyeColor color) { return FABRIC_BLOCKS.get(color); } - public static Block createFence(Block block) { - return new FenceBlock(BlockBehaviour.Properties.copy(block)); + public static RegistrySupplier register(String name, Supplier block) { + var supplier = BLOCKS.register(name, block); + ModItems.register(name, properties -> new BlockItem(block.get(), properties)); + return supplier; } - public static Block createFenceGate(Block block) { - return new FenceGateBlock(BlockBehaviour.Properties.copy(block), WoodType.OAK); // TODO: parameterize WoodType and BlockSetType + public static RegistrySupplier registerFence(String name, Block block) { + return register(name, () -> new FenceBlock(of(block))); } - public static Block createButton(Block block) { - return new ButtonBlock(BlockBehaviour.Properties.copy(block).noCollission().strength(0.5F), BlockSetType.STONE, 20, false); + public static RegistrySupplier registerFenceGate(String name, Block block) { + return register(name, () -> new FenceGateBlock(of(block), WoodType.OAK)); // TODO: parameterize WoodType and BlockSetType } - public static Block createSlab(Block block) { - return new SlabBlock(BlockBehaviour.Properties.copy(block)); + public static RegistrySupplier registerButton(String name, Block block) { + return register(name, () -> new ButtonBlock(of(block).noCollission().strength(0.5F), BlockSetType.STONE, 20, false)); } - public static Block createStairs(Block block) { - return new StairBlock(block.defaultBlockState(), BlockBehaviour.Properties.copy(block)); + public static RegistrySupplier registerSlab(String name, Block block) { + return register(name, () -> new SlabBlock(of(block))); } - public static Block createWall(Block block) { - return new WallBlock(BlockBehaviour.Properties.copy(block)); + public static RegistrySupplier registerStairs(String name, Block block) { + return register(name, () -> new StairBlock(block.defaultBlockState(), of(block))); + } + + public static RegistrySupplier registerWall(String name, Block block) { + return register(name, () -> new WallBlock(of(block))); + } + + private static BlockBehaviour.Properties of(Material material, MaterialColor color) { + return BlockBehaviour.Properties.of(material, color); + } + + private static BlockBehaviour.Properties of(Material material) { + return of(material); + } + + private static BlockBehaviour.Properties of(Block block) { + return BlockBehaviour.Properties.copy(block); } } diff --git a/common/src/main/java/org/dimdev/dimdoors/block/door/DimensionalTrapdoorBlock.java b/common/src/main/java/org/dimdev/dimdoors/block/door/DimensionalTrapdoorBlock.java index c2f6477d..44e5d34d 100644 --- a/common/src/main/java/org/dimdev/dimdoors/block/door/DimensionalTrapdoorBlock.java +++ b/common/src/main/java/org/dimdev/dimdoors/block/door/DimensionalTrapdoorBlock.java @@ -1,68 +1,65 @@ package org.dimdev.dimdoors.block.door; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockSetType; -import net.minecraft.block.BlockState; -import net.minecraft.block.TrapdoorBlock; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.fluid.Fluids; -import net.minecraft.sound.SoundEvent; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.util.shape.VoxelShapes; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; - +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.TrapDoorBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockSetType; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; import org.dimdev.dimdoors.block.RiftProvider; import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; +import org.jetbrains.annotations.Nullable; // TODO: Make this placeable on rifts -public class DimensionalTrapdoorBlock extends TrapdoorBlock implements RiftProvider { - public DimensionalTrapdoorBlock(Block.Settings settings, BlockSetType setType) { +public class DimensionalTrapdoorBlock extends TrapDoorBlock implements RiftProvider { + public DimensionalTrapdoorBlock(BlockBehaviour.Properties settings, BlockSetType setType) { super(settings, setType); } @Override @SuppressWarnings("deprecation") - public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { - if (!world.isClient && state.get(TrapdoorBlock.OPEN)) { + public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (!world.isClientSide() && state.getValue(TrapDoorBlock.OPEN)) { this.getRift(world, pos, state).teleport(entity); } } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new EntranceRiftBlockEntity(pos, state); } @Override - public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { state = state.cycle(OPEN); - world.setBlockState(pos, state, 2); + world.setBlock(pos, state, 2); - if (state.get(WATERLOGGED)) { - world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + if (state.getValue(WATERLOGGED)) { + world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); } - this.playToggleSound(player, world, pos, state.get(OPEN)); - return ActionResult.SUCCESS; + this.playSound(player, world, pos, state.getValue(OPEN)); + return InteractionResult.SUCCESS; } @Override - public EntranceRiftBlockEntity getRift(World world, BlockPos pos, BlockState state) { + public EntranceRiftBlockEntity getRift(Level world, BlockPos pos, BlockState state) { return (EntranceRiftBlockEntity) world.getBlockEntity(pos); } @Override - public VoxelShape getRaycastShape(BlockState state, BlockView world, BlockPos pos) { - return VoxelShapes.fullCube(); + public VoxelShape getInteractionShape(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos) { + return Shapes.block(); } } diff --git a/common/src/main/java/org/dimdev/dimdoors/fluid/ModFluids.java b/common/src/main/java/org/dimdev/dimdoors/fluid/ModFluids.java index 0f2b0fb0..a4411d82 100644 --- a/common/src/main/java/org/dimdev/dimdoors/fluid/ModFluids.java +++ b/common/src/main/java/org/dimdev/dimdoors/fluid/ModFluids.java @@ -4,8 +4,10 @@ import java.util.function.Function; import dev.architectury.core.fluid.ArchitecturyFluidAttributes; import dev.architectury.core.fluid.SimpleArchitecturyFluidAttributes; +import dev.architectury.registry.registries.DeferredRegister; import net.minecraft.client.MinecraftClient; import net.minecraft.client.texture.Sprite; +import net.minecraft.core.registries.Registries; import net.minecraft.fluid.FlowableFluid; import net.minecraft.fluid.Fluid; import net.minecraft.fluid.FluidState; @@ -26,9 +28,12 @@ import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; import net.minecraft.world.level.material.FlowingFluid; +import net.minecraft.world.level.material.Fluid; import org.dimdev.dimdoors.DimensionalDoors; public class ModFluids { + public static final DeferredRegister FLUIDS = DeferredRegister.create(DimensionalDoors.MOD_ID, Registries.FLUID); + public static final FlowingFluid ETERNAL_FLUID = register("dimdoors:eternal_fluid", new EternalFluid.Still()); public static final FlowableFluid FLOWING_ETERNAL_FLUID = register("dimdoors:flowing_eternal_fluid", new EternalFluid.Flowing()); diff --git a/common/src/main/java/org/dimdev/dimdoors/item/DimensionalEraserItem.java b/common/src/main/java/org/dimdev/dimdoors/item/DimensionalEraserItem.java new file mode 100644 index 00000000..946863a5 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/DimensionalEraserItem.java @@ -0,0 +1,51 @@ +package org.dimdev.dimdoors.item; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.dimdev.dimdoors.api.util.TeleportUtil; +import org.dimdev.dimdoors.block.ModBlocks; +import org.dimdev.dimdoors.sound.ModSoundEvents; +import org.dimdev.dimdoors.world.ModDimensions; +import org.dimdev.dimdoors.world.pocket.VirtualLocation; + +import static org.dimdev.dimdoors.api.util.math.MathUtil.entityEulerAngle; + +public class DimensionalEraserItem extends Item { + public DimensionalEraserItem(Settings settings) { + super(settings); + } + + @Override + public TypedActionResult use(World world, PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + + HitResult hit = RaycastHelper.raycast(player, RaycastHelper.REACH_DISTANCE, 1.0F, a -> !(a instanceof PlayerEntity)); + + if (hit != null && hit.getType() == HitResult.Type.ENTITY) { + if(((EntityHitResult) hit).getEntity() instanceof ServerPlayerEntity) { + BlockPos teleportPos = ((EntityHitResult) hit).getEntity().getBlockPos(); + while(ModDimensions.LIMBO_DIMENSION.getBlockState(VirtualLocation.getTopPos(ModDimensions.LIMBO_DIMENSION, teleportPos.getX(), teleportPos.getZ())).getBlock() == ModBlocks.ETERNAL_FLUID) { + teleportPos = teleportPos.add(1, 0, 1); + } + TeleportUtil.teleport(((EntityHitResult) hit).getEntity(), ModDimensions.LIMBO_DIMENSION, teleportPos.withY(255), entityEulerAngle(((EntityHitResult) hit).getEntity()), ((EntityHitResult) hit).getEntity().getVelocity()); + } + + ((EntityHitResult) hit).getEntity().remove(Entity.RemovalReason.KILLED); + player.playSound(ModSoundEvents.BLOOP, 1.0f, 1.0f); + return new TypedActionResult<>(ActionResult.SUCCESS, stack); + } + + return new TypedActionResult<>(ActionResult.FAIL, stack); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/ItemExtensions.java b/common/src/main/java/org/dimdev/dimdoors/item/ItemExtensions.java new file mode 100644 index 00000000..450852a1 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/ItemExtensions.java @@ -0,0 +1,16 @@ +package org.dimdev.dimdoors.item; + +import net.minecraft.world.item.Item; + +public interface ItemExtensions { + Item.Properties dimdoors_getSettings(); + + static Item.Properties getSettings(Item item) { + Item.Properties settings = ((ItemExtensions) item).dimdoors_getSettings(); + return ((SettingsExtensions) settings).clone(); + } + + interface SettingsExtensions extends Cloneable { + Item.Properties clone(); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/MaskWandItem.java b/common/src/main/java/org/dimdev/dimdoors/item/MaskWandItem.java new file mode 100644 index 00000000..fc7202ac --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/MaskWandItem.java @@ -0,0 +1,65 @@ +package org.dimdev.dimdoors.item; + +import java.util.List; + +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.HitResult; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import net.minecraft.client.item.TooltipContext; +import net.minecraft.client.resource.language.I18n; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.world.World; + +import net.fabricmc.api.Environment; + +import static net.fabricmc.api.EnvType.CLIENT; + + public class MaskWandItem extends Item { + private static final Logger LOGGER = LogManager.getLogger(); + + public static final String ID = "rift_configuration_tool"; + + public MaskWandItem(Properties settings) { + super(settings); + } + + @Override + public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { + ItemStack stack = player.getItemInHand(hand); + HitResult hit = player.pick(RaycastHelper.REACH_DISTANCE, 0, false); + + if (world.isClientSide()) { + return InteractionResultHolder.fail(stack); + } else { + if(hit.getType().equals(HitResult.Type.BLOCK)) { +// MaskEntity mask = ModEntityTypes.MASK.create((ServerWorld) world, null, LiteralText.EMPTY, player, ((BlockHitResult) hit).getBlockPos(), SpawnReason.SPAWNER, true, false); +// world.spawnEntity(mask); + } + } + + return InteractionResultHolder.success(stack); + } + + @Override + @Environment(CLIENT) + public void appendTooltip(ItemStack itemStack, World world, List list, TooltipContext tooltipContext) { + if (I18n.hasTranslation(this.getTranslationKey() + ".info")) { + list.add(Text.translatable(this.getTranslationKey() + ".info")); + } + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/ModArmorMaterials.java b/common/src/main/java/org/dimdev/dimdoors/item/ModArmorMaterials.java new file mode 100644 index 00000000..338fe91e --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/ModArmorMaterials.java @@ -0,0 +1,77 @@ +package org.dimdev.dimdoors.item; + +import net.minecraft.item.ArmorItem; +import net.minecraft.item.ArmorMaterial; +import net.minecraft.sound.SoundEvents; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.Lazy; +import net.minecraft.util.LazyLoadedValue; +import net.minecraft.world.item.ArmorMaterial; +import net.minecraft.world.item.crafting.Ingredient; + +public enum ModArmorMaterials implements ArmorMaterial { + WORLD_THREAD(5, 15, SoundEvents.ARMOR_EQUIP_LEATHER, new LazyLoadedValue<>(() -> Ingredient.of(ModItems.WORLD_THREAD.get())), "world_thread", new int[]{1, 2, 3, 1}, 0.0F, 0.0F), + GARMENT_OF_REALITY(5, 15, SoundEvents.ARMOR_EQUIP_LEATHER, new LazyLoadedValue<>(() -> Ingredient.of(ModItems.INFRANGIBLE_FIBER.get())), "garment_of_reality", new int[]{1, 2, 3, 1}, 0.0F, 0.0F); //TODO: DEFINE TRAITS + + private static final int[] BASE_DURABILITY = new int[]{13, 15, 16, 11}; + private final int durabilityMultiplier; + private final int enchantability; + private final SoundEvent equipSound; + private final LazyLoadedValue repairIngredient; + private final String name; + private final int[] protectionAmounts; + private final float toughness; + private final float knockbackResistance; + + ModArmorMaterials(int durabilityMultiplier, int enchantability, SoundEvent equipSound, LazyLoadedValue repairIngredient, String name, int[] protectionAmounts, float toughness, float knockbackResistance) { + this.durabilityMultiplier = durabilityMultiplier; + this.enchantability = enchantability; + this.equipSound = equipSound; + this.repairIngredient = repairIngredient; + this.name = name; + this.protectionAmounts = protectionAmounts; + this.toughness = toughness; + this.knockbackResistance = knockbackResistance; + } + + @Override + public int getDurability(ArmorItem.Type type) { + return BASE_DURABILITY[type.getEquipmentSlot().getEntitySlotId()] * this.durabilityMultiplier; + } + + @Override + public int getProtection(ArmorItem.Type type) { + return this.protectionAmounts[type.getEquipmentSlot().getEntitySlotId()]; + } + + @Override + public int getEnchantability() { + return this.enchantability; + } + + @Override + public SoundEvent getEquipSound() { + return this.equipSound; + } + + @Override + public Ingredient getRepairIngredient() { + return this.repairIngredient.get(); + } + + @Override + public String getName() { + return this.name; + } + + @Override + public float getToughness() { + return this.toughness; + } + + @Override + public float getKnockbackResistance() { + return this.knockbackResistance; + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/ModItems.java b/common/src/main/java/org/dimdev/dimdoors/item/ModItems.java new file mode 100644 index 00000000..767c847f --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/ModItems.java @@ -0,0 +1,314 @@ +package org.dimdev.dimdoors.item; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; + +import dev.architectury.registry.CreativeTabRegistry; +import dev.architectury.registry.registries.DeferredRegister; +import dev.architectury.registry.registries.RegistrySupplier; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.item.*; +import net.minecraft.world.level.block.Block; +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.matrix.Matrix; +import org.dimdev.matrix.Registrar; +import org.dimdev.matrix.RegistryEntry; + +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.BlockItem; +import net.minecraft.item.BucketItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.item.SpawnEggItem; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; + +import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback; +import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; + +import org.dimdev.dimdoors.block.ModBlocks; +import org.dimdev.dimdoors.entity.ModEntityTypes; +import org.dimdev.dimdoors.fluid.ModFluids; +import org.dimdev.dimdoors.item.door.DimensionalTrapdoorItem; +import org.dimdev.dimdoors.rift.targets.RandomTarget; +import org.dimdev.dimdoors.sound.ModSoundEvents; + +import static org.dimdev.dimdoors.DimensionalDoors.id; + +@SuppressWarnings("unused") +@Registrar(element = Item.class, modid = "dimdoors") +public final class ModItems { + // DO NOT REMOVE!!! + public static final DeferredRegister REGISTRY = DeferredRegister.create(DimensionalDoors.MOD_ID, Registries.ITEM); + + public static final RegistrySupplier STONE_PLAYER = registerWithoutTab("stone_player", ModBlocks.STONE_PLAYER); + + @RegistryEntry("quartz_door") public static final Item QUARTZ_DOOR = create(ModBlocks.QUARTZ_DOOR); + + @RegistryEntry("gold_door") public static final Item GOLD_DOOR = create(ModBlocks.GOLD_DOOR); + + @RegistryEntry("stone_door") public static final Item STONE_DOOR = create(ModBlocks.STONE_DOOR); + + @RegistryEntry("wood_dimensional_trapdoor") public static final Item OAK_DIMENSIONAL_TRAPDOOR = create(new DimensionalTrapdoorItem( + ModBlocks.OAK_DIMENSIONAL_TRAPDOOR, + new Item.Properties().stacksTo(1), + rift -> rift.setDestination( + RandomTarget.builder() + .acceptedGroups(Collections.singleton(0)) + .coordFactor(1) + .negativeDepthFactor(80) + .positiveDepthFactor(Double.MAX_VALUE) + .weightMaximum(100) + .noLink(false) + .newRiftWeight(0) + .build()) + )); + + public static final RegistrySupplier WORLD_THREAD = create("world_thread", () -> new Item(new Item.Properties())); + + public static final RegistrySupplier INFRANGIBLE_FIBER = create("infrangible_fiber", () -> new Item(new Item.Properties())); + + public static final RegistrySupplier FRAYED_FILAMENTS = create("frayed_filament", () -> new Item(new Item.Properties())); + + public static final RegistrySupplier RIFT_CONFIGURATION_TOOL = create("rift_configuration_tool", () -> new RiftConfigurationToolItem()); + + public static final RegistrySupplier RIFT_BLADE = create("rift_blade", () -> new RiftBladeItem(new Item.Properties().durability(100))); + + public static final RegistrySupplier RIFT_REMOVER = create("rift_remover", () -> new RiftRemoverItem(new Item.Properties().stacksTo(1).durability(100))); + + public static final RegistrySupplier RIFT_SIGNATURE = create("rift_signature", () -> new RiftSignatureItem(new Item.Properties().stacksTo(1).maxDamage(1))); + + public static final RegistrySupplier STABILIZED_RIFT_SIGNATURE = create("stabilized_rift_signature", () -> new StabilizedRiftSignatureItem(new Item.Properties().stacksTo(1).maxDamage(20))); + + public static final RegistrySupplier RIFT_STABILIZER = create("rift_stabilizer", () -> new RiftStabilizerItem(new Item.Properties().stacksTo(1).maxDamage(6))); + + public static final RegistrySupplier RIFT_KEY = create("rift_key", () -> new RiftKeyItem(new Item.Properties().fireproof().stacksTo(1))); + + public static final RegistrySupplier DIMENSIONAL_ERASER = create("dimensional_eraser", () -> new DimensionalEraserItem(new Item.Properties().maxDamage(100))); + + public static final RegistrySupplier MONOLITH_SPAWNER = new "monolith_spawner", () -> SpawnEggItem(ModEntityTypes.MONOLITH, 0xffffff, 0xffffff, new Item.Properties()); + + public static final RegistrySupplier WORLD_THREAD_HELMET = create("world_thread_helmet", () -> new ArmorItem(ArmorItem(ModArmorMaterials.WORLD_THREAD, ArmorItem.Type.HELMET, new Item.Properties())); + + public static final RegistrySupplier WORLD_THREAD_CHESTPLATE = create("world_thread_chestplate", () -> new ArmorItem(ModArmorMaterials.WORLD_THREAD, ArmorItem.Type.CHESTPLATE, new Item.Properties())); + + public static final RegistrySupplier WORLD_THREAD_LEGGINGS = create("world_thread_leggings", () -> new ArmorItem(ModArmorMaterials.WORLD_THREAD, ArmorItem.Type.LEGGINGS, new Item.Properties())); + + public static final RegistrySupplier WORLD_THREAD_BOOTS = create("world_thread_boots", () -> new ArmorItem(ModArmorMaterials.WORLD_THREAD, ArmorItem.Type.BOOTS, new Item.Properties())); + + public static final RegistrySupplier MASK_WAND = create("mask_wand", () -> new MaskWandItem(new Item.Properties().stacksTo(100)/**/)); + + public static final RegistrySupplier STABLE_FABRIC = create("stable_fabric", () -> new Item(new Item.Properties())); + + public static final RegistrySupplier WHITE_FABRIC = create("white_fabric", () -> ModBlocks.WHITE_FABRIC); + + public static final RegistrySupplier ORANGE_FABRIC = create("orange_fabric", () -> ModBlocks.ORANGE_FABRIC); + + public static final RegistrySupplier MAGENTA_FABRIC = create("magenta_fabric", () -> ModBlocks.MAGENTA_FABRIC); + + public static final RegistrySupplier LIGHT_BLUE_FABRIC = create("light_blue_fabric", () -> ModBlocks.LIGHT_BLUE_FABRIC); + + public static final RegistrySupplier YELLOW_FABRIC = create("yellow_fabric", () -> ModBlocks.YELLOW_FABRIC); + + public static final RegistrySupplier LIME_FABRIC = create("lime_fabric", () -> ModBlocks.LIME_FABRIC); + + public static final RegistrySupplier PINK_FABRIC = create("pink_fabric", () -> ModBlocks.PINK_FABRIC); + + public static final RegistrySupplier GRAY_FABRIC = create("gray_fabric", () -> ModBlocks.GRAY_FABRIC); + + public static final RegistrySupplier LIGHT_GRAY_FABRIC = create("light_gray_fabric", () -> ModBlocks.LIGHT_GRAY_FABRIC); + + public static final RegistrySupplier CYAN_FABRIC = create("cyan_fabric", () -> ModBlocks.CYAN_FABRIC); + + public static final RegistrySupplier PURPLE_FABRIC = create("purple_fabric", () -> ModBlocks.PURPLE_FABRIC); + + public static final RegistrySupplier BLUE_FABRIC = create("blue_fabric", () -> ModBlocks.BLUE_FABRIC); + + public static final RegistrySupplier BROWN_FABRIC = create("brown_fabric", () -> ModBlocks.BROWN_FABRIC); + + public static final RegistrySupplier GREEN_FABRIC = create("green_fabric", () -> ModBlocks.GREEN_FABRIC); + + public static final RegistrySupplier RED_FABRIC = create("red_fabric", () -> ModBlocks.RED_FABRIC); + + public static final RegistrySupplier BLACK_FABRIC = create("black_fabric", () -> ModBlocks.BLACK_FABRIC); + + public static final RegistrySupplier WHITE_ANCIENT_FABRIC = create("white_ancient_fabric", () -> ModBlocks.WHITE_ANCIENT_FABRIC); + + public static final RegistrySupplier ORANGE_ANCIENT_FABRIC = create("orange_ancient_fabric", () -> ModBlocks.ORANGE_ANCIENT_FABRIC); + + public static final RegistrySupplier MAGENTA_ANCIENT_FABRIC = create("magenta_ancient_fabric", () -> ModBlocks.MAGENTA_ANCIENT_FABRIC); + + public static final RegistrySupplier LIGHT_BLUE_ANCIENT_FABRIC = create("light_blue_ancient_fabric", () -> ModBlocks.LIGHT_BLUE_ANCIENT_FABRIC); + + public static final RegistrySupplier YELLOW_ANCIENT_FABRIC = create("yellow_ancient_fabric", () -> ModBlocks.YELLOW_ANCIENT_FABRIC); + + public static final RegistrySupplier LIME_ANCIENT_FABRIC = create("lime_ancient_fabric", () -> ModBlocks.LIME_ANCIENT_FABRIC); + + public static final RegistrySupplier PINK_ANCIENT_FABRIC = create("pink_ancient_fabric", () -> ModBlocks.PINK_ANCIENT_FABRIC); + + public static final RegistrySupplier GRAY_ANCIENT_FABRIC = create("gray_ancient_fabric", () -> ModBlocks.GRAY_ANCIENT_FABRIC); + + public static final RegistrySupplier LIGHT_GRAY_ANCIENT_FABRIC = create("light_gray_ancient_fabric", () -> ModBlocks.LIGHT_GRAY_ANCIENT_FABRIC); + + public static final RegistrySupplier CYAN_ANCIENT_FABRIC = create("cyan_ancient_fabric", () -> ModBlocks.CYAN_ANCIENT_FABRIC); + + public static final RegistrySupplier PURPLE_ANCIENT_FABRIC = create("purple_ancient_fabric", () -> ModBlocks.PURPLE_ANCIENT_FABRIC); + + public static final RegistrySupplier BLUE_ANCIENT_FABRIC = create("blue_ancient_fabric", () -> ModBlocks.BLUE_ANCIENT_FABRIC); + + public static final RegistrySupplier BROWN_ANCIENT_FABRIC = create("brown_ancient_fabric", () -> ModBlocks.BROWN_ANCIENT_FABRIC); + + public static final RegistrySupplier GREEN_ANCIENT_FABRIC = create("green_ancient_fabric", () -> ModBlocks.GREEN_ANCIENT_FABRIC); + + public static final RegistrySupplier RED_ANCIENT_FABRIC = create("red_ancient_fabric", () -> ModBlocks.RED_ANCIENT_FABRIC); + + public static final RegistrySupplier BLACK_ANCIENT_FABRIC = create("black_ancient_fabric", () -> ModBlocks.BLACK_ANCIENT_FABRIC); + + public static final RegistrySupplier DECAYED_BLOCK = createWithoutItemGroup("decayed_block", () -> ModBlocks.DECAYED_BLOCK); + + public static final RegistrySupplier UNFOLDED_BLOCK = createWithoutItemGroup("unfolded_block", () -> ModBlocks.UNFOLDED_BLOCK); + + public static final RegistrySupplier UNWARPED_BLOCK = createWithoutItemGroup("unwarped_block", () -> ModBlocks.UNWARPED_BLOCK); + + public static final RegistrySupplier UNRAVELLED_BLOCK = createWithoutItemGroup("unravelled_block", () -> ModBlocks.UNRAVELLED_BLOCK); + + public static final RegistrySupplier UNRAVELLED_FABRIC = create("unravelled_fabric", () -> ModBlocks.UNRAVELLED_FABRIC); + + public static final RegistrySupplier CREEPY_RECORD = create("creepy_record", () -> new net.minecraft.item.MusicDiscItem(10, ModSoundEvents.CREEPY, new Item.Properties(), 317)); + + public static final RegistrySupplier WHITE_VOID_RECORD = create("white_void_record", () -> new net.minecraft.item.MusicDiscItem(10, ModSoundEvents.WHITE_VOID, new Item.Properties(), 225)); + + public static final RegistrySupplier MARKING_PLATE = createWithoutItemGroup("marking_plate", () -> ModBlocks.MARKING_PLATE); + +// @RegistryEntry("eternal_fluid")// public static final Item ETERNAL_FLUID = create(ModBlocks.ETERNAL_FLUID); + + @RegistryEntry("eternal_fluid_bucket") public static final Item ETERNAL_FLUID_BUCKET = create(new BucketItem(ModFluids.ETERNAL_FLUID, new Item.Properties().recipeRemainder(Items.BUCKET).stacksTo(1))); + + @RegistryEntry("solid_static") public static final Item SOLID_STATIC = create(ModBlocks.SOLID_STATIC); + + @RegistryEntry("tesselating_loom") public static final Item TESSELATING_LOOM = create(ModBlocks.TESSELATING_LOOM); + + @RegistryEntry("mask_shard") public static final Item MASK_SHARD = create(new Item(new Item.Properties()/**/)); + + @RegistryEntry("fuzzy_fireball") public static final Item FUZZY_FIREBALL = create(new Item(new Item.Properties())); + + @RegistryEntry("fabric_of_finality") public static final Item FABRIC_OF_FINALITY = create(new Item(new Item.Properties())); + + @RegistryEntry("reality_sponge") public static final Item REALITY_SPONGE = create(ModBlocks.REALITY_SPONGE); + + @RegistryEntry("liminal_lint") public static final Item LIMINAL_LINT = create(new Item(new Item.Properties())); + + @RegistryEntry("enduring_fibers") public static final Item ENDURING_FIBERS = create(new Item(new Item.Properties())); + + @RegistryEntry("rift_pearl") public static final Item RIFT_PEARL = create(new Item(new Item.Properties())); + + @RegistryEntry("fabric_of_reality") public static final Item FABRIC_OF_REALITY = create(new Item(new Item.Properties())); + + @RegistryEntry("amalgam_lump") public static final Item AMALGAM_LUMP = new Item(new Item.Properties()); + + @RegistryEntry("clod") public static final Item CLOD = new Item(new Item.Properties()); + + @RegistryEntry("garment_of_reality_helmet") public static final Item GARMENT_OF_REALITY_HELMET = create(new ArmorItem(ModArmorMaterials.GARMENT_OF_REALITY, ArmorItem.Type.HELMET, new Item.Properties())); + + @RegistryEntry("garment_of_reality_chestplate") public static final Item GARMENT_OF_REALITY_CHESTPLATE = create(new ArmorItem(ModArmorMaterials.GARMENT_OF_REALITY, ArmorItem.Type.CHESTPLATE, new Item.Properties())); + + @RegistryEntry("garment_of_reality_leggings") public static final Item GARMENT_OF_REALITY_LEGGINGS = create(new ArmorItem(ModArmorMaterials.GARMENT_OF_REALITY, ArmorItem.Type.LEGGINGS, new Item.Properties())); + + @RegistryEntry("garment_of_reality_boots") public static final Item GARMENT_OF_REALITY_BOOTS = create(new ArmorItem(ModArmorMaterials.GARMENT_OF_REALITY, ArmorItem.Type.BOOTS, new Item.Properties())); + + @RegistryEntry("driftwood_log") public static final Item DRIFTWOOD_LOG = create(ModBlocks.DRIFTWOOD_LOG); + @RegistryEntry("driftwood_planks") public static final Item DRIFTWOOD_PLANKS = create(ModBlocks.DRIFTWOOD_PLANKS); + @RegistryEntry("driftwood_fence") public static final Item DRIFTWOOD_FENCE = create(ModBlocks.DRIFTWOOD_FENCE); + @RegistryEntry("driftwood_gate") public static final Item DRIFTWOOD_GATE = create(ModBlocks.DRIFTWOOD_GATE); + @RegistryEntry("driftwood_button") public static final Item DRIFTWOOD_BUTTON = create(ModBlocks.DRIFTWOOD_BUTTON); + @RegistryEntry("driftwood_slab") public static final Item DRIFTWOOD_SLAB = create(ModBlocks.DRIFTWOOD_SLAB); + @RegistryEntry("driftwood_stairs") public static final Item DRIFTWOOD_STAIRS = create(ModBlocks.DRIFTWOOD_STAIRS); + @RegistryEntry("driftwood_door") public static final Item DRIFTWOOD_DOOR = create(ModBlocks.DRIFTWOOD_DOOR); + @RegistryEntry("driftwood_trapdoor") public static final Item DRIFTWOOD_TRAPDOOR = create(ModBlocks.DRIFTWOOD_TRAPDOOR); + + @RegistryEntry("amalgam_block") public static final Item AMALGAM_BLOCK = create(ModBlocks.AMALGAM_BLOCK); + @RegistryEntry("amalgam_door") public static final Item AMALGAM_DOOR = create(ModBlocks.AMALGAM_DOOR); + @RegistryEntry("amalgam_trapdoor") public static final Item AMALGAM_TRAPDOOR = create(ModBlocks.AMALGAM_TRAPDOOR); + @RegistryEntry("rust") public static final Item RUST = create(ModBlocks.RUST); + @RegistryEntry("amalgam_slab") public static final Item AMALGAM_SLAB = create(ModBlocks.AMALGAM_SLAB); + @RegistryEntry("amalgam_stairs") public static final Item AMALGAM_STAIRS = create(ModBlocks.AMALGAM_STAIRS); + @RegistryEntry("amalgam_ore") public static final Item AMALGAM_ORE = create(ModBlocks.AMALGAM_ORE); + @RegistryEntry("clod_ore") public static final Item CLOD_ORE = create(ModBlocks.CLOD_ORE); + + @RegistryEntry("clod_block") public static final Item CLOD_BLOCK = create(ModBlocks.CLOD_BLOCK); + @RegistryEntry("gravel_fence") public static final Item GRAVEL_FENCE = create(ModBlocks.GRAVEL_FENCE); + @RegistryEntry("gravel_gate") public static final Item GRAVEL_GATE = create(ModBlocks.GRAVEL_GATE); + @RegistryEntry("gravel_button") public static final Item GRAVEL_BUTTON = create(ModBlocks.GRAVEL_BUTTON); + @RegistryEntry("gravel_slab") public static final Item GRAVEL_SLAB = create(ModBlocks.GRAVEL_SLAB); + @RegistryEntry("gravel_stairs") public static final Item GRAVEL_STAIRS = create(ModBlocks.GRAVEL_STAIRS); + @RegistryEntry("gravel_wall") public static final Item GRAVEL_WALL = create(ModBlocks.GRAVEL_WALL); + + @RegistryEntry("dark_sand") public static final Item DARK_SAND = create(ModBlocks.DARK_SAND); + @RegistryEntry("dark_sand_fence") public static final Item DARK_SAND_FENCE = create(ModBlocks.DARK_SAND_FENCE); + @RegistryEntry("dark_sand_gate") public static final Item DARK_SAND_GATE = create(ModBlocks.DARK_SAND_GATE); + @RegistryEntry("dark_sand_button") public static final Item DARK_SAND_BUTTON = create(ModBlocks.DARK_SAND_BUTTON); + @RegistryEntry("dark_sand_slab") public static final Item DARK_SAND_SLAB = create(ModBlocks.DARK_SAND_SLAB); + @RegistryEntry("dark_sand_stairs") public static final Item DARK_SAND_STAIRS = create(ModBlocks.DARK_SAND_STAIRS); + @RegistryEntry("dark_sand_wall") public static final Item DARK_SAND_WALL = create(ModBlocks.DARK_SAND_WALL); + + @RegistryEntry("clay_fence") public static final Item CLAY_FENCE = create(ModBlocks.CLAY_FENCE); + @RegistryEntry("clay_gate") public static final Item CLAY_GATE = create(ModBlocks.CLAY_GATE); + @RegistryEntry("clay_button") public static final Item CLAY_BUTTON = create(ModBlocks.CLAY_BUTTON); + @RegistryEntry("clay_slab") public static final Item CLAY_SLAB = create(ModBlocks.CLAY_SLAB); + @RegistryEntry("clay_stairs") public static final Item CLAY_STAIRS = create(ModBlocks.CLAY_STAIRS); + + @RegistryEntry("mud_fence") public static final Item MUD_FENCE = create(ModBlocks.MUD_FENCE); + @RegistryEntry("mud_gate") public static final Item MUD_GATE = create(ModBlocks.MUD_GATE); + @RegistryEntry("mud_button") public static final Item MUD_BUTTON = create(ModBlocks.MUD_BUTTON); + @RegistryEntry("mud_slab") public static final Item MUD_SLAB = create(ModBlocks.MUD_SLAB); + @RegistryEntry("mud_stairs") public static final Item MUD_STAIRS = create(ModBlocks.MUD_STAIRS); + + @RegistryEntry("deepslate_slab") public static final Item DEEPSLATE_SLAB = create(ModBlocks.DEEPSLATE_SLAB); + @RegistryEntry("deepslate_stairs") public static final Item DEEPSLATE_STAIRS = create(ModBlocks.DEEPSLATE_STAIRS); + @RegistryEntry("deepslate_wall") public static final Item DEEPSLATE_WALL = create(ModBlocks.DEEPSLATE_WALL); + + @RegistryEntry("red_sand_slab") public static final Item RED_SAND_SLAB = create(ModBlocks.RED_SAND_SLAB); + @RegistryEntry("red_sand_stairs") public static final Item RED_SAND_STAIRS = create(ModBlocks.RED_SAND_STAIRS); + @RegistryEntry("red_sand_wall") public static final Item RED_SAND_WALL = create(ModBlocks.RED_SAND_WALL); + + @RegistryEntry("sand_slab") public static final Item SAND_SLAB = create(ModBlocks.SAND_SLAB); + @RegistryEntry("sand_stairs") public static final Item SAND_STAIRS = create(ModBlocks.SAND_STAIRS); + @RegistryEntry("sand_wall") public static final Item SAND_WALL = create(ModBlocks.SAND_WALL); + + @RegistryEntry("end_stone_slab") public static final Item END_STONE_SLAB = create(ModBlocks.END_STONE_SLAB); + @RegistryEntry("end_stone_stairs") public static final Item END_STONE_STAIRS = create(ModBlocks.END_STONE_STAIRS); + @RegistryEntry("end_stone_wall") public static final Item END_STONE_WALL = create(ModBlocks.END_STONE_WALL); + + @RegistryEntry("netherrack_fence") public static final Item NETHERRACK_FENCE = create(ModBlocks.NETHERRACK_FENCE); + @RegistryEntry("netherrack_slab") public static final Item NETHERRACK_SLAB = create(ModBlocks.NETHERRACK_SLAB); + @RegistryEntry("netherrack_stairs") public static final Item NETHERRACK_STAIRS = create(ModBlocks.NETHERRACK_STAIRS); + @RegistryEntry("netherrack_wall") public static final Item NETHERRACK_WALL = create(ModBlocks.NETHERRACK_WALL); + + @RegistryEntry("unraveled_spike") public static final Item UNRAVELED_SPIKE = create(ModBlocks.UNRAVELED_SPIKE); + @RegistryEntry("unraveled_fence") public static final Item UNRAVELED_FENCE = create(ModBlocks.UNRAVELED_FENCE); + @RegistryEntry("unraveled_gate") public static final Item UNRAVELED_GATE = create(ModBlocks.UNRAVELED_GATE); + @RegistryEntry("unraveled_button") public static final Item UNRAVELED_BUTTON = create(ModBlocks.UNRAVELED_BUTTON); + @RegistryEntry("unraveled_slab") public static final Item UNRAVELED_SLAB = create(ModBlocks.UNRAVELED_SLAB); + @RegistryEntry("unraveled_stairs") public static final Item UNRAVELED_STAIRS = create(ModBlocks.UNRAVELED_STAIRS); + public static final Set DOOR_ITEMS = new HashSet<>(); + + public static final CreativeTabRegistry.TabSupplier DIMENSIONAL_DOORS = CreativeTabRegistry.create(id("dimensional_doors"), () -> new ItemStack(ModItems.RIFT_BLADE.get())); + + public static RegistrySupplier register(String name, Function item) { + return register(name, () -> item.apply(new Item.Properties().arch$tab(DIMENSIONAL_DOORS))); + } + public static RegistrySupplier register(String name, Supplier item) { + return REGISTRY.register(name, item); + } + + public static void init() { + REGISTRY.register(); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/RaycastHelper.java b/common/src/main/java/org/dimdev/dimdoors/item/RaycastHelper.java new file mode 100644 index 00000000..2a59ac20 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/RaycastHelper.java @@ -0,0 +1,40 @@ +package org.dimdev.dimdoors.item; + +import java.util.function.Predicate; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.projectile.ProjectileUtil; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.BlockView; + +import org.dimdev.dimdoors.block.entity.DetachedRiftBlockEntity; +import org.dimdev.dimdoors.block.entity.RiftBlockEntity; + +public final class RaycastHelper { + public static final int REACH_DISTANCE = 5; + + public static boolean hitsDetachedRift(HitResult hit, BlockView world) { + return hit != null && hit.getType() == HitResult.Type.BLOCK && world.getBlockEntity(((BlockHitResult) hit).getBlockPos()) instanceof DetachedRiftBlockEntity; + } + + public static boolean hitsRift(HitResult hit, BlockView world) { + return hit != null && hit.getType() == HitResult.Type.BLOCK && world.getBlockEntity(((BlockHitResult) hit).getBlockPos()) instanceof RiftBlockEntity; + } + + public static boolean hitsLivingEntity(HitResult hit) { + return hit != null && hit.getType() == HitResult.Type.ENTITY && ((EntityHitResult) hit).getEntity() instanceof LivingEntity; + } + + public static HitResult raycast(Entity entity, double maxDistance, float tickDelta, Predicate predicate) { + Vec3d vec3d = entity.getCameraPosVec(tickDelta); + Vec3d vec3d2 = entity.getRotationVec(tickDelta); + Vec3d vec3d3 = vec3d.add(vec3d2.x * maxDistance, vec3d2.y * maxDistance, vec3d2.z * maxDistance); + Box box = entity.getBoundingBox().stretch(vec3d2.multiply(maxDistance)).expand(1.0D, 1.0D, 1.0D); + return ProjectileUtil.raycast(entity, vec3d, vec3d3, box, predicate, maxDistance); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/RiftBladeItem.java b/common/src/main/java/org/dimdev/dimdoors/item/RiftBladeItem.java new file mode 100644 index 00000000..b4f00376 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/RiftBladeItem.java @@ -0,0 +1,118 @@ +package org.dimdev.dimdoors.item; + +import java.util.List; +import java.util.Objects; + +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.SwordItem; +import net.minecraft.item.ToolMaterials; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.World; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.dimdoors.block.DimensionalPortalBlock; +import org.dimdev.dimdoors.block.ModBlocks; +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; +import org.dimdev.dimdoors.block.entity.RiftBlockEntity; +import org.dimdev.dimdoors.client.ToolTipHelper; + +public class RiftBladeItem extends SwordItem { + public static final String ID = "rift_blade"; + + public RiftBladeItem(Settings settings) { + super(ToolMaterials.IRON, 3, -2.4F, settings); + } + + @Environment(EnvType.CLIENT) + @Override + public void appendTooltip(ItemStack itemStack, World world, List list, TooltipContext tooltipContext) { + ToolTipHelper.processTranslation(list, this.getTranslationKey() + ".info"); + } + + @Override + public boolean hasGlint(ItemStack itemStack) { + return true; + } + + @Override + public boolean canRepair(ItemStack item, ItemStack repairingItem) { + return Objects.equals(ModItems.STABLE_FABRIC, repairingItem.getItem()); + } + + @Override + public TypedActionResult use(World world, PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + HitResult hit = RaycastHelper.raycast(player, 16, 0.0F, LivingEntity.class::isInstance); + + if (hit == null) { + hit = RaycastHelper.raycast(player, 16, 1.0F, LivingEntity.class::isInstance); + } + + if (hit == null) { + hit = player.raycast(16, 1.0F, false); //TODO: make the range of the Rift Blade configurable + } + + if (hit == null) { + hit = player.raycast(16, 0, false); + } + + if (world.isClient) { + if (RaycastHelper.hitsLivingEntity(hit) || RaycastHelper.hitsRift(hit, world)) { + return new TypedActionResult<>(ActionResult.SUCCESS, stack); + } else { + player.sendMessage(Text.translatable(this.getTranslationKey() + ".rift_miss"), true); + RiftBlockEntity.showRiftCoreUntil = System.currentTimeMillis() + DimensionalDoors.getConfig().getGraphicsConfig().highlightRiftCoreFor; + return new TypedActionResult<>(ActionResult.FAIL, stack); + } + } + + if (RaycastHelper.hitsLivingEntity(hit)) { + double damageMultiplier = (double) stack.getDamage() / (double) stack.getMaxDamage(); + // TODO: gaussian, instead or random + double offsetDistance = Math.random() * damageMultiplier * 7 + 2; //TODO: make these offset distances configurable + double offsetRotationYaw = (Math.random() - 0.5) * damageMultiplier * 360; + + Vec3d playerVec = player.getPos(); + Vec3d entityVec = hit.getPos(); + Vec3d offsetDirection = playerVec.subtract(entityVec).normalize(); + offsetDirection = offsetDirection.rotateY((float) (offsetRotationYaw * Math.PI) / 180); + + Vec3d added = entityVec.add(offsetDirection.multiply(offsetDistance)); + BlockPos teleportPosition = new BlockPos(new Vec3i((int) added.x, (int) added. y, (int) added.z)); + while (world.getBlockState(teleportPosition).getMaterial().blocksMovement()) + teleportPosition = teleportPosition.up(); + player.teleport(teleportPosition.getX(), teleportPosition.getY(), teleportPosition.getZ()); + player.setYaw((float) (Math.random() * 2 * Math.PI)); + + stack.damage(1, player, a -> a.sendToolBreakStatus(hand)); + return new TypedActionResult<>(ActionResult.SUCCESS, stack); + } else if (RaycastHelper.hitsDetachedRift(hit, world)) { + BlockHitResult blockHitResult = (BlockHitResult) hit; + BlockPos pos = blockHitResult.getBlockPos(); + RiftBlockEntity rift = (RiftBlockEntity) world.getBlockEntity(blockHitResult.getBlockPos()); + + world.setBlockState(pos, ModBlocks.DIMENSIONAL_PORTAL.getDefaultState().with(DimensionalPortalBlock.FACING, blockHitResult.getSide())); + ((EntranceRiftBlockEntity) world.getBlockEntity(pos)).setData(rift.getData()); + + stack.damage(1, player, a -> a.sendToolBreakStatus(hand)); + return new TypedActionResult<>(ActionResult.SUCCESS, stack); + } + return new TypedActionResult<>(ActionResult.FAIL, stack); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/RiftConfigurationToolItem.java b/common/src/main/java/org/dimdev/dimdoors/item/RiftConfigurationToolItem.java new file mode 100644 index 00000000..ea0ae7ce --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/RiftConfigurationToolItem.java @@ -0,0 +1,120 @@ +package org.dimdev.dimdoors.item; + +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.client.resource.language.I18n; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +import net.fabricmc.api.Environment; + +import org.dimdev.dimdoors.api.item.ExtendedItem; +import org.dimdev.dimdoors.api.util.EntityUtils; +import org.dimdev.dimdoors.block.entity.RiftBlockEntity; +import org.dimdev.dimdoors.item.component.CounterComponent; +import org.dimdev.dimdoors.network.ServerPacketHandler; +import org.dimdev.dimdoors.rift.targets.IdMarker; + +import static net.fabricmc.api.EnvType.CLIENT; + +public class RiftConfigurationToolItem extends Item implements ExtendedItem { + private static final Logger LOGGER = LogManager.getLogger(); + + public static final String ID = "rift_configuration_tool"; + + RiftConfigurationToolItem() { + super(new Item.Settings().maxCount(1).maxDamage(16)); + } + + @Override + public TypedActionResult use(World world, PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + HitResult hit = player.raycast(RaycastHelper.REACH_DISTANCE, 0, false); + + if (world.isClient) { + return TypedActionResult.fail(stack); + } else { + CounterComponent counter = CounterComponent.get(stack); + + if (RaycastHelper.hitsRift(hit, world)) { + RiftBlockEntity rift = (RiftBlockEntity) world.getBlockEntity(((BlockHitResult) hit).getBlockPos()); + + if (rift.getDestination() instanceof IdMarker && ((IdMarker) rift.getDestination()).getId() >= 0) { + EntityUtils.chat(player, Text.of("Id: " + ((IdMarker) rift.getDestination()).getId())); + } else { + int id = counter.increment(); + + ServerPacketHandler.get((ServerPlayerEntity) player).sync(stack, hand); + + EntityUtils.chat(player, Text.of("Rift stripped of data and set to target id: " + id)); + + rift.setDestination(new IdMarker(id)); + } + + return TypedActionResult.success(stack); + } else { + EntityUtils.chat(player, Text.of("Current Count: " + counter.count())); + } + } + + return TypedActionResult.success(stack); + } + + @Override + public TypedActionResult onAttackBlock(World world, PlayerEntity player, Hand hand, BlockPos pos, Direction direction) { + if (world.isClient) { + if (player.isSneaking()) { + if (CounterComponent.get(player.getStackInHand(hand)).count() != 0 || world.getBlockEntity(pos) instanceof RiftBlockEntity) { + return TypedActionResult.success(true); + } + return TypedActionResult.fail(false); + } + } else { + ItemStack stack = player.getStackInHand(hand); + if (player.isSneaking()) { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof RiftBlockEntity) { + RiftBlockEntity rift = (RiftBlockEntity) blockEntity; + if (!(rift.getDestination() instanceof IdMarker) || ((IdMarker) rift.getDestination()).getId() != -1) { + rift.setDestination(new IdMarker(-1)); + EntityUtils.chat(player, Text.of("Rift stripped of data and set to invalid id: -1")); + return TypedActionResult.success(false); + } + } else if (CounterComponent.get(stack).count() != 0) { + CounterComponent.get(stack).reset(); + + ServerPacketHandler.get((ServerPlayerEntity) player).sync(stack, hand); + + EntityUtils.chat(player, Text.of("Counter has been reset.")); + return TypedActionResult.success(false); + } + } + } + return TypedActionResult.pass(false); + } + + @Override + @Environment(CLIENT) + public void appendTooltip(ItemStack itemStack, World world, List list, TooltipContext tooltipContext) { + if (I18n.hasTranslation(this.getTranslationKey() + ".info")) { + list.add(Text.translatable(this.getTranslationKey() + ".info")); + } + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/RiftKeyItem.java b/common/src/main/java/org/dimdev/dimdoors/item/RiftKeyItem.java new file mode 100644 index 00000000..9958675b --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/RiftKeyItem.java @@ -0,0 +1,145 @@ +package org.dimdev.dimdoors.item; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.block.BlockState; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.nbt.NbtIntArray; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Uuids; +import net.minecraft.world.World; + +import net.fabricmc.fabric.api.util.NbtType; + +import org.dimdev.dimdoors.api.util.EntityUtils; +import org.dimdev.dimdoors.api.util.Location; +import org.dimdev.dimdoors.block.RiftProvider; +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; +import org.dimdev.dimdoors.block.entity.RiftBlockEntity; +import org.dimdev.dimdoors.mixin.accessor.ListTagAccessor; +import org.dimdev.dimdoors.network.ServerPacketHandler; +import org.dimdev.dimdoors.rift.registry.Rift; +import org.dimdev.dimdoors.world.level.registry.DimensionalRegistry; + +public class RiftKeyItem extends Item { + public RiftKeyItem(Settings settings) { + super(settings); + } + + @Override + public void appendTooltip(ItemStack stack, @Nullable World world, List tooltip, TooltipContext context) { + if (isEmpty(stack)) { + tooltip.add(Text.translatable("item.dimdoors.rift_key.no_links")); + } else if (context.isAdvanced()) { + for (UUID id : getIds(stack)) { + tooltip.add(Text.of(" " + id.toString())); + } + } + super.appendTooltip(stack, world, tooltip, context); + } + + @Override + public boolean hasGlint(ItemStack stack) { + return !isEmpty(stack); + } + + @Override + public boolean isNbtSynced() { + return super.isNbtSynced(); + } + + @Override + public int getMaxUseTime(ItemStack stack) { + return 30; + } + + @Override + public void onCraft(ItemStack stack, World world, PlayerEntity player) { + stack.setNbt(this.getDefaultStack().getNbt()); + } + + @Override + public ItemStack getDefaultStack() { + ItemStack stack = super.getDefaultStack(); + stack.setSubNbt("Ids", ListTagAccessor.createListTag(new ArrayList<>(), (byte) NbtType.INT_ARRAY)); + return stack; + } + + @Override + public ActionResult useOnBlock(ItemUsageContext context) { + if (context.getWorld().isClient) { + return ActionResult.CONSUME; + } + PlayerEntity player = context.getPlayer(); + BlockState state = context.getWorld().getBlockState(context.getBlockPos()); + if (player != null && state.getBlock() instanceof RiftProvider && player.isSneaky()) { + RiftBlockEntity riftBlockEntity = ((RiftProvider) state.getBlock()).getRift(context.getWorld(), context.getBlockPos(), state); + if (riftBlockEntity.isDetached()) { + return super.useOnBlock(context); + } + EntranceRiftBlockEntity entranceRiftBlockEntity = ((EntranceRiftBlockEntity) riftBlockEntity); + Rift rift = DimensionalRegistry.getRiftRegistry().getRift(new Location(entranceRiftBlockEntity.getWorld().getRegistryKey(), entranceRiftBlockEntity.getPos())); + if (entranceRiftBlockEntity.isLocked()) { + if (tryRemove(context.getStack(), rift.getId())) { + entranceRiftBlockEntity.setLocked(false); + entranceRiftBlockEntity.markDirty(); + EntityUtils.chat(player, Text.translatable("rifts.unlocked")); + ServerPacketHandler.get((ServerPlayerEntity) player).sync(context.getStack(), context.getHand()); + return ActionResult.SUCCESS; + } else { + EntityUtils.chat(player, Text.translatable("rifts.cantUnlock")); + } + } else { + entranceRiftBlockEntity.setLocked(true); + add(context.getStack(), rift.getId()); + entranceRiftBlockEntity.markDirty(); + EntityUtils.chat(player, Text.translatable("rifts.locked")); + ServerPacketHandler.get((ServerPlayerEntity) player).sync(context.getStack(), context.getHand()); + return ActionResult.SUCCESS; + } + } + return super.useOnBlock(context); + } + + public static boolean tryRemove(ItemStack stack, UUID id) { + NbtIntArray arrayTag = new NbtIntArray(Uuids.toIntArray(id)); + return stack.getNbt().getList("Ids", NbtType.INT_ARRAY).remove(arrayTag); + } + + public static void add(ItemStack stack, UUID id) { + if (!has(stack, id)) { + stack.getOrCreateNbt().getList("Ids", NbtType.INT_ARRAY).add(new NbtIntArray(Uuids.toIntArray(id))); + } + } + + public static boolean has(ItemStack stack, UUID id) { + return stack.getOrCreateNbt().getList("Ids", NbtType.INT_ARRAY).contains(new NbtIntArray(Uuids.toIntArray(id))); + } + + public static boolean isEmpty(ItemStack stack) { + return stack.getOrCreateNbt().getList("Ids", NbtType.INT_ARRAY).isEmpty(); + } + + public static List getIds(ItemStack stack) { + return stack.getOrCreateNbt() + .getList("Ids", NbtType.INT_ARRAY) + .stream() + .map(NbtIntArray.class::cast) + .map(NbtIntArray::getIntArray) + .map(Uuids::toUuid) + .collect(Collectors.toList()); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/RiftRemoverItem.java b/common/src/main/java/org/dimdev/dimdoors/item/RiftRemoverItem.java new file mode 100644 index 00000000..4021396d --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/RiftRemoverItem.java @@ -0,0 +1,84 @@ +package org.dimdev.dimdoors.item; + +import java.util.List; +import java.util.Objects; + +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContext; +import net.minecraft.loot.context.LootContextParameters; +import net.minecraft.loot.context.LootContextTypes; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.ItemScatterer; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.dimdoors.block.entity.DetachedRiftBlockEntity; +import org.dimdev.dimdoors.block.entity.RiftBlockEntity; +import org.dimdev.dimdoors.client.ToolTipHelper; +import org.dimdev.dimdoors.sound.ModSoundEvents; + +public class RiftRemoverItem extends Item { + public static final String ID = "rift_remover"; + public static final Identifier REMOVED_RIFT_LOOT_TABLE = DimensionalDoors.id("removed_rift"); + + public RiftRemoverItem(Settings settings) { + super(settings); + } + + @Environment(EnvType.CLIENT) + @Override + public void appendTooltip(ItemStack itemStack, World world, List list, TooltipContext tooltipContext) { + ToolTipHelper.processTranslation(list, this.getTranslationKey() + ".info"); + } + + @Override + public TypedActionResult use(World world, PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + HitResult hit = player.raycast(RaycastHelper.REACH_DISTANCE, 0, false); + + if (world.isClient) { + if (!RaycastHelper.hitsDetachedRift(hit, world)) { + player.sendMessage(Text.translatable("tools.rift_miss"), true); + RiftBlockEntity.showRiftCoreUntil = System.currentTimeMillis() + DimensionalDoors.getConfig().getGraphicsConfig().highlightRiftCoreFor; + } + return new TypedActionResult<>(ActionResult.FAIL, stack); + } + + if (RaycastHelper.hitsDetachedRift(hit, world)) { + // casting to BlockHitResult is mostly safe since RaycastHelper#hitsDetachedRift already checks hit type + DetachedRiftBlockEntity rift = (DetachedRiftBlockEntity) world.getBlockEntity(((BlockHitResult) hit).getBlockPos()); + if (!Objects.requireNonNull(rift).closing) { + rift.setClosing(true); + world.playSound(null, player.getBlockPos(), ModSoundEvents.RIFT_CLOSE, SoundCategory.BLOCKS, 0.6f, 1); + stack.damage(10, player, a -> a.sendToolBreakStatus(hand)); + LootContext ctx = new LootContext.Builder((ServerWorld) world).random(world.random).parameter(LootContextParameters.ORIGIN, Vec3d.ofCenter(((BlockHitResult) hit).getBlockPos())).optionalParameter(LootContextParameters.THIS_ENTITY, player).build(LootContextTypes.GENERIC); + ((ServerWorld) world).getServer().getLootManager().getTable(REMOVED_RIFT_LOOT_TABLE).generateLoot(ctx).forEach(stack1 -> { + ItemScatterer.spawn(world, ((BlockHitResult) hit).getBlockPos().getX(), ((BlockHitResult) hit).getBlockPos().getY(), ((BlockHitResult) hit).getBlockPos().getZ(), stack1); + }); + + player.sendMessage(Text.translatable(this.getTranslationKey() + ".closing"), true); + return new TypedActionResult<>(ActionResult.SUCCESS, stack); + } else { + player.sendMessage(Text.translatable(this.getTranslationKey() + ".already_closing"), true); + } + } + return new TypedActionResult<>(ActionResult.FAIL, stack); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/RiftSignatureItem.java b/common/src/main/java/org/dimdev/dimdoors/item/RiftSignatureItem.java new file mode 100644 index 00000000..b0a46ba8 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/RiftSignatureItem.java @@ -0,0 +1,148 @@ +package org.dimdev.dimdoors.item; + +import java.util.List; + +import org.jetbrains.annotations.NotNull; + +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Formatting; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.dimdoors.api.util.Location; +import org.dimdev.dimdoors.api.util.RotatedLocation; +import org.dimdev.dimdoors.block.ModBlocks; +import org.dimdev.dimdoors.block.entity.DetachedRiftBlockEntity; +import org.dimdev.dimdoors.client.ToolTipHelper; +import org.dimdev.dimdoors.rift.targets.RiftReference; +import org.dimdev.dimdoors.sound.ModSoundEvents; +import org.dimdev.dimdoors.world.ModDimensions; + +public class RiftSignatureItem extends Item { + public static final String ID = "rift_signature"; + + public RiftSignatureItem(Settings settings) { + super(settings); + } + + @Override + public boolean hasGlint(ItemStack stack) { + return stack.getNbt() != null && stack.getNbt().contains("destination"); + } + + @Override + public ActionResult useOnBlock(@NotNull ItemUsageContext itemUsageContext) { + PlayerEntity player = itemUsageContext.getPlayer(); + World world = itemUsageContext.getWorld(); + BlockPos pos = itemUsageContext.getBlockPos(); + Hand hand = itemUsageContext.getHand(); + Direction side = itemUsageContext.getSide(); + + ItemPlacementContext placementContext = new ItemPlacementContext(itemUsageContext); + + ItemStack stack = player.getStackInHand(hand); + pos = world.getBlockState(pos).getBlock().canReplace(world.getBlockState(pos), placementContext) ? pos : pos.offset(side); + + // Fail if the player can't place a block there + if (!player.canPlaceOn(pos, side.getOpposite(), stack)) { + return ActionResult.FAIL; + } + + if (world.isClient) { + return ActionResult.SUCCESS; + } + + if(ModDimensions.isPrivatePocketDimension(world) && !DimensionalDoors.getConfig().getPocketsConfig().canUseRiftSignatureInPrivatePockets) { + player.sendMessage(Text.translatable("tools.signature_blocked").formatted(Formatting.BLACK), true); + return ActionResult.FAIL; + } + + RotatedLocation target = getSource(stack); + + if (target == null) { + // The link signature has not been used. Store its current target as the first location. + setSource(stack, new RotatedLocation(world.getRegistryKey(), pos, player.getYaw(), 0)); + player.sendMessage(Text.translatable(this.getTranslationKey() + ".stored"), true); + world.playSound(null, player.getBlockPos(), ModSoundEvents.RIFT_START, SoundCategory.BLOCKS, 0.6f, 1); + } else { + // Place a rift at the saved point + if (target.getBlockState().getBlock() != ModBlocks.DETACHED_RIFT) { + if (!target.getBlockState().getBlock().canMobSpawnInside()) { + player.sendMessage(Text.translatable("tools.target_became_block"), true); + clearSource(stack); // TODO: But is this fair? It's a rather hidden way of unbinding your signature! + return ActionResult.FAIL; + } + World sourceWorld = DimensionalDoors.getWorld(target.world); + sourceWorld.setBlockState(target.getBlockPos(), ModBlocks.DETACHED_RIFT.getDefaultState()); + DetachedRiftBlockEntity rift1 = (DetachedRiftBlockEntity) target.getBlockEntity(); + rift1.setDestination(RiftReference.tryMakeRelative(target, new Location((ServerWorld) world, pos))); + rift1.register(); + } + + // Place a rift at the target point + world.setBlockState(pos, ModBlocks.DETACHED_RIFT.getDefaultState()); + DetachedRiftBlockEntity rift2 = (DetachedRiftBlockEntity) world.getBlockEntity(pos); + rift2.setDestination(RiftReference.tryMakeRelative(new Location((ServerWorld) world, pos), target)); + rift2.register(); + + stack.damage(1, player, a -> { + }); // TODO: calculate damage based on position? + + clearSource(stack); + player.sendMessage(Text.translatable(this.getTranslationKey() + ".created"), true); + // null = send sound to the player too, we have to do this because this code is not run client-side + world.playSound(null, player.getBlockPos(), ModSoundEvents.RIFT_END, SoundCategory.BLOCKS, 0.6f, 1); + } + + return ActionResult.SUCCESS; + } + + public static void setSource(ItemStack itemStack, RotatedLocation destination) { + if (!itemStack.hasNbt()) itemStack.setNbt(new NbtCompound()); + itemStack.getNbt().put("destination", RotatedLocation.serialize(destination)); + } + + public static void clearSource(ItemStack itemStack) { + if (itemStack.hasNbt()) { + itemStack.getNbt().remove("destination"); + } + } + + public static RotatedLocation getSource(ItemStack itemStack) { + if (itemStack.hasNbt() && itemStack.getNbt().contains("destination")) { + return RotatedLocation.deserialize(itemStack.getNbt().getCompound("destination")); + } else { + return null; + } + } + + @Override + @Environment(EnvType.CLIENT) + public void appendTooltip(ItemStack itemStack, World world, List list, TooltipContext tooltipContext) { + RotatedLocation transform = getSource(itemStack); + if (transform != null) { + list.add(Text.translatable(this.getTranslationKey() + ".bound.info0", transform.getX(), transform.getY(), transform.getZ(), transform.getWorldId().getValue())); + list.add(Text.translatable(this.getTranslationKey() + ".bound.info1", transform.getWorldId().getValue())); + } else { + ToolTipHelper.processTranslation(list, this.getTranslationKey() + ".unbound.info"); + } + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/RiftStabilizerItem.java b/common/src/main/java/org/dimdev/dimdoors/item/RiftStabilizerItem.java new file mode 100644 index 00000000..4696a986 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/RiftStabilizerItem.java @@ -0,0 +1,71 @@ +package org.dimdev.dimdoors.item; + +import java.util.List; + +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.sound.SoundCategory; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.World; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.dimdoors.block.entity.DetachedRiftBlockEntity; +import org.dimdev.dimdoors.block.entity.RiftBlockEntity; +import org.dimdev.dimdoors.sound.ModSoundEvents; + +public class RiftStabilizerItem extends Item { + public RiftStabilizerItem(Settings settings) { + super(settings); + } + + @Override + public TypedActionResult use(World world, PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + HitResult hit = player.raycast(RaycastHelper.REACH_DISTANCE, 0, false); + + if (world.isClient) { + if (RaycastHelper.hitsDetachedRift(hit, world)) { + // TODO: not necessarily success, fix this and all other similar cases to make arm swing correct + return new TypedActionResult<>(ActionResult.SUCCESS, stack); + } else { + player.sendMessage(Text.translatable("tools.rift_miss"), true); + RiftBlockEntity.showRiftCoreUntil = System.currentTimeMillis() + DimensionalDoors.getConfig().getGraphicsConfig().highlightRiftCoreFor; + return new TypedActionResult<>(ActionResult.FAIL, stack); + } + } + + if (RaycastHelper.hitsDetachedRift(hit, world)) { + DetachedRiftBlockEntity rift = (DetachedRiftBlockEntity) world.getBlockEntity(new BlockPos(new Vec3i((int) hit.getPos().x, (int) hit.getPos().y, (int) hit.getPos().z))); + if (!rift.stabilized && !rift.closing) { + rift.setStabilized(true); + world.playSound(null, player.getBlockPos(), ModSoundEvents.RIFT_CLOSE, SoundCategory.BLOCKS, 0.6f, 1); // TODO: different sound + stack.damage(1, player, a -> { + }); + player.sendMessage(Text.translatable(this.getTranslationKey() + ".stabilized"), true); + return new TypedActionResult<>(ActionResult.SUCCESS, stack); + } else { + player.sendMessage(Text.translatable(this.getTranslationKey() + ".already_stabilized"), true); + } + } + return new TypedActionResult<>(ActionResult.FAIL, stack); + } + + @Environment(EnvType.CLIENT) + @Override + public void appendTooltip(ItemStack itemStack, World world, List list, TooltipContext tooltipContext) { + list.add(Text.translatable(this.getTranslationKey() + ".info")); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/StabilizedRiftSignatureItem.java b/common/src/main/java/org/dimdev/dimdoors/item/StabilizedRiftSignatureItem.java new file mode 100644 index 00000000..1b9a2a44 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/StabilizedRiftSignatureItem.java @@ -0,0 +1,116 @@ +package org.dimdev.dimdoors.item; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.dimdoors.api.util.Location; +import org.dimdev.dimdoors.api.util.RotatedLocation; +import org.dimdev.dimdoors.block.ModBlocks; +import org.dimdev.dimdoors.block.entity.DetachedRiftBlockEntity; +import org.dimdev.dimdoors.rift.targets.RiftReference; +import org.dimdev.dimdoors.sound.ModSoundEvents; + +public class StabilizedRiftSignatureItem extends Item { // TODO: common superclass with rift signature + public static final String ID = "stabilized_rift_signature"; + + public StabilizedRiftSignatureItem(Settings settings) { + super(settings); + } + + @Override + public boolean hasGlint(ItemStack stack) { + return stack.getNbt() != null && stack.getNbt().contains("destination"); + } + + @Override + public ActionResult useOnBlock(ItemUsageContext itemUsageContext) { + PlayerEntity player = itemUsageContext.getPlayer(); + World world = itemUsageContext.getWorld(); + BlockPos pos = itemUsageContext.getBlockPos(); + Hand hand = itemUsageContext.getHand(); + Direction side = itemUsageContext.getSide(); + + ItemPlacementContext itemPlacementContext = new ItemPlacementContext(itemUsageContext); + + ItemStack stack = player.getStackInHand(hand); + pos = world.getBlockState(pos).getBlock().canReplace(world.getBlockState(pos), new ItemPlacementContext(itemUsageContext)) ? pos : pos.offset(side); + // Fail if the player can't place a block there + if (!player.canPlaceOn(pos, side.getOpposite(), stack)) { + return ActionResult.FAIL; + } + + if (world.isClient) { + return ActionResult.SUCCESS; + } + + RotatedLocation target = getTarget(stack); + + if (target == null) { + // The link signature has not been used. Store its current target as the first location. + setSource(stack, new RotatedLocation(world.getRegistryKey(), pos, player.getYaw(), 0)); + player.sendMessage(Text.translatable(this.getTranslationKey() + ".stored"), true); + world.playSound(null, player.getBlockPos(), ModSoundEvents.RIFT_START, SoundCategory.BLOCKS, 0.6f, 1); + } else { + // Place a rift at the target point + if (target.getBlockState().getBlock() != ModBlocks.DETACHED_RIFT) { + if (!target.getBlockState().getBlock().canReplace(world.getBlockState(target.getBlockPos()), itemPlacementContext)) { + player.sendMessage(Text.translatable("tools.target_became_block"), true); + // Don't clear source, stabilized signatures always stay bound + return ActionResult.FAIL; + } + World targetWorld = DimensionalDoors.getWorld(target.world); + targetWorld.setBlockState(target.getBlockPos(), ModBlocks.DETACHED_RIFT.getDefaultState()); + DetachedRiftBlockEntity rift1 = (DetachedRiftBlockEntity) target.getBlockEntity(); + rift1.register(); + } + + // Place a rift at the source point + world.setBlockState(pos, ModBlocks.DETACHED_RIFT.getDefaultState()); + DetachedRiftBlockEntity rift2 = (DetachedRiftBlockEntity) world.getBlockEntity(pos); + rift2.setDestination(RiftReference.tryMakeRelative(new Location((ServerWorld) world, pos), target)); + rift2.register(); + + stack.damage(1, player, playerEntity -> { + }); + + player.sendMessage(Text.translatable(this.getTranslationKey() + ".created"), true); + world.playSound(null, player.getBlockPos(), ModSoundEvents.RIFT_END, SoundCategory.BLOCKS, 0.6f, 1); + } + + return ActionResult.SUCCESS; + } + + public static void setSource(ItemStack itemStack, RotatedLocation destination) { + if (!itemStack.hasNbt()) itemStack.setNbt(new NbtCompound()); + itemStack.getNbt().put("destination", RotatedLocation.serialize(destination)); + } + + public static void clearSource(ItemStack itemStack) { + if (itemStack.hasNbt()) { + itemStack.getNbt().remove("destination"); + } + } + + public static RotatedLocation getTarget(ItemStack itemStack) { + if (itemStack.hasNbt() && itemStack.getNbt().contains("destination")) { + return RotatedLocation.deserialize(itemStack.getNbt().getCompound("destination")); + } else { + return null; + } + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/component/CounterComponent.java b/common/src/main/java/org/dimdev/dimdoors/item/component/CounterComponent.java new file mode 100644 index 00000000..d38d2abc --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/component/CounterComponent.java @@ -0,0 +1,34 @@ +package org.dimdev.dimdoors.item.component; + +import dev.onyxstudios.cca.api.v3.item.ItemComponent; + +import net.minecraft.item.ItemStack; + +import org.dimdev.dimdoors.DimensionalDoorsComponents; + +public class CounterComponent extends ItemComponent { + + public CounterComponent(ItemStack stack) { + super(stack); + if (!this.hasTag("counter")) + this.putInt("counter", 0); + } + + public int increment() { + int counter = count(); + putInt("counter", counter + 1); + return counter; + } + + public int count() { + return getInt("counter"); + } + + public void reset() { + putInt("counter", 0); + } + + public static CounterComponent get(T provider) { + return DimensionalDoorsComponents.COUNTER_COMPONENT_KEY.get(provider); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalDoorItem.java b/common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalDoorItem.java new file mode 100644 index 00000000..af1a427b --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalDoorItem.java @@ -0,0 +1,134 @@ +package org.dimdev.dimdoors.item.door; + +import java.util.List; +import java.util.function.Consumer; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; +import net.minecraft.util.ActionResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.dimdoors.block.ModBlocks; +import org.dimdev.dimdoors.block.RiftProvider; +import org.dimdev.dimdoors.block.entity.DetachedRiftBlockEntity; +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; +import org.dimdev.dimdoors.block.entity.RiftBlockEntity; +import org.dimdev.dimdoors.client.ToolTipHelper; + +public class DimensionalDoorItem extends BlockItem { + private final Consumer setupFunction; + private boolean hasToolTip = false; + + public DimensionalDoorItem(Block block, Settings settings, Consumer setupFunction) { + this(block, settings, setupFunction, false); + } + + public DimensionalDoorItem(Block block, Settings settings, Consumer setupFunction, boolean hasToolTip) { + super(block, settings); + this.setupFunction = setupFunction; + this.hasToolTip = hasToolTip; + } + + @Environment(EnvType.CLIENT) + @Override + public void appendTooltip(ItemStack itemStack, World world, List list, TooltipContext tooltipContext) { + if(hasToolTip) { + ToolTipHelper.processTranslation(list, this.getTranslationKey() + ".info"); + } + } + + @Override + public ActionResult place(ItemPlacementContext context) { + BlockPos pos = context.getBlockPos(); + + if (!context.getWorld().getBlockState(pos).canReplace(context)) { + pos = pos.offset(context.getPlayerLookDirection()); + } + + boolean placedOnRift = context.getWorld().getBlockState(pos).getBlock() == ModBlocks.DETACHED_RIFT; + + if (!placedOnRift && !context.getPlayer().isSneaking() && isRiftNear(context.getWorld(), pos)) { + // Allowing on second right click would require cancelling client-side, which + // is impossible (see https://github.com/MinecraftForge/MinecraftForge/issues/3272) + // without sending custom packets. + + if (context.getWorld().isClient) { + context.getPlayer().sendMessage(Text.translatable("rifts.entrances.rift_too_close"), true); + RiftBlockEntity.showRiftCoreUntil = System.currentTimeMillis() + DimensionalDoors.getConfig().getGraphicsConfig().highlightRiftCoreFor; + } + + return ActionResult.FAIL; + } + + if (context.getWorld().isClient) { + return super.place(context); + } + + // Store the rift entity if there's a rift block there that may be broken + DetachedRiftBlockEntity rift = null; + if (placedOnRift) { + rift = (DetachedRiftBlockEntity) context.getWorld().getBlockEntity(pos); + rift.setUnregisterDisabled(true); + } + + ActionResult result = super.place(context); + if (result == ActionResult.SUCCESS || result == ActionResult.CONSUME) { + BlockState state = context.getWorld().getBlockState(pos); + if (rift == null) { + // Get the rift entity (not hard coded, works with any door size) + @SuppressWarnings("unchecked") // Guaranteed to be IRiftProvider because of constructor + EntranceRiftBlockEntity entranceRift = ((RiftProvider) state.getBlock()).getRift(context.getWorld(), pos, state); + + // Configure the rift to its default functionality + this.setupRift(entranceRift); + + // Register the rift in the registry + entranceRift.markDirty(); + entranceRift.register(); + } else { + // Copy from the old rift + EntranceRiftBlockEntity newRift = (EntranceRiftBlockEntity) context.getWorld().getBlockEntity(pos); + newRift.copyFrom(rift); + newRift.updateType(); + } + } else if (rift != null) { + rift.setUnregisterDisabled(false); + } + + return result; + } + + public static boolean isRiftNear(World world, BlockPos pos) { + for (int x = pos.getX() - 5; x < pos.getX() + 5; x++) { + for (int y = pos.getY() - 5; y < pos.getY() + 5; y++) { + for (int z = pos.getZ() - 5; z < pos.getZ() + 5; z++) { + BlockPos searchPos = new BlockPos(x, y, z); + if (world.getBlockState(searchPos).getBlock() == ModBlocks.DETACHED_RIFT) { + DetachedRiftBlockEntity rift = (DetachedRiftBlockEntity) world.getBlockEntity(searchPos); + if (Math.sqrt(pos.getSquaredDistance(searchPos)) < rift.size) { + return true; + } + } + } + } + } + + return false; + } + + public void setupRift(EntranceRiftBlockEntity entranceRift) { + this.setupFunction.accept(entranceRift); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalDoorItemRegistrar.java b/common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalDoorItemRegistrar.java new file mode 100644 index 00000000..9700e25f --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalDoorItemRegistrar.java @@ -0,0 +1,231 @@ +package org.dimdev.dimdoors.item.door; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.apache.commons.lang3.tuple.Triple; +import org.joml.Quaternionf; + +import net.minecraft.block.Block; +import net.minecraft.block.DoorBlock; +import net.minecraft.block.TrapdoorBlock; +import net.minecraft.client.resource.language.I18n; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.item.TallBlockItem; +import net.minecraft.registry.Registry; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Identifier; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry; +import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback; +import net.fabricmc.loader.api.FabricLoader; + +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.dimdoors.api.util.function.TriFunction; +import org.dimdev.dimdoors.block.door.DimensionalDoorBlock; +import org.dimdev.dimdoors.block.door.DimensionalTrapdoorBlock; +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; +import org.dimdev.dimdoors.client.UnderlaidChildItemRenderer; +import org.dimdev.dimdoors.item.ItemExtensions; +import org.dimdev.dimdoors.item.door.data.RiftDataList; +import org.dimdev.dimdoors.rift.targets.EscapeTarget; +import org.dimdev.dimdoors.rift.targets.PublicPocketTarget; + +public class DimensionalDoorItemRegistrar { + public static final String PREFIX = "item_ag_dim_"; + + private final Registry registry; + + private final Map blocksAlreadyNotifiedAbout = new HashMap<>(); + private final Map>> toBeMapped = new HashMap<>(); + + private final Map> placementFunctions = new HashMap<>(); + + public DimensionalDoorItemRegistrar(Registry registry) { + this.registry = registry; + + init(); + RegistryEntryAddedCallback.event(registry).register((rawId, id, object) -> handleEntry(id, object)); + } + + public boolean isRegistered(Item item) { + return placementFunctions.containsKey(item); + } + + public ActionResult place(Item item, ItemPlacementContext context) { + return placementFunctions.get(item).apply(context); + } + + private void init() { + new ArrayList<>(registry.getEntrySet()) + .forEach(entry -> handleEntry(entry.getKey().getValue(), entry.getValue())); + } + + public void handleEntry(Identifier identifier, Item original) { + if (DimensionalDoors.getConfig().getDoorsConfig().isAllowed(identifier)) { + if (original instanceof TallBlockItem) { + Block block = ((TallBlockItem) original).getBlock(); + handleEntry(identifier, original, block, AutoGenDimensionalDoorItem::new); + } else if (original instanceof BlockItem) { + Block originalBlock = ((BlockItem) original).getBlock(); + if (originalBlock instanceof DoorBlock) { + handleEntry(identifier, original, originalBlock, AutoGenDimensionalDoorItem::new); + } else { + handleEntry(identifier, original, originalBlock, AutoGenDimensionalTrapdoorItem::new); + } + } + } + } + + private void handleEntry(Identifier identifier, Item original, Block originalBlock, TriFunction constructor) { + + if (!(originalBlock instanceof DimensionalDoorBlock) + && !(originalBlock instanceof DimensionalTrapdoorBlock) + && (originalBlock instanceof DoorBlock || originalBlock instanceof TrapdoorBlock)) { + Item.Settings settings = ItemExtensions.getSettings(original)/*.group(DoorData.PARENT_ITEMS.contains(original) || DoorData.PARENT_BLOCKS.contains(originalBlock) ? null : ModItems.DIMENSIONAL_DOORS)*/; //TODO: Redo with the new way Itemgroups work. + + Function dimItemConstructor = (dimBlock) -> constructor.apply(dimBlock, settings, original); + + if (!blocksAlreadyNotifiedAbout.containsKey(originalBlock)) { + toBeMapped.put(originalBlock, new ImmutableTriple<>(identifier, original, dimItemConstructor)); + return; + } + + register(identifier, original, blocksAlreadyNotifiedAbout.get(originalBlock), dimItemConstructor); + } + } + + public void notifyBlockMapped(Block original, Block dimBlock) { + if (!toBeMapped.containsKey(original)) { + blocksAlreadyNotifiedAbout.put(original, dimBlock); + return; + } + Triple> triple = toBeMapped.get(original); + register(triple.getLeft(), triple.getMiddle(), dimBlock, triple.getRight()); + } + + private void register(Identifier identifier, Item original, Block block, Function dimItem) { + Identifier gennedId = DimensionalDoors.id(PREFIX + identifier.getNamespace() + "_" + identifier.getPath()); + BlockItem item = Registry.register(registry, gennedId, dimItem.apply(block)); + placementFunctions.put(original, item::place); + if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) { + registerItemRenderer(item); + } + } + + @Environment(EnvType.CLIENT) + private void registerItemRenderer(BlockItem dimItem) { + BuiltinItemRendererRegistry.INSTANCE.register(dimItem, Renderer.RENDERER); + } + + // extract renderer to inner interface so it can be removed in server environment via annotation + @Environment(EnvType.CLIENT) + private interface Renderer { + UnderlaidChildItemRenderer RENDERER = new UnderlaidChildItemRenderer(Items.ENDER_PEARL); + } + + private static class AutoGenDimensionalDoorItem extends DimensionalDoorItem implements ChildItem { + private final Item originalItem; + + public AutoGenDimensionalDoorItem(Block block, Settings settings, Item originalItem) { + super(block, settings, null); + this.originalItem = originalItem; + } + + @Override + public void setupRift(EntranceRiftBlockEntity entranceRift) { + RiftDataList data = DoorRiftDataLoader.getInstance().getRiftData(originalItem); + if (data != null) { + RiftDataList.OptRiftData riftData = data.getRiftData(entranceRift); + entranceRift.setDestination(riftData.getDestination()); + riftData.getProperties().ifPresent(entranceRift::setProperties); + } else { + entranceRift.setDestination(new PublicPocketTarget()); + } + } + + @Override + public Text getName(ItemStack stack) { + return Text.translatable("dimdoors.autogen_item_prefix", I18n.translate(originalItem.getTranslationKey())); + } + + @Override + public Text getName() { + return Text.translatable("dimdoors.autogen_item_prefix", I18n.translate(originalItem.getTranslationKey())); + } + + @Override + public Item getOriginalItem() { + return originalItem; + } + + @Environment(EnvType.CLIENT) + @Override + public void transform(MatrixStack matrices) { + matrices.scale(0.769f, 0.769f, 1); + matrices.translate(-0.06, 0.125, 0); + } + } + + private static class AutoGenDimensionalTrapdoorItem extends DimensionalTrapdoorItem implements ChildItem { + private final Item originalItem; + + public AutoGenDimensionalTrapdoorItem(Block block, Settings settings, Item originalItem) { + super(block, settings, null); + this.originalItem = originalItem; + } + + @Override + protected void setupRift(EntranceRiftBlockEntity entranceRift) { + RiftDataList data = DoorRiftDataLoader.getInstance().getRiftData(originalItem); + if (data != null) { + RiftDataList.OptRiftData riftData = data.getRiftData(entranceRift); + entranceRift.setDestination(riftData.getDestination()); + riftData.getProperties().ifPresent(entranceRift::setProperties); + } else { + entranceRift.setDestination(new EscapeTarget(true)); + } + } + + @Override + public Text getName(ItemStack stack) { + return Text.translatable("dimdoors.autogen_item_prefix", I18n.translate(originalItem.getTranslationKey())); + } + + @Override + public Text getName() { + return Text.translatable("dimdoors.autogen_item_prefix", I18n.translate(originalItem.getTranslationKey())); + } + + @Override + public Item getOriginalItem() { + return originalItem; + } + + @Environment(EnvType.CLIENT) + @Override + public void transform(MatrixStack matrices) { + matrices.scale(0.55f, 0.55f, 0.6f); + matrices.translate(0.05, -0.05, 0.41); + matrices.multiply(new Quaternionf().rotateXYZ(90, 0, 0)); + } + } + + public interface ChildItem { + Item getOriginalItem(); + + default void transform(MatrixStack matrices) { + } + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalTrapdoorItem.java b/common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalTrapdoorItem.java new file mode 100644 index 00000000..b845cb50 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/DimensionalTrapdoorItem.java @@ -0,0 +1,59 @@ +package org.dimdev.dimdoors.item.door; + +import java.util.function.Consumer; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.util.ActionResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.dimdev.dimdoors.block.RiftProvider; +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; + +public class DimensionalTrapdoorItem extends BlockItem { + private final Consumer setupFunction; + + public DimensionalTrapdoorItem(Block block, Settings settings, Consumer setupFunction) { + super(block, settings); + this.setupFunction = setupFunction; + } + + @Override + public ActionResult place(ItemPlacementContext context) { + World world = context.getWorld(); + BlockPos pos = context.getBlockPos(); + + if (world.isClient) { + return super.place(context); + } + + boolean replaceable = world.getBlockState(pos).canReplace(context); // Check this before calling super, since that changes the block + ActionResult result = super.place(context); + + if (result == ActionResult.SUCCESS) { + if (!replaceable) { + pos = pos.offset(context.getPlayerLookDirection()); + } + + BlockState state = world.getBlockState(pos); + // Get the rift entity (not hard coded, works with any door size) + EntranceRiftBlockEntity entranceRift = ((RiftProvider) state.getBlock()).getRift(world, pos, state); + + // Configure the rift to its default functionality + this.setupRift(entranceRift); + + // Register the rift in the registry + entranceRift.markDirty(); + entranceRift.register(); + } + + return result; + } + + protected void setupRift(EntranceRiftBlockEntity entranceRift) { + this.setupFunction.accept(entranceRift); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/DoorRiftDataLoader.java b/common/src/main/java/org/dimdev/dimdoors/item/door/DoorRiftDataLoader.java new file mode 100644 index 00000000..8e97d1c4 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/DoorRiftDataLoader.java @@ -0,0 +1,68 @@ +package org.dimdev.dimdoors.item.door; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import net.minecraft.item.Item; +import net.minecraft.registry.Registries; +import net.minecraft.resource.Resource; +import net.minecraft.resource.ResourceManager; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; + +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.dimdoors.item.door.data.RiftDataList; + +// TODO: make it async? +public final class DoorRiftDataLoader implements SimpleSynchronousResourceReloadListener { + private static final DoorRiftDataLoader INSTANCE = new DoorRiftDataLoader(); + private static final Logger LOGGER = LogManager.getLogger("DoorRiftDataLoader"); + private static final Gson GSON = new GsonBuilder().create(); + private final Map itemRiftData = new HashMap<>(); + + public static DoorRiftDataLoader getInstance() { + return INSTANCE; + } + + private DoorRiftDataLoader() { + } + + public RiftDataList getRiftData(Item item) { + return itemRiftData.get(item); + } + + @Override + public Identifier getFabricId() { + return DimensionalDoors.id("door_rift_data"); + } + + @Override + public void reload(ResourceManager manager) { + itemRiftData.clear(); + Map resources = manager.findResources("door/data", id -> id.getPath().endsWith(".json")); + resources.forEach((id, resource) -> { + String name = id.getPath().substring(id.getPath().lastIndexOf('/') + 1, id.getPath().lastIndexOf('.')); + Identifier itemId = new Identifier(id.getNamespace(), name); + if (!Registries.ITEM.containsId(itemId)) { + LOGGER.error("Could not find item " + itemId + " for door data " + id); + return; + } + Item item = Registries.ITEM.get(itemId); + try { + JsonArray json = GSON.fromJson(resource.getReader(), JsonArray.class); + RiftDataList dataList = RiftDataList.fromJson(json); + itemRiftData.put(item, dataList); + } catch (IOException e) { + LOGGER.error("Could not read door data " + id, e); + } + }); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/data/RiftDataList.java b/common/src/main/java/org/dimdev/dimdoors/item/door/data/RiftDataList.java new file mode 100644 index 00000000..fa443b3a --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/data/RiftDataList.java @@ -0,0 +1,88 @@ +package org.dimdev.dimdoors.item.door.data; + +import java.util.LinkedList; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.mojang.serialization.JsonOps; + +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtOps; +import net.minecraft.util.Pair; + +import org.dimdev.dimdoors.item.door.data.condition.Condition; +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; +import org.dimdev.dimdoors.rift.registry.LinkProperties; +import org.dimdev.dimdoors.rift.targets.VirtualTarget; + +public class RiftDataList { + private final LinkedList> riftDataConditions; + + public static RiftDataList fromJson(JsonArray jsonArray) { + LinkedList> riftDataConditions = new LinkedList<>(); + for (JsonElement json : jsonArray) { + JsonObject jsonObject = json.getAsJsonObject(); + //OptRiftData riftData = OptRiftData.fromJson(jsonObject.getAsJsonObject("data")); + JsonObject unbakedRiftData = jsonObject.getAsJsonObject("data"); + Condition condition = Condition.fromJson(jsonObject.getAsJsonObject("condition")); + riftDataConditions.add(new Pair<>(unbakedRiftData, condition)); + } + return new RiftDataList(riftDataConditions); + } + + public RiftDataList(LinkedList> riftDataConditions) { + this.riftDataConditions = riftDataConditions.stream().map(pair -> new Pair<>(OptRiftData.fromJson(pair.getLeft()), pair.getRight())).collect(Collectors.toCollection(LinkedList::new)); + } + + public OptRiftData getRiftData(EntranceRiftBlockEntity rift) { + return riftDataConditions.stream().filter(pair -> pair.getRight().matches(rift)).findFirst().orElseThrow(() -> new RuntimeException("Could not find any matching rift data")).getLeft(); + } + + public JsonArray toJson() { + JsonArray jsonArray = new JsonArray(); + for (Map.Entry entry : this.riftDataConditions.stream().collect(Collectors.toMap(Pair::getLeft, Pair::getRight)).entrySet()) { + JsonObject unbakedRiftData = entry.getKey().toJson(new JsonObject()); + Condition condition = entry.getValue(); + JsonObject jsonInner = new JsonObject(); + jsonInner.add("data", unbakedRiftData); + jsonInner.add("condition", condition.toJson(new JsonObject())); + jsonArray.add(jsonInner); + } + return jsonArray; + } + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + public static class OptRiftData { + private final VirtualTarget destination; + private final Optional linkProperties; + + public static OptRiftData fromJson(JsonObject json) { + VirtualTarget destination = Optional.of(json.get("destination")).map(JsonElement::getAsJsonObject).map(j -> JsonOps.INSTANCE.convertTo(NbtOps.INSTANCE, j)).map(NbtCompound.class::cast).map(VirtualTarget::fromNbt).get(); + Optional linkProperties = Optional.ofNullable(json.get("properties")).map(JsonElement::getAsJsonObject).map(j -> JsonOps.INSTANCE.convertTo(NbtOps.INSTANCE, j)).map(NbtCompound.class::cast).map(LinkProperties::fromNbt); + return new OptRiftData(destination, linkProperties); + } + + public OptRiftData(VirtualTarget destination, Optional linkProperties) { + this.destination = destination; + this.linkProperties = linkProperties; + } + + public JsonObject toJson(JsonObject json) { + Optional.of(this.destination).ifPresent(s -> json.add("destination", NbtOps.INSTANCE.convertTo(JsonOps.INSTANCE, VirtualTarget.toNbt(s)))); + this.linkProperties.ifPresent(s -> json.add("properties", NbtOps.INSTANCE.convertTo(JsonOps.INSTANCE, LinkProperties.toNbt(s)))); + return json; + } + + public Optional getProperties() { + return linkProperties; + } + + public VirtualTarget getDestination() { + return destination; + } + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AllCondition.java b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AllCondition.java new file mode 100644 index 00000000..395c3ce3 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AllCondition.java @@ -0,0 +1,32 @@ +package org.dimdev.dimdoors.item.door.data.condition; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; + +public class AllCondition extends MultipleCondition { + public AllCondition(List conditions) { + super(conditions); + } + + public static AllCondition fromJson(JsonObject json) { + JsonArray conditions = json.getAsJsonArray("conditions"); + return new AllCondition(StreamSupport.stream(conditions.spliterator(), false).map(JsonElement::getAsJsonObject).map(Condition::fromJson).collect(Collectors.toList())); + } + + @Override + public ConditionType getType() { + return ConditionType.ALL; + } + + @Override + public boolean matches(EntranceRiftBlockEntity rift) { + return this.conditions.stream().allMatch(c -> c.matches(rift)); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AlwaysTrueCondition.java b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AlwaysTrueCondition.java new file mode 100644 index 00000000..c4ace692 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AlwaysTrueCondition.java @@ -0,0 +1,23 @@ +package org.dimdev.dimdoors.item.door.data.condition; + +import com.google.gson.JsonObject; + +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; + +public enum AlwaysTrueCondition implements Condition { + INSTANCE; + + @Override + public boolean matches(EntranceRiftBlockEntity rift) { + return true; + } + + @Override + public void toJsonInner(JsonObject json) { + } + + @Override + public ConditionType getType() { + return ConditionType.ALWAYS_TRUE; + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AnyCondition.java b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AnyCondition.java new file mode 100644 index 00000000..b7364ac4 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/AnyCondition.java @@ -0,0 +1,32 @@ +package org.dimdev.dimdoors.item.door.data.condition; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; + +public class AnyCondition extends MultipleCondition { + public AnyCondition(List conditions) { + super(conditions); + } + + public static AnyCondition fromJson(JsonObject json) { + JsonArray conditions = json.getAsJsonArray("conditions"); + return new AnyCondition(StreamSupport.stream(conditions.spliterator(), false).map(JsonElement::getAsJsonObject).map(Condition::fromJson).collect(Collectors.toList())); + } + + @Override + public ConditionType getType() { + return ConditionType.ANY; + } + + @Override + public boolean matches(EntranceRiftBlockEntity rift) { + return this.conditions.stream().anyMatch(c -> c.matches(rift)); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/Condition.java b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/Condition.java new file mode 100644 index 00000000..50fba059 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/Condition.java @@ -0,0 +1,60 @@ +package org.dimdev.dimdoors.item.door.data.condition; + +import java.util.Objects; +import java.util.function.Function; + +import com.google.gson.JsonObject; +import com.mojang.serialization.Lifecycle; + +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.SimpleRegistry; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; + +import org.dimdev.dimdoors.DimensionalDoors; +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; + +public interface Condition { + Registry> REGISTRY = FabricRegistryBuilder., SimpleRegistry>>from(new SimpleRegistry<>(RegistryKey.ofRegistry(DimensionalDoors.id("rift_data_condition")), Lifecycle.stable(), false)).buildAndRegister(); + + boolean matches(EntranceRiftBlockEntity rift); + + default JsonObject toJson(JsonObject json) { + json.addProperty("type", getType().getId()); + this.toJsonInner(json); + return json; + } + + void toJsonInner(JsonObject json); + + ConditionType getType(); + + static Condition fromJson(JsonObject json) { + Identifier type = new Identifier(json.getAsJsonPrimitive("type").getAsString()); + return Objects.requireNonNull(REGISTRY.get(type)).fromJson(json); + } + + interface ConditionType { + ConditionType ALWAYS_TRUE = register("always_true", j -> AlwaysTrueCondition.INSTANCE); + ConditionType ALL = register("all", AllCondition::fromJson); + ConditionType ANY = register("any", AnyCondition::fromJson); + ConditionType INVERSE = register("inverse", InverseCondition::fromJson); + ConditionType WORLD_MATCH = register("world_match", WorldMatchCondition::fromJson); + + T fromJson(JsonObject json); + + default String getId() { + return String.valueOf(REGISTRY.getId(this)); + } + + static void register() { + DimensionalDoors.apiSubscribers.forEach(d -> d.registerConditionTypes(REGISTRY)); + } + + static ConditionType register(String name, Function fromJson) { + return Registry.register(REGISTRY, DimensionalDoors.id(name), json -> fromJson.apply(json)); + } + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/InverseCondition.java b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/InverseCondition.java new file mode 100644 index 00000000..4e9d26cb --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/InverseCondition.java @@ -0,0 +1,27 @@ +package org.dimdev.dimdoors.item.door.data.condition; + +import com.google.gson.JsonObject; + +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; + +public record InverseCondition(Condition condition) implements Condition { + + @Override + public void toJsonInner(JsonObject json) { + json.add("condition", condition.toJson(new JsonObject())); + } + + @Override + public ConditionType getType() { + return ConditionType.INVERSE; + } + + public static InverseCondition fromJson(JsonObject json) { + return new InverseCondition(Condition.fromJson(json.getAsJsonObject("condition"))); + } + + @Override + public boolean matches(EntranceRiftBlockEntity rift) { + return !this.condition.matches(rift); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/MultipleCondition.java b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/MultipleCondition.java new file mode 100644 index 00000000..ca6139f4 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/MultipleCondition.java @@ -0,0 +1,21 @@ +package org.dimdev.dimdoors.item.door.data.condition; + +import java.util.List; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +public abstract class MultipleCondition implements Condition { + protected final List conditions; + + protected MultipleCondition(List conditions) { + this.conditions = conditions; + } + + @Override + public void toJsonInner(JsonObject json) { + JsonArray conditionsJson = new JsonArray(); + conditions.forEach(c -> conditionsJson.add(c.toJson( new JsonObject()))); + json.add("conditions", conditionsJson); + } +} diff --git a/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/WorldMatchCondition.java b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/WorldMatchCondition.java new file mode 100644 index 00000000..688fff70 --- /dev/null +++ b/common/src/main/java/org/dimdev/dimdoors/item/door/data/condition/WorldMatchCondition.java @@ -0,0 +1,33 @@ +package org.dimdev.dimdoors.item.door.data.condition; + +import com.google.gson.JsonObject; + +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.Identifier; +import net.minecraft.world.World; + +import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; + +public record WorldMatchCondition(RegistryKey world) implements Condition { + public static WorldMatchCondition fromJson(JsonObject json) { + RegistryKey key = RegistryKey.of(RegistryKeys.WORLD, new Identifier(json.getAsJsonPrimitive("world").getAsString())); + return new WorldMatchCondition(key); + } + + @Override + public boolean matches(EntranceRiftBlockEntity rift) { + //noinspection ConstantConditions + return rift.getWorld().getRegistryKey() == this.world; + } + + @Override + public void toJsonInner(JsonObject json) { + json.addProperty("world", world.getValue().toString()); + } + + @Override + public ConditionType getType() { + return ConditionType.WORLD_MATCH; + } +}