seat riding gate fix

This commit is contained in:
Darto KLoning
2026-10-03 12:00:13 +07:00
parent 258354b7d9
commit 57ee17b56c
9 changed files with 40 additions and 37 deletions
+14
View File
@@ -1,3 +1,10 @@
## 4.0.12 — Minecraft 26.2 riding gate fix
- Diagnostic 4.0.11 isolated the failure to `player.startRiding(seat)`: the Seat spawned successfully but mounting returned false.
- Verified against Minecraft 26.2 `Entity.startRiding`: server-side riding is rejected when the vehicle entity type reports `canSerialize() == false`.
- Handcrafted registered `Seat` with `EntityType.Builder.noSave()`, which makes the Seat non-serializable and therefore impossible to ride on 26.2.
- Removed `.noSave()` from the Seat entity registration. The Seat still self-discards when it has no passenger or its furniture block is gone, so it remains ephemeral during normal gameplay.
- Kept the 4.0.11 diagnostic logging for this test build so the result can be confirmed from the next log.
## 4.0.9 — Seat synchronization fix
- Compared the Fabric 26.2 port directly against the original 1.21.x seating implementation.
- The current debug log proves server-side mounting already succeeds: the client reports `Received passengers for unknown entity`. This means the failure is no longer the chair/bench/couch interaction callback; the invisible `Seat` vehicle is not known client-side when the passenger update arrives.
@@ -112,3 +119,10 @@ The remaining major migration area is the 26.2 extract/submit rendering pipeline
## 4.0.4 Fabric 26.2 build fix
- Removed the legacy `Seat.makeBoundingBox()` override. In Minecraft 26.2, `Entity.makeBoundingBox()` is final and cannot be overridden.
- The seat-specific AABB is still retained for seat height/passenger attachment calculations and is refreshed by the wrapped level callback.
## 4.0.11-fabric-26.2
- Reworked seat interaction dispatch to mirror Refurbished Furniture: seating is performed from `useWithoutItem`; held-item paths return `TRY_WITH_EMPTY_HAND` after Handcrafted-specific cushion handling.
- Removed client-side fake success from `SittableBlock.sitOn`; `Seat.sit` is server-authoritative like the reference implementation.
- Seat blocks now return `SUCCESS` after the empty-hand interaction attempt, matching the reference block behavior.
- Added concise server-side Seat attempt/result diagnostics so a failed mount is visible in `latest.log`.
+1 -1
View File
@@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx4G
org.gradle.parallel=true
org.gradle.caching=true
mod_version=4.0.10
mod_version=4.0.12
maven_group=earth.terrarium.handcrafted
archives_base_name=handcrafted
@@ -92,19 +92,13 @@ public class ChairBlock extends HorizontalDirectionalBlock implements SittableBl
protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) {
InteractionResult result = InteractionUtils.interactOptionalCushion(state, level, pos, player, stack, COLOR);
if (result != InteractionResult.TRY_WITH_EMPTY_HAND) return result;
if (this.sitOn(level, pos, player, state.getValue(FACING))) {
return InteractionResult.CONSUME;
}
return InteractionResult.CONSUME;
return InteractionResult.TRY_WITH_EMPTY_HAND;
}
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
return this.sitOn(level, pos, player, state.getValue(FACING))
? InteractionResult.SUCCESS
: InteractionResult.PASS;
this.sitOn(level, pos, player, state.getValue(FACING));
return InteractionResult.SUCCESS;
}
@Override
@@ -36,10 +36,8 @@ public class CushionBlock extends Block implements SittableBlock {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
if (this.sitOn(level, pos, player, null)) {
return InteractionResult.CONSUME;
}
return InteractionResult.CONSUME;
this.sitOn(level, pos, player, null);
return InteractionResult.SUCCESS;
}
@Override
@@ -63,17 +63,13 @@ public class DiningBenchBlock extends HorizontalDirectionalBlock implements Sitt
@Override
protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) {
if (this.sitOn(level, pos, player, null)) {
return InteractionResult.CONSUME;
}
return InteractionResult.CONSUME;
return InteractionResult.TRY_WITH_EMPTY_HAND;
}
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
return this.sitOn(level, pos, player, null)
? InteractionResult.SUCCESS
: InteractionResult.PASS;
this.sitOn(level, pos, player, null);
return InteractionResult.SUCCESS;
}
@Override
@@ -89,17 +89,13 @@ public abstract class ModularSeatBlock extends HorizontalDirectionalBlock implem
@Override
protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) {
if (this.sitOn(level, pos, player, state.getValue(FACING))) {
return InteractionResult.CONSUME;
}
return InteractionResult.CONSUME;
return InteractionResult.TRY_WITH_EMPTY_HAND;
}
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
return this.sitOn(level, pos, player, state.getValue(FACING))
? InteractionResult.SUCCESS
: InteractionResult.PASS;
this.sitOn(level, pos, player, state.getValue(FACING));
return InteractionResult.SUCCESS;
}
@Override
@@ -10,11 +10,6 @@ import net.minecraft.world.phys.AABB;
public interface SittableBlock {
default boolean sitOn(Level level, BlockPos pos, Player player, Direction dir) {
// Keep seating server-authoritative. On the client, report a handled
// interaction so Minecraft sends/keeps the block-use interaction path.
if (level.isClientSide()) {
return true;
}
return Seat.sit(player, pos, this.getSeatHeight(level.getBlockState(pos)), dir);
}
@@ -1,6 +1,9 @@
package earth.terrarium.handcrafted.common.entities;
import earth.terrarium.handcrafted.Handcrafted;
import earth.terrarium.handcrafted.common.blocks.base.SittableBlock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import earth.terrarium.handcrafted.common.registry.ModEntityTypes;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -20,6 +23,7 @@ import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class Seat extends Entity {
private static final Logger LOGGER = LoggerFactory.getLogger(Handcrafted.MOD_ID + "/Seat");
private boolean canRotate;
public Seat(EntityType<? extends Entity> entityType, Level level) {
@@ -39,10 +43,17 @@ public class Seat extends Entity {
public static boolean sit(Player player, BlockPos pos, double seatHeight, Direction dir) {
Level level = player.level();
if (!level.isClientSide() && availableAt(level, pos)) {
if (level.isClientSide()) {
return false;
}
boolean available = availableAt(level, pos);
LOGGER.info("Seat attempt: player={}, pos={}, height={}, direction={}, available={}", player.getName().getString(), pos, seatHeight, dir, available);
if (available) {
Seat seat = new Seat(level, pos, seatHeight, dir);
level.addFreshEntity(seat);
if (player.startRiding(seat)) {
boolean spawned = level.addFreshEntity(seat);
boolean mounted = spawned && player.startRiding(seat);
LOGGER.info("Seat result: spawned={}, mounted={}, seatId={}", spawned, mounted, seat.getId());
if (mounted) {
return true;
}
seat.discard();
@@ -19,7 +19,6 @@ public class ModEntityTypes {
public static final RegistryEntry<EntityType<Seat>> SEAT = ENTITY_TYPES.register("seat", () ->
EntityType.Builder.<Seat>of(Seat::new, MobCategory.MISC)
.sized(0, 0)
.noSave()
.fireImmune()
.noSummon()
.build(ResourceKey.create(Registries.ENTITY_TYPE, Identifier.fromNamespaceAndPath(Handcrafted.MOD_ID, "seat"))));