fix(camping): half-slab hammock geometry + smarter tent grounding
All checks were successful
Deploy Addons / deploy (push) Successful in 15s
All checks were successful
Deploy Addons / deploy (push) Successful in 15s
- Hammock now uses a custom geometry.silverlabs.hammock_slab (8-voxel tall half-slab instead of a full cube), matching its thin collision box so the block reads visually as a hammock cradle, not a brick. - Tent placement now projects the player's feet down to the nearest solid block (up to 3 blocks) before picking the base Y, so mid-jump fractional positions or standing-on-slab cases don't mis-place the footprint one block too high. - Failure messages now include the exact failing cell coordinates and the block type that's in the way, so we can diagnose live pitch attempts without guesswork. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -96,14 +96,26 @@ function tryPlaceTent(player) {
|
||||
const dim = player.dimension;
|
||||
const facing = cardinalFacing(player.getRotation().y);
|
||||
const { fx, fz, rx, rz } = vecsForFacing(facing);
|
||||
const feet = {
|
||||
x: Math.floor(player.location.x),
|
||||
y: Math.floor(player.location.y),
|
||||
z: Math.floor(player.location.z),
|
||||
};
|
||||
const ox = feet.x + fx;
|
||||
const oy = feet.y;
|
||||
const oz = feet.z + fz;
|
||||
// Use precise player position; floor X/Z but scan Y downward to find the actual
|
||||
// standing surface. player.location.y may be fractionally above the block you're
|
||||
// on (e.g. 87.01), so floor() alone is reliable, but if the player is in the
|
||||
// air (jumping / on a slab / flying) we want to project them down to solid ground
|
||||
// so the tent doesn't try to sit on empty space.
|
||||
const feetX = Math.floor(player.location.x);
|
||||
const feetZ = Math.floor(player.location.z);
|
||||
let feetY = Math.floor(player.location.y);
|
||||
// If the block at feet level is air (player's mid-jump or location rounded up),
|
||||
// scan downward up to 3 blocks to find the ground.
|
||||
for (let probe = 0; probe < 4; probe++) {
|
||||
const here = dim.getBlock({ x: feetX, y: feetY - 1, z: feetZ });
|
||||
if (here && here.isSolid) break;
|
||||
const onSolid = dim.getBlock({ x: feetX, y: feetY, z: feetZ });
|
||||
if (onSolid && onSolid.isSolid) { feetY += 1; break; }
|
||||
feetY -= 1;
|
||||
}
|
||||
const ox = feetX + fx;
|
||||
const oy = feetY;
|
||||
const oz = feetZ + fz;
|
||||
|
||||
const groundCells = [];
|
||||
const clearCells = [];
|
||||
@@ -119,18 +131,19 @@ function tryPlaceTent(player) {
|
||||
for (const g of groundCells) {
|
||||
const b = dim.getBlock(g);
|
||||
if (!b || !b.isSolid) {
|
||||
player.sendMessage("§c[Camping] §7Need a flat 2×3 patch of solid ground in front of you.");
|
||||
const seen = b ? b.typeId : "unloaded";
|
||||
player.sendMessage(`§c[Camping] §7Ground at §f${g.x},${g.y},${g.z}§7 is §f${seen}§7 — need solid ground there.`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (const c of clearCells) {
|
||||
const b = dim.getBlock(c);
|
||||
if (!b) {
|
||||
player.sendMessage("§c[Camping] §7Can't reach that area (chunk unloaded).");
|
||||
player.sendMessage(`§c[Camping] §7Can't reach §f${c.x},${c.y},${c.z}§7 (chunk unloaded).`);
|
||||
return false;
|
||||
}
|
||||
if (!b.isAir && !b.isLiquid) {
|
||||
player.sendMessage("§c[Camping] §7The space above the tent footprint isn't clear.");
|
||||
player.sendMessage(`§c[Camping] §7Space at §f${c.x},${c.y},${c.z}§7 is blocked by §f${b.typeId}§7.`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user