fix suvival dupe, fix teleportation issue

This commit is contained in:
candle 2025-08-01 18:54:42 -04:00
parent 54c9024615
commit 881ba1a9a2
3 changed files with 41 additions and 44 deletions

View File

@ -46,12 +46,9 @@ import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.Containers;
import net.minecraft.world.item.DyeColor;
import net.minecraft.network.protocol.game.ClientboundStopSoundPacket;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -66,6 +63,11 @@ public class SuitcaseBlock extends BaseEntityBlock {
private final static VoxelShape SHAPE_S = Block.box(0, 0, 2, 16, 4, 14);
private final static VoxelShape SHAPE_E = Block.box(2, 0, 0, 14, 4, 16);
private final static VoxelShape SHAPE_W = Block.box(2, 0, 0, 14, 4, 16);
private static final int PORTAL_SEARCH_RADIUS = 50;
private static final int PORTAL_SEARCH_Y_MIN = -20;
private static final int PORTAL_SEARCH_Y_MAX = 40;
private static final double PORTAL_TELEPORT_Y_OFFSET = -3.0;
public SuitcaseBlock(BlockBehaviour.Properties properties) {
super(properties);
@ -119,42 +121,6 @@ public class SuitcaseBlock extends BaseEntityBlock {
@Override
public void onRemove(BlockState state, @NotNull Level world, @NotNull BlockPos pos, BlockState newState, boolean isMoving) {
if (!state.is(newState.getBlock())) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof SuitcaseBlockEntity suitcase) {
ItemStack itemStack = new ItemStack(this);
String boundKeystone = suitcase.getBoundKeystoneName();
if (boundKeystone != null) {
CompoundTag beNbt = new CompoundTag();
suitcase.saveAdditional(beNbt);
if (!beNbt.isEmpty()) {
BlockItem.setBlockEntityData(itemStack, ModBlockEntities.SUITCASE_BLOCK_ENTITY.get(), beNbt);
}
CompoundTag display = itemStack.getOrCreateTagElement("display");
ListTag lore = new ListTag();
String displayName = boundKeystone.replace("_", " ");
Component boundText;
if (suitcase.isLocked()) {
boundText = Component.literal("Bound to: §k" + displayName)
.withStyle(ChatFormatting.GRAY);
} else {
boundText = Component.literal("Bound to: " + displayName)
.withStyle(ChatFormatting.GRAY);
}
Component lockText = Component.literal(suitcase.isLocked() ? "§cLocked" : "§aUnlocked")
.withStyle(ChatFormatting.GRAY);
if (!suitcase.getEnteredPlayers().isEmpty()) {
Component warningText = Component.literal("§c⚠ Contains " + suitcase.getEnteredPlayers().size() + " Traveler's!")
.withStyle(ChatFormatting.RED);
lore.add(StringTag.valueOf(Component.Serializer.toJson(warningText)));
}
lore.add(StringTag.valueOf(Component.Serializer.toJson(boundText)));
lore.add(StringTag.valueOf(Component.Serializer.toJson(lockText)));
display.put("Lore", lore);
}
Containers.dropItemStack(world, pos.getX(), pos.getY(), pos.getZ(), itemStack);
}
super.onRemove(state, world, pos, newState, isMoving);
}
}
@ -263,8 +229,16 @@ public class SuitcaseBlock extends BaseEntityBlock {
player.fallDistance = 0f;
PlayerEntryData ped = PlayerEntryData.get(targetWorld);
// Find the portal block position in the pocket dimension
BlockPos portalPos = findPortalBlockInDimension(targetWorld);
if (portalPos != null) {
// Update the entry position to match the portal block location
Vec3 portalLocation = new Vec3(portalPos.getX() + 0.5, portalPos.getY() + PORTAL_TELEPORT_Y_OFFSET, portalPos.getZ() + 0.5);
ped.setEntry(portalLocation, 0f, 0f);
}
Vec3 dest = ped.getEntryPos();
float yaw = ped.getEntryYaw();
float pitch = player.getXRot();
@ -283,6 +257,24 @@ public class SuitcaseBlock extends BaseEntityBlock {
}
}
private BlockPos findPortalBlockInDimension(ServerLevel targetWorld) {
// Search around the structure placement area (0, 64, 0) for portal blocks
BlockPos structureCenter = new BlockPos(0, 64, 0);
for (int x = -PORTAL_SEARCH_RADIUS; x <= PORTAL_SEARCH_RADIUS; x++) {
for (int y = PORTAL_SEARCH_Y_MIN; y <= PORTAL_SEARCH_Y_MAX; y++) {
for (int z = -PORTAL_SEARCH_RADIUS; z <= PORTAL_SEARCH_RADIUS; z++) {
BlockPos checkPos = structureCenter.offset(x, y, z);
if (targetWorld.getBlockState(checkPos).getBlock() instanceof PocketPortalBlock) {
return checkPos;
}
}
}
}
return null;
}
@Override
public @NotNull VoxelShape getShape(BlockState state, @NotNull BlockGetter world, @NotNull BlockPos pos, @NotNull CollisionContext context) {
return switch (state.getValue(FACING)) {

View File

@ -111,9 +111,9 @@ public class SuitcaseBlockEntity extends BlockEntity {
if (data.uuid.equals(playerUuid)) {
EnteredPlayerData exitData = new EnteredPlayerData(
data.uuid,
this.worldPosition.getX() + 0.5, this.worldPosition.getY() + 1.0, this.worldPosition.getZ() + 0.5,
data.x, data.y, data.z,
data.pitch, data.yaw,
this.worldPosition
data.suitcasePos != null ? data.suitcasePos : this.worldPosition
);
enteredPlayers.remove(i);
setChangedAndNotify();

View File

@ -21,9 +21,14 @@ public class ServerChunkManagerMixin {
private void onRunDistanceManagerUpdates(CallbackInfoReturnable<Boolean> cir) {
// Only apply special chunk processing logic to RuntimeWorld instances (fantasy dimensions)
if (this.level instanceof RuntimeWorld) {
if (!((FantasyWorldAccess) this.level).fantasy$shouldTick()) {
cir.setReturnValue(false);
FantasyWorldAccess worldAccess = (FantasyWorldAccess) this.level;
// Always allow distance manager updates if chunks are loaded (prevents breaking entity initialization)
// Only block when world is truly empty AND configured not to tick when empty
if (this.level.getChunkSource().getLoadedChunksCount() > 0 || worldAccess.fantasy$shouldTick()) {
// Allow distance manager to run - this is critical for entity systems
return;
}
cir.setReturnValue(false);
}
// Regular worlds (overworld, nether, end) process chunks normally without interference
}