feat: A-frame tent + portal walk-through field + texture polish
All checks were successful
Deploy Addons / deploy (push) Successful in 14s
All checks were successful
Deploy Addons / deploy (push) Successful in 14s
- camping: replace cube tent with A-frame slope panels (tent_panel_l/r) + cardinal_direction permutations; vote-skip sleep that mixes player.isSleeping bed sleepers with tent occupants and respects the playersSleepingPercentage gamerule; new weathered-canvas texture. - lobby: walk-through silverlabs:portal_field block (no collision, translucent swirl, cross-plane geo) auto-placed above each portal frame; invisible silverlabs:portal_label entity floats above each portal with the destination world name; transfer detection now scans down through the field to find the destination frame. - postal: regenerate post_office and mailbox block textures so they fill the full block face (brick + POST plaque, full red panel with slot/latch /flag/rivets) instead of small sprites floating on transparent. - dynamite + tow-boat: ship the addons (volumes wired into all four worlds; enabled_packs registers them into Mya's world). - art: build-textures.py extended; build-art-catalog.py added to project. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
95
tow-boat-addon/tow_boat_BP/entities/tow_boat.json
Normal file
95
tow-boat-addon/tow_boat_BP/entities/tow_boat.json
Normal file
@@ -0,0 +1,95 @@
|
||||
{
|
||||
"format_version": "1.21.0",
|
||||
"minecraft:entity": {
|
||||
"description": {
|
||||
"identifier": "silverlabs:tow_boat",
|
||||
"is_spawnable": false,
|
||||
"is_summonable": true,
|
||||
"is_experimental": false
|
||||
},
|
||||
"components": {
|
||||
"minecraft:type_family": {
|
||||
"family": ["tow_boat", "boat"]
|
||||
},
|
||||
"minecraft:health": {
|
||||
"value": 20,
|
||||
"max": 20
|
||||
},
|
||||
"minecraft:collision_box": {
|
||||
"width": 1.4,
|
||||
"height": 0.55
|
||||
},
|
||||
"minecraft:physics": {
|
||||
"has_gravity": true,
|
||||
"has_collision": true
|
||||
},
|
||||
"minecraft:pushable": {
|
||||
"is_pushable": true,
|
||||
"is_pushable_by_piston": false
|
||||
},
|
||||
"minecraft:persistent": {},
|
||||
"minecraft:nameable": {},
|
||||
"minecraft:movement": {
|
||||
"value": 0.18
|
||||
},
|
||||
"minecraft:movement.basic": {},
|
||||
"minecraft:navigation.float": {
|
||||
"can_path_over_water": true,
|
||||
"can_breach": false
|
||||
},
|
||||
"minecraft:underwater_movement": {
|
||||
"value": 0.0
|
||||
},
|
||||
"minecraft:can_climb": {},
|
||||
"minecraft:rideable": {
|
||||
"seat_count": 1,
|
||||
"family_types": ["player"],
|
||||
"interact_text": "action.interact.mount",
|
||||
"pull_in_entities": false,
|
||||
"seats": [
|
||||
{
|
||||
"position": [0, 0.4, 0.0],
|
||||
"lock_rider_rotation": 90,
|
||||
"min_rider_count": 0,
|
||||
"max_rider_count": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:input_ground_controlled": {},
|
||||
"minecraft:leashable": {
|
||||
"soft_distance": 4.0,
|
||||
"hard_distance": 6.0,
|
||||
"max_distance": 12.0
|
||||
},
|
||||
"minecraft:damage_sensor": {
|
||||
"triggers": [
|
||||
{
|
||||
"cause": "drowning",
|
||||
"deals_damage": "no"
|
||||
},
|
||||
{
|
||||
"cause": "fall",
|
||||
"deals_damage": "no"
|
||||
},
|
||||
{
|
||||
"cause": "fire",
|
||||
"deals_damage": "no"
|
||||
},
|
||||
{
|
||||
"cause": "fire_tick",
|
||||
"deals_damage": "no"
|
||||
},
|
||||
{
|
||||
"cause": "lava",
|
||||
"deals_damage": "no"
|
||||
},
|
||||
{
|
||||
"cause": "suffocation",
|
||||
"deals_damage": "no"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"events": {}
|
||||
}
|
||||
}
|
||||
26
tow-boat-addon/tow_boat_BP/items/tow_boat.json
Normal file
26
tow-boat-addon/tow_boat_BP/items/tow_boat.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"format_version": "1.21.0",
|
||||
"minecraft:item": {
|
||||
"description": {
|
||||
"identifier": "silverlabs:tow_boat",
|
||||
"menu_category": {
|
||||
"category": "equipment",
|
||||
"group": "itemGroup.name.boat"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:max_stack_size": 1,
|
||||
"minecraft:icon": "tow_boat",
|
||||
"minecraft:display_name": {
|
||||
"value": "Tow Boat"
|
||||
},
|
||||
"minecraft:entity_placer": {
|
||||
"entity": "silverlabs:tow_boat",
|
||||
"use_on": [
|
||||
"minecraft:water",
|
||||
"minecraft:flowing_water"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
tow-boat-addon/tow_boat_BP/manifest.json
Normal file
33
tow-boat-addon/tow_boat_BP/manifest.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"name": "Tow Boat",
|
||||
"description": "A flatbed boat that can be leashed and chained for towing.",
|
||||
"uuid": "a35d89fd-99e1-497a-9e78-35443c0cd59f",
|
||||
"version": [1, 0, 0],
|
||||
"min_engine_version": [1, 21, 0]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "data",
|
||||
"uuid": "b29d967c-8a9a-491d-867d-2866890780f0",
|
||||
"version": [1, 0, 0]
|
||||
},
|
||||
{
|
||||
"type": "script",
|
||||
"uuid": "06b92593-0c15-41a0-8f39-bc6bba516ebb",
|
||||
"version": [1, 0, 0],
|
||||
"entry": "scripts/main.js"
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"uuid": "c6193eda-f160-475b-ab65-fca17741e41b",
|
||||
"version": [1, 0, 0]
|
||||
},
|
||||
{
|
||||
"module_name": "@minecraft/server",
|
||||
"version": "1.17.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
tow-boat-addon/tow_boat_BP/pack_icon.png
Normal file
BIN
tow-boat-addon/tow_boat_BP/pack_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 381 B |
24
tow-boat-addon/tow_boat_BP/recipes/tow_boat.json
Normal file
24
tow-boat-addon/tow_boat_BP/recipes/tow_boat.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"format_version": "1.21.0",
|
||||
"minecraft:recipe_shaped": {
|
||||
"description": {
|
||||
"identifier": "silverlabs:tow_boat_recipe"
|
||||
},
|
||||
"tags": ["crafting_table"],
|
||||
"unlock": [
|
||||
{ "item": "minecraft:lead" }
|
||||
],
|
||||
"pattern": [
|
||||
"PLP",
|
||||
"PPP"
|
||||
],
|
||||
"key": {
|
||||
"P": { "item": "minecraft:planks" },
|
||||
"L": { "item": "minecraft:lead" }
|
||||
},
|
||||
"result": {
|
||||
"item": "silverlabs:tow_boat",
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
150
tow-boat-addon/tow_boat_BP/scripts/main.js
Normal file
150
tow-boat-addon/tow_boat_BP/scripts/main.js
Normal file
@@ -0,0 +1,150 @@
|
||||
import { world, system } from "@minecraft/server";
|
||||
|
||||
const BOAT = "silverlabs:tow_boat";
|
||||
const TOW_PROP = "silverlabs:tow_target";
|
||||
|
||||
const SOFT_DIST = 3.0;
|
||||
const HARD_DIST = 8.0;
|
||||
const PULL_GAIN = 0.20;
|
||||
const TICK_RATE = 4;
|
||||
|
||||
function dist(a, b) {
|
||||
const dx = a.x - b.x;
|
||||
const dy = a.y - b.y;
|
||||
const dz = a.z - b.z;
|
||||
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
function unitVec(from, to, len) {
|
||||
return {
|
||||
x: (to.x - from.x) / len,
|
||||
y: (to.y - from.y) / len,
|
||||
z: (to.z - from.z) / len
|
||||
};
|
||||
}
|
||||
|
||||
function getTowTarget(boat) {
|
||||
const id = boat.getDynamicProperty(TOW_PROP);
|
||||
return typeof id === "string" && id.length > 0 ? id : null;
|
||||
}
|
||||
|
||||
function setTowTarget(boat, targetId) {
|
||||
boat.setDynamicProperty(TOW_PROP, targetId);
|
||||
}
|
||||
|
||||
function clearTowTarget(boat) {
|
||||
boat.setDynamicProperty(TOW_PROP, "");
|
||||
}
|
||||
|
||||
function findLeashedBoat(player) {
|
||||
const overworld = world.getDimension(player.dimension.id);
|
||||
const nearby = overworld.getEntities({
|
||||
type: BOAT,
|
||||
location: player.location,
|
||||
maxDistance: 16
|
||||
});
|
||||
for (const boat of nearby) {
|
||||
try {
|
||||
const holder = boat.getComponent("leashable")?.leashHolder;
|
||||
if (holder && holder.id === player.id) return boat;
|
||||
} catch {
|
||||
/* ignore — component may be unavailable mid-load */
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
world.beforeEvents.playerInteractWithEntity.subscribe((ev) => {
|
||||
const { player, target } = ev;
|
||||
if (target.typeId !== BOAT) return;
|
||||
if (!player.isSneaking) return;
|
||||
|
||||
const inv = player.getComponent("inventory")?.container;
|
||||
const held = inv?.getItem(player.selectedSlotIndex);
|
||||
if (held) return; // empty hand only
|
||||
|
||||
if (getTowTarget(target)) {
|
||||
ev.cancel = true;
|
||||
system.run(() => {
|
||||
clearTowTarget(target);
|
||||
player.sendMessage("§eTow link removed.");
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const leader = findLeashedBoat(player);
|
||||
if (!leader || leader.id === target.id) return;
|
||||
|
||||
ev.cancel = true;
|
||||
system.run(() => {
|
||||
setTowTarget(target, leader.id);
|
||||
try {
|
||||
leader.getComponent("leashable")?.unleash();
|
||||
} catch {
|
||||
/* unleash may not exist on all versions; safe to ignore */
|
||||
}
|
||||
player.sendMessage("§aTow link created — boat will follow the leader.");
|
||||
});
|
||||
});
|
||||
|
||||
function tickFollowers() {
|
||||
for (const dim of ["overworld", "nether", "the_end"]) {
|
||||
let boats;
|
||||
try {
|
||||
boats = world.getDimension(dim).getEntities({ type: BOAT });
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
for (const boat of boats) {
|
||||
const targetId = getTowTarget(boat);
|
||||
if (!targetId) continue;
|
||||
|
||||
const target = world.getEntity(targetId);
|
||||
if (!target || !target.isValid()) {
|
||||
clearTowTarget(boat);
|
||||
continue;
|
||||
}
|
||||
|
||||
const d = dist(boat.location, target.location);
|
||||
if (d < SOFT_DIST) continue;
|
||||
|
||||
if (d > HARD_DIST) {
|
||||
const u = unitVec(target.location, boat.location, d);
|
||||
try {
|
||||
boat.teleport({
|
||||
x: target.location.x + u.x * (SOFT_DIST - 0.5),
|
||||
y: target.location.y,
|
||||
z: target.location.z + u.z * (SOFT_DIST - 0.5)
|
||||
});
|
||||
} catch { /* chunk unloaded */ }
|
||||
continue;
|
||||
}
|
||||
|
||||
const u = unitVec(boat.location, target.location, d);
|
||||
try {
|
||||
boat.applyImpulse({
|
||||
x: u.x * PULL_GAIN,
|
||||
y: 0,
|
||||
z: u.z * PULL_GAIN
|
||||
});
|
||||
} catch { /* boat may not support impulse if unloaded */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
system.runInterval(tickFollowers, TICK_RATE);
|
||||
|
||||
world.afterEvents.entityRemove.subscribe((ev) => {
|
||||
const removedId = ev.removedEntityId;
|
||||
for (const dim of ["overworld", "nether", "the_end"]) {
|
||||
let boats;
|
||||
try {
|
||||
boats = world.getDimension(dim).getEntities({ type: BOAT });
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
for (const boat of boats) {
|
||||
if (getTowTarget(boat) === removedId) clearTowTarget(boat);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"animations": {
|
||||
"animation.tow_boat.bob": {
|
||||
"loop": true,
|
||||
"animation_length": 4.0,
|
||||
"bones": {
|
||||
"root": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"1.0": [0, 0.6, 0],
|
||||
"2.0": [0, 0, 0],
|
||||
"3.0": [0, -0.4, 0],
|
||||
"4.0": [0, 0, 0]
|
||||
},
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"1.0": [1.5, 0, -0.5],
|
||||
"2.0": [0, 0, 0],
|
||||
"3.0": [-1.0, 0, 0.5],
|
||||
"4.0": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
tow-boat-addon/tow_boat_RP/entity/tow_boat.entity.json
Normal file
30
tow-boat-addon/tow_boat_RP/entity/tow_boat.entity.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"minecraft:client_entity": {
|
||||
"description": {
|
||||
"identifier": "silverlabs:tow_boat",
|
||||
"materials": {
|
||||
"default": "entity_alphatest"
|
||||
},
|
||||
"textures": {
|
||||
"default": "textures/entity/tow_boat"
|
||||
},
|
||||
"geometry": {
|
||||
"default": "geometry.tow_boat"
|
||||
},
|
||||
"render_controllers": [
|
||||
"controller.render.tow_boat"
|
||||
],
|
||||
"animations": {
|
||||
"bob": "animation.tow_boat.bob"
|
||||
},
|
||||
"scripts": {
|
||||
"animate": ["bob"]
|
||||
},
|
||||
"spawn_egg": {
|
||||
"texture": "tow_boat",
|
||||
"texture_index": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
tow-boat-addon/tow_boat_RP/manifest.json
Normal file
17
tow-boat-addon/tow_boat_RP/manifest.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"name": "Tow Boat Resources",
|
||||
"description": "Model, texture, and animations for the Tow Boat addon.",
|
||||
"uuid": "c6193eda-f160-475b-ab65-fca17741e41b",
|
||||
"version": [1, 0, 0],
|
||||
"min_engine_version": [1, 21, 0]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "resources",
|
||||
"uuid": "2ef90fb4-1c8f-404e-924f-a41463a51758",
|
||||
"version": [1, 0, 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
105
tow-boat-addon/tow_boat_RP/models/entity/tow_boat.geo.json
Normal file
105
tow-boat-addon/tow_boat_RP/models/entity/tow_boat.geo.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:geometry": [
|
||||
{
|
||||
"description": {
|
||||
"identifier": "geometry.tow_boat",
|
||||
"texture_width": 64,
|
||||
"texture_height": 32,
|
||||
"visible_bounds_width": 3,
|
||||
"visible_bounds_height": 2,
|
||||
"visible_bounds_offset": [0, 0.5, 0]
|
||||
},
|
||||
"bones": [
|
||||
{
|
||||
"name": "root",
|
||||
"pivot": [0, 0, 0]
|
||||
},
|
||||
{
|
||||
"name": "hull",
|
||||
"parent": "root",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-11, 0, -16],
|
||||
"size": [22, 3, 32],
|
||||
"uv": [0, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "deck",
|
||||
"parent": "hull",
|
||||
"pivot": [0, 3, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-11, 3, -16],
|
||||
"size": [22, 1, 32],
|
||||
"uv": [0, 16]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rail_left",
|
||||
"parent": "deck",
|
||||
"pivot": [-11, 4, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-12, 4, -16],
|
||||
"size": [1, 2, 32],
|
||||
"uv": [0, 18]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rail_right",
|
||||
"parent": "deck",
|
||||
"pivot": [11, 4, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [11, 4, -16],
|
||||
"size": [1, 2, 32],
|
||||
"uv": [0, 18]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rail_front",
|
||||
"parent": "deck",
|
||||
"pivot": [0, 4, -16],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-11, 4, -17],
|
||||
"size": [22, 2, 1],
|
||||
"uv": [0, 22]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rail_back",
|
||||
"parent": "deck",
|
||||
"pivot": [0, 4, 16],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-11, 4, 16],
|
||||
"size": [22, 2, 1],
|
||||
"uv": [0, 22]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tow_post",
|
||||
"parent": "deck",
|
||||
"pivot": [0, 4, -14],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-1, 4, -15],
|
||||
"size": [2, 4, 2],
|
||||
"uv": [44, 16]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
tow-boat-addon/tow_boat_RP/pack_icon.png
Normal file
BIN
tow-boat-addon/tow_boat_RP/pack_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 381 B |
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"render_controllers": {
|
||||
"controller.render.tow_boat": {
|
||||
"geometry": "Geometry.default",
|
||||
"materials": [
|
||||
{ "*": "Material.default" }
|
||||
],
|
||||
"textures": ["Texture.default"]
|
||||
}
|
||||
}
|
||||
}
|
||||
3
tow-boat-addon/tow_boat_RP/texts/en_US.lang
Normal file
3
tow-boat-addon/tow_boat_RP/texts/en_US.lang
Normal file
@@ -0,0 +1,3 @@
|
||||
item.silverlabs:tow_boat=Tow Boat
|
||||
entity.silverlabs:tow_boat.name=Tow Boat
|
||||
action.interact.mount=Mount
|
||||
3
tow-boat-addon/tow_boat_RP/texts/languages.json
Normal file
3
tow-boat-addon/tow_boat_RP/texts/languages.json
Normal file
@@ -0,0 +1,3 @@
|
||||
[
|
||||
"en_US"
|
||||
]
|
||||
BIN
tow-boat-addon/tow_boat_RP/textures/entity/tow_boat.png
Normal file
BIN
tow-boat-addon/tow_boat_RP/textures/entity/tow_boat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 571 B |
9
tow-boat-addon/tow_boat_RP/textures/item_texture.json
Normal file
9
tow-boat-addon/tow_boat_RP/textures/item_texture.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"resource_pack_name": "tow_boat_RP",
|
||||
"texture_name": "atlas.items",
|
||||
"texture_data": {
|
||||
"tow_boat": {
|
||||
"textures": "textures/items/tow_boat"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
tow-boat-addon/tow_boat_RP/textures/items/tow_boat.png
Normal file
BIN
tow-boat-addon/tow_boat_RP/textures/items/tow_boat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 160 B |
Reference in New Issue
Block a user