Skip to content

Commit

Permalink
Adjust the bed command so that teleportation follows the respawn stra…
Browse files Browse the repository at this point in the history
…tegy. (#286)
  • Loading branch information
LittleCircleOO authored Jun 16, 2024
1 parent bbf216a commit 3a74a75
Showing 1 changed file with 45 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,66 @@
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;

import net.minecraft.block.BedBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.RespawnAnchorBlock;
import net.minecraft.entity.EntityType;
import net.minecraft.command.CommandException;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;

import java.util.Objects;
import java.util.Optional;

public class BedCommand implements Command<ServerCommandSource> {
@Override
public int run(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
var player = context.getSource().getPlayerOrThrow();
var spawnPos = player.getSpawnPointPosition();
var spawnDim = player.getSpawnPointDimension();
var spawnAngle = player.getSpawnAngle();

if (spawnPos == null) {
throw new CommandException(ECText.access(player).getText("cmd.bed.error.none_set", TextFormatType.Error));
}

var world = Objects.requireNonNull(player.getServer()).getWorld(spawnDim);

if (world == null) {
throw new IllegalStateException(String.format(
"could not resolve the ServerWorld corresponding to the player's spawn dimension. dimension: '%s'",
spawnDim.getValue())
);
}

//Safe Position Calculation, based on the game respawn position calculation logic,
//which was basically rewritten because the game code caused the state of the RespawnAnchorBlock to be refreshed.
Vec3d safeSpawnPos;
BlockState blockState = world.getBlockState(spawnPos);
Block block = blockState.getBlock();
if (block instanceof RespawnAnchorBlock
&& (Integer)blockState.get(RespawnAnchorBlock.CHARGES) > 0 && RespawnAnchorBlock.isNether(world)) {
Optional<Vec3d> optional = RespawnAnchorBlock.findRespawnPosition(EntityType.PLAYER, world, spawnPos);
safeSpawnPos = optional.orElseGet(() -> new Vec3d((double)spawnPos.getX() + 0.5, (double)spawnPos.getY() + 1, (double)spawnPos.getZ() + 0.5));
} else if (block instanceof BedBlock && BedBlock.isBedWorking(world)) {
Optional<Vec3d> optional = BedBlock.findWakeUpPosition(EntityType.PLAYER, world, spawnPos, (Direction)blockState.get(BedBlock.FACING), spawnAngle);
safeSpawnPos = optional.orElseGet(() -> new Vec3d((double)spawnPos.getX() + 0.5, (double)spawnPos.getY() + 0.5625, (double)spawnPos.getZ() + 0.5));
} else {
boolean bl = block.canMobSpawnInside(blockState);
BlockState blockState2 = world.getBlockState(spawnPos.up());
boolean bl2 = blockState2.getBlock().canMobSpawnInside(blockState2);
if(bl && bl2) {
safeSpawnPos = new Vec3d((double)spawnPos.getX() + 0.5, (double)spawnPos.getY() + 0.1, (double)spawnPos.getZ() + 0.5);
}else{
safeSpawnPos = Vec3d.ofBottomCenter(spawnPos);
}
}

PlayerTeleporter.requestTeleport(
player,
new MinecraftLocation(spawnDim, spawnPos.getX(), spawnPos.getY(), spawnPos.getZ()),
new MinecraftLocation(spawnDim, safeSpawnPos.getX(), safeSpawnPos.getY(), safeSpawnPos.getZ()),
ECText.access(player).getText("cmd.bed.bed_destination_name", TextFormatType.Accent));

return 0;
Expand Down

0 comments on commit 3a74a75

Please sign in to comment.