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:
@@ -26,7 +26,7 @@
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 4, 16]
|
||||
},
|
||||
"minecraft:geometry": "minecraft:geometry.full_block",
|
||||
"minecraft:geometry": "geometry.silverlabs.hammock_slab",
|
||||
"minecraft:light_dampening": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"format_version": "1.21.0",
|
||||
"minecraft:geometry": [
|
||||
{
|
||||
"description": {
|
||||
"identifier": "geometry.silverlabs.hammock_slab",
|
||||
"texture_width": 16,
|
||||
"texture_height": 16,
|
||||
"visible_bounds_width": 2,
|
||||
"visible_bounds_height": 1,
|
||||
"visible_bounds_offset": [0, 0.25, 0]
|
||||
},
|
||||
"bones": [
|
||||
{
|
||||
"name": "root",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 4, 16],
|
||||
"uv": {
|
||||
"north": { "uv": [0, 12], "uv_size": [16, 4] },
|
||||
"south": { "uv": [0, 12], "uv_size": [16, 4] },
|
||||
"east": { "uv": [0, 12], "uv_size": [16, 4] },
|
||||
"west": { "uv": [0, 12], "uv_size": [16, 4] },
|
||||
"up": { "uv": [0, 0], "uv_size": [16, 16] },
|
||||
"down": { "uv": [0, 0], "uv_size": [16, 16] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user