diff --git a/camping-supplies-addon/camping_supplies_BP/blocks/hammock_cloth.json b/camping-supplies-addon/camping_supplies_BP/blocks/hammock_cloth.json index 7a11607..efd12b4 100644 --- a/camping-supplies-addon/camping_supplies_BP/blocks/hammock_cloth.json +++ b/camping-supplies-addon/camping_supplies_BP/blocks/hammock_cloth.json @@ -20,7 +20,7 @@ }, "minecraft:collision_box": { "origin": [-8, 0, -8], - "size": [16, 4, 16] + "size": [16, 1, 16] }, "minecraft:selection_box": { "origin": [-8, 0, -8], diff --git a/camping-supplies-addon/camping_supplies_BP/scripts/main.js b/camping-supplies-addon/camping_supplies_BP/scripts/main.js index a338096..37c5558 100644 --- a/camping-supplies-addon/camping_supplies_BP/scripts/main.js +++ b/camping-supplies-addon/camping_supplies_BP/scripts/main.js @@ -112,7 +112,7 @@ function tryPlaceTent(player) { const cx = ox + l * fx + w * rx; const cz = oz + l * fz + w * rz; groundCells.push({ x: cx, y: oy - 1, z: cz }); - for (let h = 0; h <= 2; h++) clearCells.push({ x: cx, y: oy + h, z: cz }); + for (let h = 0; h <= 1; h++) clearCells.push({ x: cx, y: oy + h, z: cz }); } } @@ -310,31 +310,81 @@ function sleepInTent(player) { player.sendMessage("§a[Camping] §7You rest until dawn. §8Spawn point unchanged."); } +const HAMMOCK_ANCHOR_PROP = "camping_hammock_anchor"; + function toggleHammock(player, loc) { if (player.hasTag(HAMMOCK_TAG)) { - player.removeTag(HAMMOCK_TAG); - player.sendMessage("§7[Camping] You climb out of the hammock."); + exitHammock(player); return; } player.addTag(HAMMOCK_TAG); + const anchor = { x: loc.x + 0.5, y: loc.y + 0.1, z: loc.z + 0.5 }; try { - player.teleport( - { x: loc.x + 0.5, y: loc.y + 0.4, z: loc.z + 0.5 }, - { dimension: player.dimension } - ); + player.setDynamicProperty(HAMMOCK_ANCHOR_PROP, JSON.stringify(anchor)); + } catch (_) {} + try { + player.teleport(anchor, { dimension: player.dimension }); + } catch (_) {} + // Slowness 255 + weakness + mining_fatigue make the player effectively immobile while + // still conscious; saturation + regen are the "rest" payoff. + try { + player.addEffect("slowness", 100000, { amplifier: 255, showParticles: false }); + player.addEffect("weakness", 100000, { amplifier: 255, showParticles: false }); + player.addEffect("mining_fatigue", 100000, { amplifier: 255, showParticles: false }); + player.addEffect("saturation", 40, { amplifier: 0, showParticles: false }); + player.addEffect("regeneration", 200, { amplifier: 1, showParticles: false }); } catch (_) {} player.sendMessage("§a[Camping] §7You settle into the hammock. Wild creatures don't notice you. §8(Sneak to climb out.)"); } -// ─── Hammock upkeep loop: mob repulsion + sneak-exit ──────── +function exitHammock(player) { + player.removeTag(HAMMOCK_TAG); + try { + player.removeEffect("slowness"); + player.removeEffect("weakness"); + player.removeEffect("mining_fatigue"); + } catch (_) {} + // Nudge player one block off the hammock so the next tick doesn't re-teleport them + // back into the cradle. + try { + const raw = player.getDynamicProperty(HAMMOCK_ANCHOR_PROP); + if (raw && typeof raw === "string") { + const a = JSON.parse(raw); + const yaw = player.getRotation().y; + const rad = (yaw * Math.PI) / 180; + const dx = -Math.sin(rad); + const dz = Math.cos(rad); + player.teleport( + { x: a.x + dx * 1.2, y: a.y + 0.3, z: a.z + dz * 1.2 }, + { dimension: player.dimension } + ); + } + } catch (_) {} + try { player.setDynamicProperty(HAMMOCK_ANCHOR_PROP, undefined); } catch (_) {} + player.sendMessage("§7[Camping] You climb out of the hammock."); +} + +// ─── Hammock upkeep loop: position lock + mob repulsion + sneak-exit ──────── system.runInterval(() => { for (const player of world.getAllPlayers()) { if (!player.hasTag(HAMMOCK_TAG)) continue; if (player.isSneaking) { - player.removeTag(HAMMOCK_TAG); - player.sendMessage("§7[Camping] You climb out of the hammock."); + exitHammock(player); continue; } + // Pin the player to the hammock anchor so they can't drift off even with slowness + try { + const raw = player.getDynamicProperty(HAMMOCK_ANCHOR_PROP); + if (raw && typeof raw === "string") { + const a = JSON.parse(raw); + const dx = player.location.x - a.x; + const dy = player.location.y - a.y; + const dz = player.location.z - a.z; + if (dx * dx + dy * dy + dz * dz > 0.25) { + player.teleport(a, { dimension: player.dimension }); + } + } + } catch (_) {} let hostiles = []; try { hostiles = player.dimension.getEntities({