diff --git a/patches/minecraft/net/minecraft/entity/player/PlayerEntity.java.patch b/patches/minecraft/net/minecraft/entity/player/PlayerEntity.java.patch index 754b453f9b..d9ba318ef7 100644 --- a/patches/minecraft/net/minecraft/entity/player/PlayerEntity.java.patch +++ b/patches/minecraft/net/minecraft/entity/player/PlayerEntity.java.patch @@ -266,17 +266,15 @@ super.func_213366_dy(); if (this.field_70170_p instanceof ServerWorld && p_225652_2_) { ((ServerWorld)this.field_70170_p).func_72854_c(); -@@ -1242,8 +_,8 @@ - } - - return optional; -- } else if (block instanceof BedBlock && BedBlock.func_235330_a_(p_242374_0_)) { -- return BedBlock.func_242652_a(EntityType.field_200729_aH, p_242374_0_, p_242374_1_, p_242374_2_); -+ } else if (blockstate.isBed(p_242374_0_, p_242374_1_, null) && BedBlock.func_235330_a_(p_242374_0_)) { -+ return blockstate.getBedSpawnPosition(EntityType.field_200729_aH, p_242374_0_, p_242374_1_, p_242374_2_, null); +@@ -1245,7 +_,7 @@ + } else if (block instanceof BedBlock && BedBlock.func_235330_a_(p_242374_0_)) { + return BedBlock.func_242652_a(EntityType.field_200729_aH, p_242374_0_, p_242374_1_, p_242374_2_); } else if (!p_242374_3_) { - return Optional.empty(); +- return Optional.empty(); ++ return blockstate.getRespawnPosition(EntityType.field_200729_aH, p_242374_0_, p_242374_1_, p_242374_2_, null); } else { + boolean flag = block.func_181623_g(); + boolean flag1 = p_242374_0_.func_180495_p(p_242374_1_.func_177984_a()).func_177230_c().func_181623_g(); @@ -1425,6 +_,7 @@ public boolean func_225503_b_(float p_225503_1_, float p_225503_2_) { diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java b/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java index c7c27ec307..58091b9f62 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java @@ -230,6 +230,26 @@ public interface IForgeBlock return this.getBlock() instanceof BedBlock; //TODO: Forge: Keep isBed function? } + /** + * Returns the position that the entity is moved to upon + * respawning at this block. + * + * @param state The current state + * @param world The current world + * @param pos Block position in world + * @param orientation The angle the entity had when setting the respawn point + * @param entity The entity respawning, often null + * @return The spawn position or the empty optional if respawning here is not possible + */ + default Optional getRespawnPosition(BlockState state, EntityType type, IWorldReader world, BlockPos pos, float orientation, @Nullable LivingEntity entity) + { + if (isBed(state, world, pos, entity) && world instanceof World && BedBlock.canSetSpawn((World) world)) + { + return getBedSpawnPosition(type, state, world, pos, orientation, entity); + } + return Optional.empty(); + } + /** * Determines if a specified mob type can spawn on this block, returning false will * prevent any mob from spawning on the block. @@ -255,7 +275,9 @@ public interface IForgeBlock * @param orientation The direction the entity is facing while getting into bed. * @param sleeper The sleeper or camera entity, null in some cases. * @return The spawn position + * @deprecated use {@link #getRespawnPosition(BlockState, EntityType, IWorldReader, BlockPos, float, LivingEntity)} */ + @Deprecated default Optional getBedSpawnPosition(EntityType entityType, BlockState state, IWorldReader world, BlockPos pos, float orientation, @Nullable LivingEntity sleeper) { if (world instanceof World) diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java b/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java index b8e5262ef7..6698f362a7 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java @@ -194,12 +194,29 @@ public interface IForgeBlockState * @param orientation The direction the entity is facing while getting into bed. * @param sleeper The sleeper or camera entity, null in some cases. * @return The spawn position + * @deprecated use {@link #getRespawnPosition(EntityType, IWorldReader, BlockPos, float, LivingEntity)} */ + @Deprecated default Optional getBedSpawnPosition(EntityType type, IWorldReader world, BlockPos pos, float orientation, @Nullable LivingEntity sleeper) { return getBlockState().getBlock().getBedSpawnPosition(type, getBlockState(), world, pos, orientation, sleeper); } + /** + * Returns the position that the entity is moved to upon + * respawning at this block. + * + * @param world The current world + * @param pos Block position in world + * @param orientation The angle the entity had when setting the respawn point + * @param entity The entity respawning, often null + * @return The spawn position or the empty optional if respawning here is not possible + */ + default Optional getRespawnPosition(EntityType type, IWorldReader world, BlockPos pos, float orientation, @Nullable LivingEntity entity) + { + return getBlockState().getBlock().getRespawnPosition(getBlockState(), type, world, pos, orientation, entity); + } + /** * Called when a user either starts or stops sleeping in the bed. * diff --git a/src/test/java/net/minecraftforge/debug/block/CustomRespawnTest.java b/src/test/java/net/minecraftforge/debug/block/CustomRespawnTest.java new file mode 100644 index 0000000000..317d210b77 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/block/CustomRespawnTest.java @@ -0,0 +1,97 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2021. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.debug.block; + +import java.util.Optional; + +import javax.annotation.Nullable; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.RespawnAnchorBlock; +import net.minecraft.block.material.Material; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.IWorldReader; +import net.minecraft.world.World; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +@Mod(CustomRespawnTest.MODID) +public class CustomRespawnTest +{ + public static final boolean ENABLE = true; + public static final String MODID = "custom_respawn_test"; + + private static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID); + public static final RegistryObject TEST_RESPAWN_BLOCK = BLOCKS.register("test_respawn_block", () -> new CustomRespawnBlock(Block.Properties.of(Material.WOOD))); + + private static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID); + public static final RegistryObject TEST_RESPAWN_BLOCK_ITEM = ITEMS.register("test_respawn_block", () -> new BlockItem(TEST_RESPAWN_BLOCK.get(), (new Item.Properties()))); + + public CustomRespawnTest() + { + if (ENABLE) + { + final IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus(); + BLOCKS.register(eventBus); + ITEMS.register(eventBus); + } + } + + public static class CustomRespawnBlock extends Block + { + + public CustomRespawnBlock(Properties propertiesIn) + { + super(propertiesIn); + } + + @Override + public ActionResultType use(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity p_225533_4_, Hand p_225533_5_, BlockRayTraceResult p_225533_6_) + { + if (!world.isClientSide && p_225533_4_ instanceof ServerPlayerEntity) + { + ((ServerPlayerEntity)p_225533_4_).setRespawnPosition(world.dimension(), pos, 0, false, true); + } + return ActionResultType.sidedSuccess(world.isClientSide); + } + + @Override + public Optional getRespawnPosition(BlockState state, EntityType type, IWorldReader world, BlockPos pos, float orientation, @Nullable LivingEntity entity) + { + return RespawnAnchorBlock.findStandUpPosition(type, world, pos); + } + } + +} diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/META-INF/mods.toml index d74d351a5b..f615f14230 100644 --- a/src/test/resources/META-INF/mods.toml +++ b/src/test/resources/META-INF/mods.toml @@ -124,9 +124,12 @@ license="LGPL v2.1" modId="entity_teleport_event_test" [[mods]] modId="text_linear_filtering_test" +[[mods]] + modId="custom_respawn_test" [[mods]] modId="custom_tas_test" [[mods]] modId="dimension_settings_test" [[mods]] modId="player_attack_knockback_test" +