Compare commits
7 Commits
77a7524917
...
17a9faf206
| Author | SHA1 | Date | |
|---|---|---|---|
| 17a9faf206 | |||
| 9789906277 | |||
| 6bda72598d | |||
| af9d37462c | |||
| 7c8cd5b075 | |||
| b9e3380f6c | |||
| 145f5d9beb |
@@ -2,22 +2,38 @@
|
|||||||
"format_version": 2,
|
"format_version": 2,
|
||||||
"header": {
|
"header": {
|
||||||
"name": "Hey Hey Chicken Pet",
|
"name": "Hey Hey Chicken Pet",
|
||||||
"description": "Hey Hey the loyal Moana chicken — tameable, following pet with waddly personality.",
|
"description": "Hey Hey the loyal Moana chicken \u2014 tameable, following pet with waddly personality.",
|
||||||
"uuid": "fc811a53-dbdb-4701-bc63-c3ca1d793c47",
|
"uuid": "fc811a53-dbdb-4701-bc63-c3ca1d793c47",
|
||||||
"version": [1, 0, 0],
|
"version": [
|
||||||
"min_engine_version": [1, 21, 0]
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"min_engine_version": [
|
||||||
|
1,
|
||||||
|
21,
|
||||||
|
0
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"type": "data",
|
"type": "data",
|
||||||
"uuid": "f7aae24a-06d8-432b-85dc-359c4fda9dfd",
|
"uuid": "f7aae24a-06d8-432b-85dc-359c4fda9dfd",
|
||||||
"version": [1, 0, 0]
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
{
|
{
|
||||||
"uuid": "45ec17df-0d84-456f-b2cc-2d990f96e6d5",
|
"uuid": "45ec17df-0d84-456f-b2cc-2d990f96e6d5",
|
||||||
"version": [1, 0, 0]
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,38 @@
|
|||||||
"format_version": 2,
|
"format_version": 2,
|
||||||
"header": {
|
"header": {
|
||||||
"name": "Pets 4 Jamie's STARS",
|
"name": "Pets 4 Jamie's STARS",
|
||||||
"description": "Tameable dragon pets with eggs, gravestones and personality — built for Jamie's STARS!",
|
"description": "Tameable dragon pets with eggs, gravestones and personality \u2014 built for Jamie's STARS!",
|
||||||
"uuid": "7cf924ce-e246-4c8c-998c-f420edb26451",
|
"uuid": "7cf924ce-e246-4c8c-998c-f420edb26451",
|
||||||
"version": [1, 0, 0],
|
"version": [
|
||||||
"min_engine_version": [1, 21, 0]
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"min_engine_version": [
|
||||||
|
1,
|
||||||
|
21,
|
||||||
|
0
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"type": "data",
|
"type": "data",
|
||||||
"uuid": "6806e843-c0b4-4a4d-9cb3-d5352e396fe5",
|
"uuid": "6806e843-c0b4-4a4d-9cb3-d5352e396fe5",
|
||||||
"version": [1, 0, 0]
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
{
|
{
|
||||||
"uuid": "5f25d547-00bb-49ce-8be3-d86cd3941c9b",
|
"uuid": "5f25d547-00bb-49ce-8be3-d86cd3941c9b",
|
||||||
"version": [1, 0, 0]
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
{ "fire_breathing": "query.property('silverlabs:firing')" },
|
{ "fire_breathing": "query.property('silverlabs:firing')" },
|
||||||
{ "flying": "!query.is_on_ground && query.property('silverlabs:growth_stage') == 2" },
|
{ "flying": "!query.is_on_ground && query.property('silverlabs:growth_stage') == 2" },
|
||||||
{ "walking": "query.modified_move_speed > 0.1" },
|
{ "walking": "query.modified_move_speed > 0.1" },
|
||||||
{ "sleeping": "query.is_sitting && (query.day_light_level < 4)" },
|
{ "sleeping": "query.is_sitting && (query.time_of_day > 0.5)" },
|
||||||
{ "sitting": "query.is_sitting" },
|
{ "sitting": "query.is_sitting" },
|
||||||
{ "grooming": "query.is_on_ground && query.modified_move_speed <= 0.05 && math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) == 1" },
|
{ "grooming": "query.is_on_ground && query.modified_move_speed <= 0.05 && math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) == 1" },
|
||||||
{ "sniffing": "query.is_on_ground && query.modified_move_speed <= 0.15 && math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) == 2" },
|
{ "sniffing": "query.is_on_ground && query.modified_move_speed <= 0.15 && math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) == 2" },
|
||||||
@@ -52,14 +52,14 @@
|
|||||||
"animations": ["sit"],
|
"animations": ["sit"],
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "idle": "!query.is_sitting" },
|
{ "idle": "!query.is_sitting" },
|
||||||
{ "sleeping": "query.is_sitting && (query.day_light_level < 4)" }
|
{ "sleeping": "query.is_sitting && (query.time_of_day > 0.5)" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"sleeping": {
|
"sleeping": {
|
||||||
"animations": ["sleep"],
|
"animations": ["sleep"],
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "idle": "!query.is_sitting" },
|
{ "idle": "!query.is_sitting" },
|
||||||
{ "sitting": "query.is_sitting && (query.day_light_level >= 4)" }
|
{ "sitting": "query.is_sitting && (query.time_of_day <= 0.5)" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"flying": {
|
"flying": {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
"particle_effects": {
|
"particle_effects": {
|
||||||
"beacon_beam": "minecraft:endrod",
|
"beacon_beam": "minecraft:endrod",
|
||||||
"mood_happy": "minecraft:villager_happy",
|
"mood_happy": "minecraft:villager_happy",
|
||||||
"mood_needy": "minecraft:large_smoke"
|
"mood_needy": "minecraft:basic_smoke_particle"
|
||||||
},
|
},
|
||||||
"spawn_egg": {
|
"spawn_egg": {
|
||||||
"base_color": "#7B2FBE",
|
"base_color": "#7B2FBE",
|
||||||
|
|||||||
@@ -4,14 +4,14 @@
|
|||||||
"name": "Pets 4 Jamie's STARS Resources",
|
"name": "Pets 4 Jamie's STARS Resources",
|
||||||
"description": "Textures, models and animations for Pets 4 Jamie's STARS",
|
"description": "Textures, models and animations for Pets 4 Jamie's STARS",
|
||||||
"uuid": "5f25d547-00bb-49ce-8be3-d86cd3941c9b",
|
"uuid": "5f25d547-00bb-49ce-8be3-d86cd3941c9b",
|
||||||
"version": [1, 0, 0],
|
"version": [1, 0, 1],
|
||||||
"min_engine_version": [1, 21, 0]
|
"min_engine_version": [1, 21, 0]
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"type": "resources",
|
"type": "resources",
|
||||||
"uuid": "6adc20cd-25a5-4ca5-aa12-f5e43ee9ea22",
|
"uuid": "6adc20cd-25a5-4ca5-aa12-f5e43ee9ea22",
|
||||||
"version": [1, 0, 0]
|
"version": [1, 0, 1]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:item": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:ore_detector_advanced",
|
||||||
|
"menu_category": {
|
||||||
|
"category": "equipment",
|
||||||
|
"group": "itemGroup.name.miscellaneous"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"minecraft:max_stack_size": 1,
|
||||||
|
"minecraft:icon": "ore_detector_advanced",
|
||||||
|
"minecraft:hand_equipped": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:item": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:ore_detector_basic",
|
||||||
|
"menu_category": {
|
||||||
|
"category": "equipment",
|
||||||
|
"group": "itemGroup.name.miscellaneous"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"minecraft:max_stack_size": 1,
|
||||||
|
"minecraft:icon": "ore_detector_basic",
|
||||||
|
"minecraft:hand_equipped": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:item": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:ore_detector_improved",
|
||||||
|
"menu_category": {
|
||||||
|
"category": "equipment",
|
||||||
|
"group": "itemGroup.name.miscellaneous"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"minecraft:max_stack_size": 1,
|
||||||
|
"minecraft:icon": "ore_detector_improved",
|
||||||
|
"minecraft:hand_equipped": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,20 +4,36 @@
|
|||||||
"name": "Camping Supplies",
|
"name": "Camping Supplies",
|
||||||
"description": "Craftable tent and hammock for overnight camping without setting your spawn point",
|
"description": "Craftable tent and hammock for overnight camping without setting your spawn point",
|
||||||
"uuid": "bcf569fa-8b2c-403e-9f75-6b405132c5cd",
|
"uuid": "bcf569fa-8b2c-403e-9f75-6b405132c5cd",
|
||||||
"version": [1, 0, 0],
|
"version": [
|
||||||
"min_engine_version": [1, 21, 0]
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"min_engine_version": [
|
||||||
|
1,
|
||||||
|
21,
|
||||||
|
0
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"type": "data",
|
"type": "data",
|
||||||
"uuid": "f306e1d8-3c13-4554-9715-4799ce6d41d8",
|
"uuid": "f306e1d8-3c13-4554-9715-4799ce6d41d8",
|
||||||
"version": [1, 0, 0]
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "script",
|
"type": "script",
|
||||||
"language": "javascript",
|
"language": "javascript",
|
||||||
"uuid": "1e496657-0c83-4707-a1e8-29b757dcce79",
|
"uuid": "1e496657-0c83-4707-a1e8-29b757dcce79",
|
||||||
"version": [1, 0, 0],
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
"entry": "scripts/main.js"
|
"entry": "scripts/main.js"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -28,7 +44,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"uuid": "36f12107-10c6-484c-a0f2-b5dd88cd5baa",
|
"uuid": "36f12107-10c6-484c-a0f2-b5dd88cd5baa",
|
||||||
"version": [1, 0, 0]
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:recipe_shapeless": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:ore_detector_advanced_recipe"
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"crafting_table"
|
||||||
|
],
|
||||||
|
"unlock": [
|
||||||
|
{
|
||||||
|
"item": "silverlabs:ore_detector_improved"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ingredients": [
|
||||||
|
{ "item": "silverlabs:ore_detector_improved" },
|
||||||
|
{ "item": "minecraft:gold_ingot" },
|
||||||
|
{ "item": "minecraft:gold_ingot" },
|
||||||
|
{ "item": "minecraft:amethyst_shard" },
|
||||||
|
{ "item": "minecraft:amethyst_shard" }
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"item": "silverlabs:ore_detector_advanced",
|
||||||
|
"count": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:recipe_shaped": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:ore_detector_basic_recipe"
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"crafting_table"
|
||||||
|
],
|
||||||
|
"unlock": [
|
||||||
|
{
|
||||||
|
"item": "minecraft:redstone"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pattern": [
|
||||||
|
" R ",
|
||||||
|
"CSC",
|
||||||
|
" C "
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"R": {
|
||||||
|
"item": "minecraft:redstone"
|
||||||
|
},
|
||||||
|
"C": {
|
||||||
|
"item": "minecraft:cobblestone"
|
||||||
|
},
|
||||||
|
"S": {
|
||||||
|
"item": "minecraft:stick"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "silverlabs:ore_detector_basic",
|
||||||
|
"count": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:recipe_shapeless": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:ore_detector_improved_recipe"
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"crafting_table"
|
||||||
|
],
|
||||||
|
"unlock": [
|
||||||
|
{
|
||||||
|
"item": "silverlabs:ore_detector_basic"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ingredients": [
|
||||||
|
{ "item": "silverlabs:ore_detector_basic" },
|
||||||
|
{ "item": "minecraft:iron_ingot" },
|
||||||
|
{ "item": "minecraft:iron_ingot" },
|
||||||
|
{ "item": "minecraft:iron_ingot" },
|
||||||
|
{ "item": "minecraft:iron_ingot" },
|
||||||
|
{ "item": "minecraft:redstone" }
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"item": "silverlabs:ore_detector_improved",
|
||||||
|
"count": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -703,6 +703,116 @@ function dismantleHammockAt(loc, dimId, player) {
|
|||||||
if (player) player.sendMessage("§7[Camping] Hammock taken down.");
|
if (player) player.sendMessage("§7[Camping] Hammock taken down.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Ore Detector ───────────────────────────────────────────
|
||||||
|
// Three tiered items share one scan handler. Tier → max scan range.
|
||||||
|
// Faraday: any ore within 4 blocks of a silverlabs:private_chest is hidden
|
||||||
|
// (mirrors the source DetectOre faraday-cage mechanic, but built into private chests).
|
||||||
|
const DETECTOR_RANGES = {
|
||||||
|
"silverlabs:ore_detector_basic": 8,
|
||||||
|
"silverlabs:ore_detector_improved": 16,
|
||||||
|
"silverlabs:ore_detector_advanced": 32,
|
||||||
|
};
|
||||||
|
const PRIVATE_CHEST_ID = "silverlabs:private_chest";
|
||||||
|
const FARADAY_RADIUS = 4; // 9³ cube around each ore candidate
|
||||||
|
|
||||||
|
const ORE_IDS = new Set([
|
||||||
|
"minecraft:coal_ore", "minecraft:deepslate_coal_ore",
|
||||||
|
"minecraft:iron_ore", "minecraft:deepslate_iron_ore",
|
||||||
|
"minecraft:copper_ore", "minecraft:deepslate_copper_ore",
|
||||||
|
"minecraft:gold_ore", "minecraft:deepslate_gold_ore", "minecraft:nether_gold_ore",
|
||||||
|
"minecraft:redstone_ore", "minecraft:deepslate_redstone_ore",
|
||||||
|
"minecraft:lit_redstone_ore", "minecraft:lit_deepslate_redstone_ore",
|
||||||
|
"minecraft:lapis_ore", "minecraft:deepslate_lapis_ore",
|
||||||
|
"minecraft:emerald_ore", "minecraft:deepslate_emerald_ore",
|
||||||
|
"minecraft:diamond_ore", "minecraft:deepslate_diamond_ore",
|
||||||
|
"minecraft:nether_quartz_ore",
|
||||||
|
"minecraft:ancient_debris",
|
||||||
|
]);
|
||||||
|
|
||||||
|
function prettyOreName(typeId) {
|
||||||
|
const bare = typeId.replace(/^minecraft:/, "")
|
||||||
|
.replace(/^lit_/, "")
|
||||||
|
.replace(/^deepslate_/, "Deepslate ")
|
||||||
|
.replace(/^nether_/, "Nether ");
|
||||||
|
return bare.split("_").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPrivateChestNearby(dim, cx, cy, cz) {
|
||||||
|
for (let dx = -FARADAY_RADIUS; dx <= FARADAY_RADIUS; dx++) {
|
||||||
|
for (let dy = -FARADAY_RADIUS; dy <= FARADAY_RADIUS; dy++) {
|
||||||
|
for (let dz = -FARADAY_RADIUS; dz <= FARADAY_RADIUS; dz++) {
|
||||||
|
const b = dim.getBlock({ x: cx + dx, y: cy + dy, z: cz + dz });
|
||||||
|
if (b && b.typeId === PRIVATE_CHEST_ID) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function runOreScan(player, range) {
|
||||||
|
const dim = player.dimension;
|
||||||
|
const head = player.getHeadLocation();
|
||||||
|
const dir = player.getViewDirection();
|
||||||
|
|
||||||
|
// Walk integer-block steps along the view ray. Resolution 0.5 blocks
|
||||||
|
// catches ores the cardinal-aligned steps would skip on diagonals.
|
||||||
|
const stepCount = Math.floor(range * 2);
|
||||||
|
const seen = new Set();
|
||||||
|
let foundOre = null;
|
||||||
|
let foundDist = 0;
|
||||||
|
|
||||||
|
for (let i = 1; i <= stepCount; i++) {
|
||||||
|
const t = i * 0.5;
|
||||||
|
const px = head.x + dir.x * t;
|
||||||
|
const py = head.y + dir.y * t;
|
||||||
|
const pz = head.z + dir.z * t;
|
||||||
|
const bx = Math.floor(px);
|
||||||
|
const by = Math.floor(py);
|
||||||
|
const bz = Math.floor(pz);
|
||||||
|
const key = `${bx},${by},${bz}`;
|
||||||
|
if (seen.has(key)) continue;
|
||||||
|
seen.add(key);
|
||||||
|
|
||||||
|
let block;
|
||||||
|
try { block = dim.getBlock({ x: bx, y: by, z: bz }); } catch (_) { continue; }
|
||||||
|
if (!block) continue;
|
||||||
|
|
||||||
|
if (ORE_IDS.has(block.typeId)) {
|
||||||
|
if (isPrivateChestNearby(dim, bx, by, bz)) continue; // faraday
|
||||||
|
foundOre = block.typeId;
|
||||||
|
foundDist = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundOre) {
|
||||||
|
const distRounded = Math.round(foundDist * 10) / 10;
|
||||||
|
const pitch = Math.max(0.8, Math.min(2.0, 2.0 - (foundDist / range)));
|
||||||
|
try {
|
||||||
|
player.playSound("random.orb", { pitch, volume: 0.7 });
|
||||||
|
} catch (_) {}
|
||||||
|
try {
|
||||||
|
player.onScreenDisplay.setActionBar(`§a● §f${prettyOreName(foundOre)} §7at §b${distRounded}m`);
|
||||||
|
} catch (_) {}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
player.playSound("note.bass", { pitch: 0.7, volume: 0.5 });
|
||||||
|
} catch (_) {}
|
||||||
|
try {
|
||||||
|
player.onScreenDisplay.setActionBar(`§7○ No ores within §f${range}m`);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
world.afterEvents.itemUse.subscribe((event) => {
|
||||||
|
const player = event.source;
|
||||||
|
const stack = event.itemStack;
|
||||||
|
if (!stack || !player) return;
|
||||||
|
const range = DETECTOR_RANGES[stack.typeId];
|
||||||
|
if (!range) return;
|
||||||
|
system.run(() => runOreScan(player, range));
|
||||||
|
});
|
||||||
|
|
||||||
// ─── Boot ───────────────────────────────────────────────────
|
// ─── Boot ───────────────────────────────────────────────────
|
||||||
system.run(() => {
|
system.run(() => {
|
||||||
loadState();
|
loadState();
|
||||||
|
|||||||
@@ -4,14 +4,14 @@
|
|||||||
"name": "Camping Supplies Resources",
|
"name": "Camping Supplies Resources",
|
||||||
"description": "Textures and lang for camping supplies (tent, hammock, canvas, cloth)",
|
"description": "Textures and lang for camping supplies (tent, hammock, canvas, cloth)",
|
||||||
"uuid": "36f12107-10c6-484c-a0f2-b5dd88cd5baa",
|
"uuid": "36f12107-10c6-484c-a0f2-b5dd88cd5baa",
|
||||||
"version": [1, 0, 0],
|
"version": [1, 0, 1],
|
||||||
"min_engine_version": [1, 21, 0]
|
"min_engine_version": [1, 21, 0]
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"type": "resources",
|
"type": "resources",
|
||||||
"uuid": "c9ee429f-9374-4083-843b-4b195e8db130",
|
"uuid": "c9ee429f-9374-4083-843b-4b195e8db130",
|
||||||
"version": [1, 0, 0]
|
"version": [1, 0, 1]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
item.silverlabs:tent.name=Tent
|
item.silverlabs:tent.name=Tent
|
||||||
item.silverlabs:hammock.name=Hammock
|
item.silverlabs:hammock.name=Hammock
|
||||||
|
item.silverlabs:ore_detector_basic.name=Ore Detector
|
||||||
|
item.silverlabs:ore_detector_improved.name=Ore Detector (Improved)
|
||||||
|
item.silverlabs:ore_detector_advanced.name=Ore Detector (Advanced)
|
||||||
tile.silverlabs:tent_canvas.name=Tent Canvas
|
tile.silverlabs:tent_canvas.name=Tent Canvas
|
||||||
tile.silverlabs:hammock_cloth.name=Hammock Cloth
|
tile.silverlabs:hammock_cloth.name=Hammock Cloth
|
||||||
|
|||||||
@@ -7,6 +7,15 @@
|
|||||||
},
|
},
|
||||||
"hammock_item": {
|
"hammock_item": {
|
||||||
"textures": "textures/items/hammock"
|
"textures": "textures/items/hammock"
|
||||||
|
},
|
||||||
|
"ore_detector_basic": {
|
||||||
|
"textures": "textures/items/ore_detector_basic"
|
||||||
|
},
|
||||||
|
"ore_detector_improved": {
|
||||||
|
"textures": "textures/items/ore_detector_improved"
|
||||||
|
},
|
||||||
|
"ore_detector_advanced": {
|
||||||
|
"textures": "textures/items/ore_detector_advanced"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
After Width: | Height: | Size: 228 B |
|
After Width: | Height: | Size: 227 B |
|
After Width: | Height: | Size: 227 B |
@@ -61,6 +61,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- jamie-data:/data
|
- jamie-data:/data
|
||||||
- ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP
|
- ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP
|
||||||
|
- ./hub-return-addon/hub_return_transfer_RP:/data/resource_packs/hub_return_transfer_RP
|
||||||
- ./private-chest-addon/private_chest_BP:/data/behavior_packs/private_chest_BP
|
- ./private-chest-addon/private_chest_BP:/data/behavior_packs/private_chest_BP
|
||||||
- ./private-chest-addon/private_chest_RP:/data/resource_packs/private_chest_RP
|
- ./private-chest-addon/private_chest_RP:/data/resource_packs/private_chest_RP
|
||||||
- ./smart-crafting-addon/smart_crafting_BP:/data/behavior_packs/smart_crafting_BP
|
- ./smart-crafting-addon/smart_crafting_BP:/data/behavior_packs/smart_crafting_BP
|
||||||
@@ -76,6 +77,10 @@ services:
|
|||||||
- ./dynamite-addon/dynamite_RP:/data/resource_packs/dynamite_RP
|
- ./dynamite-addon/dynamite_RP:/data/resource_packs/dynamite_RP
|
||||||
- ./tow-boat-addon/tow_boat_BP:/data/behavior_packs/tow_boat_BP
|
- ./tow-boat-addon/tow_boat_BP:/data/behavior_packs/tow_boat_BP
|
||||||
- ./tow-boat-addon/tow_boat_RP:/data/resource_packs/tow_boat_RP
|
- ./tow-boat-addon/tow_boat_RP:/data/resource_packs/tow_boat_RP
|
||||||
|
- ./trees-features-addon/trees_features_BP:/data/behavior_packs/trees_features_BP
|
||||||
|
- ./trees-features-addon/trees_features_RP:/data/resource_packs/trees_features_RP
|
||||||
|
- ./hemp-addon/hemp_BP:/data/behavior_packs/hemp_BP
|
||||||
|
- ./hemp-addon/hemp_RP:/data/resource_packs/hemp_RP
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
mem_limit: 1500m
|
mem_limit: 1500m
|
||||||
memswap_limit: 2500m
|
memswap_limit: 2500m
|
||||||
@@ -94,6 +99,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- lyla-data:/data
|
- lyla-data:/data
|
||||||
- ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP
|
- ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP
|
||||||
|
- ./hub-return-addon/hub_return_transfer_RP:/data/resource_packs/hub_return_transfer_RP
|
||||||
- ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP
|
- ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP
|
||||||
- ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP
|
- ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP
|
||||||
- ./addon/heyhe_pet_BP:/data/behavior_packs/heyhe_pet_BP
|
- ./addon/heyhe_pet_BP:/data/behavior_packs/heyhe_pet_BP
|
||||||
@@ -135,6 +141,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- mya-data:/data
|
- mya-data:/data
|
||||||
- ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP
|
- ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP
|
||||||
|
- ./hub-return-addon/hub_return_transfer_RP:/data/resource_packs/hub_return_transfer_RP
|
||||||
- ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP
|
- ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP
|
||||||
- ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP
|
- ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP
|
||||||
- ./addon/heyhe_pet_BP:/data/behavior_packs/heyhe_pet_BP
|
- ./addon/heyhe_pet_BP:/data/behavior_packs/heyhe_pet_BP
|
||||||
@@ -157,7 +164,13 @@ services:
|
|||||||
- ./dynamite-addon/dynamite_RP:/data/resource_packs/dynamite_RP
|
- ./dynamite-addon/dynamite_RP:/data/resource_packs/dynamite_RP
|
||||||
- ./tow-boat-addon/tow_boat_BP:/data/behavior_packs/tow_boat_BP
|
- ./tow-boat-addon/tow_boat_BP:/data/behavior_packs/tow_boat_BP
|
||||||
- ./tow-boat-addon/tow_boat_RP:/data/resource_packs/tow_boat_RP
|
- ./tow-boat-addon/tow_boat_RP:/data/resource_packs/tow_boat_RP
|
||||||
|
- ./naturalist-lite-addon/naturalist_lite_BP:/data/behavior_packs/naturalist_lite_BP
|
||||||
|
- ./naturalist-lite-addon/naturalist_lite_RP:/data/resource_packs/naturalist_lite_RP
|
||||||
- ./village-evolution-addon/enabled_packs.json:/data/config/default/enabled_packs.json
|
- ./village-evolution-addon/enabled_packs.json:/data/config/default/enabled_packs.json
|
||||||
|
- ./trees-features-addon/trees_features_BP:/data/behavior_packs/trees_features_BP
|
||||||
|
- ./trees-features-addon/trees_features_RP:/data/resource_packs/trees_features_RP
|
||||||
|
- ./hemp-addon/hemp_BP:/data/behavior_packs/hemp_BP
|
||||||
|
- ./hemp-addon/hemp_RP:/data/resource_packs/hemp_RP
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
mem_limit: 1500m
|
mem_limit: 1500m
|
||||||
memswap_limit: 2500m
|
memswap_limit: 2500m
|
||||||
|
|||||||
@@ -4,20 +4,36 @@
|
|||||||
"name": "Dynamite",
|
"name": "Dynamite",
|
||||||
"description": "Throwable explosives: bangers, dynamite sticks, and bundles.",
|
"description": "Throwable explosives: bangers, dynamite sticks, and bundles.",
|
||||||
"uuid": "fac83943-16bc-4790-aa05-631894f59a03",
|
"uuid": "fac83943-16bc-4790-aa05-631894f59a03",
|
||||||
"version": [1, 0, 0],
|
"version": [
|
||||||
"min_engine_version": [1, 21, 0]
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"min_engine_version": [
|
||||||
|
1,
|
||||||
|
21,
|
||||||
|
0
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"type": "data",
|
"type": "data",
|
||||||
"uuid": "1354002c-fdd5-4f7e-b89b-f5dd2c38799c",
|
"uuid": "1354002c-fdd5-4f7e-b89b-f5dd2c38799c",
|
||||||
"version": [1, 0, 0]
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
{
|
{
|
||||||
"uuid": "a18bdde1-53f8-49aa-b06d-6f0ec6c45b46",
|
"uuid": "a18bdde1-53f8-49aa-b06d-6f0ec6c45b46",
|
||||||
"version": [1, 0, 0]
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
12
dynamite-addon/dynamite_RP/entity/thrown_banger.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"minecraft:client_entity": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:thrown_banger",
|
||||||
|
"materials": { "default": "entity_alphatest" },
|
||||||
|
"textures": { "default": "textures/entity/thrown_banger" },
|
||||||
|
"geometry": { "default": "geometry.snowball" },
|
||||||
|
"render_controllers": [ "controller.render.snowball" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
dynamite-addon/dynamite_RP/entity/thrown_bundle.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"minecraft:client_entity": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:thrown_bundle",
|
||||||
|
"materials": { "default": "entity_alphatest" },
|
||||||
|
"textures": { "default": "textures/entity/thrown_bundle" },
|
||||||
|
"geometry": { "default": "geometry.snowball" },
|
||||||
|
"render_controllers": [ "controller.render.snowball" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
dynamite-addon/dynamite_RP/entity/thrown_dynamite.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"minecraft:client_entity": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:thrown_dynamite",
|
||||||
|
"materials": { "default": "entity_alphatest" },
|
||||||
|
"textures": { "default": "textures/entity/thrown_dynamite" },
|
||||||
|
"geometry": { "default": "geometry.snowball" },
|
||||||
|
"render_controllers": [ "controller.render.snowball" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,14 +4,14 @@
|
|||||||
"name": "Dynamite Resources",
|
"name": "Dynamite Resources",
|
||||||
"description": "Textures and language for the Dynamite addon.",
|
"description": "Textures and language for the Dynamite addon.",
|
||||||
"uuid": "a18bdde1-53f8-49aa-b06d-6f0ec6c45b46",
|
"uuid": "a18bdde1-53f8-49aa-b06d-6f0ec6c45b46",
|
||||||
"version": [1, 0, 0],
|
"version": [1, 0, 2],
|
||||||
"min_engine_version": [1, 21, 0]
|
"min_engine_version": [1, 21, 0]
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"type": "resources",
|
"type": "resources",
|
||||||
"uuid": "587281f2-f159-4ad9-85a6-d20ff4899717",
|
"uuid": "587281f2-f159-4ad9-85a6-d20ff4899717",
|
||||||
"version": [1, 0, 0]
|
"version": [1, 0, 2]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
dynamite-addon/dynamite_RP/textures/entity/thrown_banger.png
Normal file
|
After Width: | Height: | Size: 298 B |
BIN
dynamite-addon/dynamite_RP/textures/entity/thrown_bundle.png
Normal file
|
After Width: | Height: | Size: 544 B |
BIN
dynamite-addon/dynamite_RP/textures/entity/thrown_dynamite.png
Normal file
|
After Width: | Height: | Size: 372 B |
74
hemp-addon/hemp_BP/blocks/hemp_crop.json
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:block": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:hemp_crop",
|
||||||
|
"menu_category": { "category": "nature" },
|
||||||
|
"states": {
|
||||||
|
"silverlabs:hemp_age": { "values": { "min": 0, "max": 5 } },
|
||||||
|
"silverlabs:hemp_top": { "values": [false, true] }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"minecraft:destructible_by_mining": { "seconds_to_destroy": 0.1 },
|
||||||
|
"minecraft:destructible_by_explosion": { "explosion_resistance": 0.1 },
|
||||||
|
"minecraft:flammable": { "destroy_chance_modifier": 60, "catch_chance_modifier": 60 },
|
||||||
|
"minecraft:light_dampening": 0,
|
||||||
|
"minecraft:map_color": "#5d8a3c",
|
||||||
|
"minecraft:collision_box": false,
|
||||||
|
"minecraft:selection_box": { "origin": [-6, 0, -6], "size": [12, 14, 12] },
|
||||||
|
"minecraft:geometry": "minecraft:geometry.cross",
|
||||||
|
"minecraft:material_instances": {
|
||||||
|
"*": {
|
||||||
|
"texture": "hemp_crop_0",
|
||||||
|
"render_method": "alpha_test",
|
||||||
|
"ambient_occlusion": false,
|
||||||
|
"face_dimming": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minecraft:loot": "loot_tables/blocks/hemp_crop.json"
|
||||||
|
},
|
||||||
|
"permutations": [
|
||||||
|
{
|
||||||
|
"condition": "query.block_state('silverlabs:hemp_age') == 1",
|
||||||
|
"components": {
|
||||||
|
"minecraft:material_instances": {
|
||||||
|
"*": { "texture": "hemp_crop_1", "render_method": "alpha_test", "ambient_occlusion": false, "face_dimming": false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"condition": "query.block_state('silverlabs:hemp_age') == 2",
|
||||||
|
"components": {
|
||||||
|
"minecraft:material_instances": {
|
||||||
|
"*": { "texture": "hemp_crop_2", "render_method": "alpha_test", "ambient_occlusion": false, "face_dimming": false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"condition": "query.block_state('silverlabs:hemp_age') == 3",
|
||||||
|
"components": {
|
||||||
|
"minecraft:material_instances": {
|
||||||
|
"*": { "texture": "hemp_crop_3", "render_method": "alpha_test", "ambient_occlusion": false, "face_dimming": false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"condition": "query.block_state('silverlabs:hemp_age') == 4",
|
||||||
|
"components": {
|
||||||
|
"minecraft:material_instances": {
|
||||||
|
"*": { "texture": "hemp_crop_4", "render_method": "alpha_test", "ambient_occlusion": false, "face_dimming": false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"condition": "query.block_state('silverlabs:hemp_age') == 5",
|
||||||
|
"components": {
|
||||||
|
"minecraft:material_instances": {
|
||||||
|
"*": { "texture": "hemp_crop_5", "render_method": "alpha_test", "ambient_occlusion": false, "face_dimming": false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
50
hemp-addon/hemp_BP/blocks/sun_lamp.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:block": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:sun_lamp",
|
||||||
|
"menu_category": {
|
||||||
|
"category": "items"
|
||||||
|
},
|
||||||
|
"states": {
|
||||||
|
"silverlabs:powered": [
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"minecraft:destructible_by_mining": {
|
||||||
|
"seconds_to_destroy": 0.3
|
||||||
|
},
|
||||||
|
"minecraft:destructible_by_explosion": {
|
||||||
|
"explosion_resistance": 0.5
|
||||||
|
},
|
||||||
|
"minecraft:map_color": "#ffd24d",
|
||||||
|
"minecraft:light_emission": 0,
|
||||||
|
"minecraft:geometry": "minecraft:geometry.full_block",
|
||||||
|
"minecraft:material_instances": {
|
||||||
|
"*": {
|
||||||
|
"texture": "sun_lamp_off",
|
||||||
|
"render_method": "opaque"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permutations": [
|
||||||
|
{
|
||||||
|
"condition": "query.block_state('silverlabs:powered') == true",
|
||||||
|
"components": {
|
||||||
|
"minecraft:light_emission": 15,
|
||||||
|
"minecraft:light_dampening": 0,
|
||||||
|
"minecraft:geometry": "minecraft:geometry.full_block",
|
||||||
|
"minecraft:material_instances": {
|
||||||
|
"*": {
|
||||||
|
"texture": "sun_lamp",
|
||||||
|
"render_method": "opaque"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
25
hemp-addon/hemp_BP/items/hemp_brownie.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:item": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:hemp_brownie",
|
||||||
|
"menu_category": {
|
||||||
|
"category": "nature"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"minecraft:icon": "hemp_brownie",
|
||||||
|
"minecraft:max_stack_size": 16,
|
||||||
|
"minecraft:use_animation": "eat",
|
||||||
|
"minecraft:use_modifiers": {
|
||||||
|
"use_duration": 1.6,
|
||||||
|
"movement_modifier": 0.35
|
||||||
|
},
|
||||||
|
"minecraft:food": {
|
||||||
|
"nutrition": 4,
|
||||||
|
"saturation_modifier": 0.6,
|
||||||
|
"can_always_eat": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
hemp-addon/hemp_BP/items/hemp_bud.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:item": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:hemp_bud",
|
||||||
|
"menu_category": {
|
||||||
|
"category": "nature"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"minecraft:icon": "hemp_bud",
|
||||||
|
"minecraft:max_stack_size": 64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
hemp-addon/hemp_BP/items/hemp_seeds.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:item": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:hemp_seeds",
|
||||||
|
"menu_category": {
|
||||||
|
"category": "nature",
|
||||||
|
"group": "itemGroup.name.seed"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"minecraft:icon": "hemp_seeds",
|
||||||
|
"minecraft:max_stack_size": 64,
|
||||||
|
"minecraft:block_placer": {
|
||||||
|
"block": "silverlabs:hemp_crop",
|
||||||
|
"use_on": [
|
||||||
|
"minecraft:dirt",
|
||||||
|
"minecraft:grass_block",
|
||||||
|
"minecraft:farmland",
|
||||||
|
"minecraft:podzol",
|
||||||
|
"minecraft:coarse_dirt",
|
||||||
|
"minecraft:rooted_dirt",
|
||||||
|
"minecraft:moss_block",
|
||||||
|
"minecraft:flower_pot"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
hemp-addon/hemp_BP/items/hemp_tincture.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:item": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:hemp_tincture",
|
||||||
|
"menu_category": {
|
||||||
|
"category": "nature"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"minecraft:icon": "hemp_tincture",
|
||||||
|
"minecraft:max_stack_size": 16,
|
||||||
|
"minecraft:use_animation": "drink",
|
||||||
|
"minecraft:use_modifiers": {
|
||||||
|
"use_duration": 1.5,
|
||||||
|
"movement_modifier": 0.35
|
||||||
|
},
|
||||||
|
"minecraft:food": {
|
||||||
|
"nutrition": 1,
|
||||||
|
"saturation_modifier": 0.1,
|
||||||
|
"can_always_eat": true,
|
||||||
|
"using_converts_to": "minecraft:glass_bottle"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
hemp-addon/hemp_BP/loot_tables/blocks/hemp_crop.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"pools": [
|
||||||
|
{
|
||||||
|
"rolls": 1,
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"type": "item",
|
||||||
|
"name": "silverlabs:hemp_seeds",
|
||||||
|
"weight": 1,
|
||||||
|
"functions": [
|
||||||
|
{ "function": "set_count", "count": { "min": 0, "max": 1 } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
54
hemp-addon/hemp_BP/manifest.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"format_version": 2,
|
||||||
|
"header": {
|
||||||
|
"name": "Hemp Plant",
|
||||||
|
"description": "Plantable hemp crop with sheers harvesting, cauldron tincture, brownie food, sun-lamp block",
|
||||||
|
"uuid": "910fafaf-bcb0-4f1a-8a05-bd235a537c3b",
|
||||||
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"min_engine_version": [
|
||||||
|
1,
|
||||||
|
21,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
{
|
||||||
|
"type": "data",
|
||||||
|
"uuid": "a10b077f-703b-46b6-b45e-71ee2044c07c",
|
||||||
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "script",
|
||||||
|
"language": "javascript",
|
||||||
|
"uuid": "6e6ef947-60fc-49d2-97c1-b3cab6661ece",
|
||||||
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"entry": "scripts/main.js"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"module_name": "@minecraft/server",
|
||||||
|
"version": "1.17.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uuid": "8e5c46ac-3b16-4f51-89f7-673bd06600f4",
|
||||||
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
24
hemp-addon/hemp_BP/recipes/hemp_brownie.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:recipe_shapeless": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:hemp_brownie_recipe"
|
||||||
|
},
|
||||||
|
"tags": ["crafting_table"],
|
||||||
|
"unlock": [
|
||||||
|
{ "item": "silverlabs:hemp_bud" },
|
||||||
|
{ "item": "minecraft:cocoa_beans" }
|
||||||
|
],
|
||||||
|
"ingredients": [
|
||||||
|
{ "item": "silverlabs:hemp_bud" },
|
||||||
|
{ "item": "silverlabs:hemp_bud" },
|
||||||
|
{ "item": "minecraft:cocoa_beans" },
|
||||||
|
{ "item": "minecraft:wheat" },
|
||||||
|
{ "item": "minecraft:sugar" }
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"item": "silverlabs:hemp_brownie",
|
||||||
|
"count": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
hemp-addon/hemp_BP/recipes/sun_lamp.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.21.0",
|
||||||
|
"minecraft:recipe_shaped": {
|
||||||
|
"description": {
|
||||||
|
"identifier": "silverlabs:sun_lamp_recipe"
|
||||||
|
},
|
||||||
|
"tags": ["crafting_table"],
|
||||||
|
"unlock": [
|
||||||
|
{ "item": "minecraft:glowstone" }
|
||||||
|
],
|
||||||
|
"pattern": [
|
||||||
|
"WIW",
|
||||||
|
"IGI",
|
||||||
|
"WIW"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"W": { "item": "minecraft:yellow_wool" },
|
||||||
|
"I": { "item": "minecraft:iron_nugget" },
|
||||||
|
"G": { "item": "minecraft:glowstone" }
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "silverlabs:sun_lamp",
|
||||||
|
"count": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
686
hemp-addon/hemp_BP/scripts/main.js
Normal file
@@ -0,0 +1,686 @@
|
|||||||
|
import { world, system, ItemStack, BlockPermutation } from "@minecraft/server";
|
||||||
|
|
||||||
|
const CROP = "silverlabs:hemp_crop";
|
||||||
|
const SUN_LAMP = "silverlabs:sun_lamp";
|
||||||
|
const SEEDS = "silverlabs:hemp_seeds";
|
||||||
|
const BUD = "silverlabs:hemp_bud";
|
||||||
|
const TINCTURE = "silverlabs:hemp_tincture";
|
||||||
|
const BROWNIE = "silverlabs:hemp_brownie";
|
||||||
|
|
||||||
|
const AGE = "silverlabs:hemp_age";
|
||||||
|
const TOP = "silverlabs:hemp_top";
|
||||||
|
|
||||||
|
const GROWTH_INTERVAL_TICKS = 100; // 5s between growth ticks
|
||||||
|
const RABBIT_INTERVAL_TICKS = 100; // 5s between rabbit checks
|
||||||
|
const SCAN_RADIUS = 5; // ±5 horizontal — dense scan, every block looked at
|
||||||
|
const SCAN_VERT = 2; // ±2 vertical
|
||||||
|
const SUN_LAMP_RANGE = 4; // blocks searched for a lamp around indoor crop
|
||||||
|
const GROWTH_CHANCE_OUTDOOR = 0.017; // per 5s tick — ~20 min for 0→4 (prime)
|
||||||
|
const GROWTH_CHANCE_INDOOR = 0.011; // per 5s tick — ~30 min for 0→4 (sun lamp required)
|
||||||
|
const OVERRIPE_CHANCE_MULT = 0.33; // age 4→5 transition is 3x slower so prime lingers
|
||||||
|
|
||||||
|
function rand(n) { return Math.floor(Math.random() * n); }
|
||||||
|
function chance(p) { return Math.random() < p; }
|
||||||
|
function clamp(v, lo, hi) { return Math.max(lo, Math.min(hi, v)); }
|
||||||
|
|
||||||
|
function getInv(player) {
|
||||||
|
return player.getComponent("minecraft:inventory")?.container ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function consumeOneOfType(player, typeId) {
|
||||||
|
const inv = getInv(player);
|
||||||
|
if (!inv) return false;
|
||||||
|
const sel = player.selectedSlotIndex;
|
||||||
|
const cur = inv.getItem(sel);
|
||||||
|
if (cur && cur.typeId === typeId) {
|
||||||
|
if (cur.amount > 1) { cur.amount -= 1; inv.setItem(sel, cur); }
|
||||||
|
else inv.setItem(sel, undefined);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < inv.size; i++) {
|
||||||
|
const it = inv.getItem(i);
|
||||||
|
if (it && it.typeId === typeId) {
|
||||||
|
if (it.amount > 1) { it.amount -= 1; inv.setItem(i, it); }
|
||||||
|
else inv.setItem(i, undefined);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function giveItem(player, typeId, count = 1) {
|
||||||
|
const inv = getInv(player);
|
||||||
|
if (!inv) return false;
|
||||||
|
try {
|
||||||
|
inv.addItem(new ItemStack(typeId, count));
|
||||||
|
return true;
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block ids that don't block sky access — the plant grows around these like
|
||||||
|
// a vanilla tree pushes through leaves. Anything else above stops growth.
|
||||||
|
function isSkyTransparent(typeId) {
|
||||||
|
if (!typeId) return true;
|
||||||
|
if (typeId === CROP) return true; // ignore our own top half
|
||||||
|
if (typeId === "minecraft:air") return true;
|
||||||
|
// Glass / panes / bars
|
||||||
|
if (typeId.includes("glass")) return true;
|
||||||
|
if (typeId === "minecraft:iron_bars") return true;
|
||||||
|
// Leaves and saplings (canopy-style obstructions)
|
||||||
|
if (typeId.includes("leaves")) return true;
|
||||||
|
if (typeId.includes("sapling")) return true;
|
||||||
|
// Other plants / vines / hanging stuff
|
||||||
|
if (typeId === "minecraft:vine" || typeId === "minecraft:weeping_vines"
|
||||||
|
|| typeId === "minecraft:twisting_vines") return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAirAbove(dim, loc) {
|
||||||
|
// Walk up from y+1; sky-transparent blocks don't count as obstructions.
|
||||||
|
for (let dy = 1; dy < 64; dy++) {
|
||||||
|
let b;
|
||||||
|
try { b = dim.getBlock({ x: loc.x, y: loc.y + dy, z: loc.z }); } catch (_) { return true; }
|
||||||
|
if (!b) return true;
|
||||||
|
if (b.isAir || b.isLiquid) continue;
|
||||||
|
if (isSkyTransparent(b.typeId)) continue;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findSunLampNear(dim, loc) {
|
||||||
|
const r = SUN_LAMP_RANGE;
|
||||||
|
for (let dy = -1; dy <= r; dy++) {
|
||||||
|
for (let dx = -r; dx <= r; dx++) {
|
||||||
|
for (let dz = -r; dz <= r; dz++) {
|
||||||
|
let b;
|
||||||
|
try { b = dim.getBlock({ x: loc.x + dx, y: loc.y + dy, z: loc.z + dz }); } catch (_) { continue; }
|
||||||
|
if (b && b.typeId === SUN_LAMP) {
|
||||||
|
try {
|
||||||
|
if (b.permutation.getState("silverlabs:powered") === true) return true;
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAge(block, newAge, outdoor) {
|
||||||
|
try {
|
||||||
|
const perm = BlockPermutation.resolve(CROP, {
|
||||||
|
[AGE]: clamp(newAge, 0, 5),
|
||||||
|
[TOP]: false,
|
||||||
|
});
|
||||||
|
block.setPermutation(perm);
|
||||||
|
if (outdoor && newAge >= 3) {
|
||||||
|
// Place top half above for the visual "tall outdoor crop"
|
||||||
|
const above = block.dimension.getBlock({ x: block.location.x, y: block.location.y + 1, z: block.location.z });
|
||||||
|
if (above && above.isAir) {
|
||||||
|
try {
|
||||||
|
const topPerm = BlockPermutation.resolve(CROP, { [AGE]: clamp(newAge, 0, 5), [TOP]: true });
|
||||||
|
above.setPermutation(topPerm);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearTopAbove(block) {
|
||||||
|
const above = block.dimension.getBlock({ x: block.location.x, y: block.location.y + 1, z: block.location.z });
|
||||||
|
if (above && above.typeId === CROP) {
|
||||||
|
try { above.setType("minecraft:air"); } catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Growth: dense scan of an 11×11×5 box around each player ---
|
||||||
|
// Every hemp_crop base in range gets a roll on every tick — no random sampling.
|
||||||
|
system.runInterval(() => {
|
||||||
|
for (const player of world.getAllPlayers()) {
|
||||||
|
const dim = player.dimension;
|
||||||
|
const px = Math.floor(player.location.x);
|
||||||
|
const py = Math.floor(player.location.y);
|
||||||
|
const pz = Math.floor(player.location.z);
|
||||||
|
for (let dy = -SCAN_VERT; dy <= SCAN_VERT; dy++) {
|
||||||
|
for (let dx = -SCAN_RADIUS; dx <= SCAN_RADIUS; dx++) {
|
||||||
|
for (let dz = -SCAN_RADIUS; dz <= SCAN_RADIUS; dz++) {
|
||||||
|
let b;
|
||||||
|
try { b = dim.getBlock({ x: px + dx, y: py + dy, z: pz + dz }); } catch (_) { continue; }
|
||||||
|
if (!b || b.typeId !== CROP) continue;
|
||||||
|
if (b.permutation.getState(TOP) === true) continue; // only base ticks
|
||||||
|
const age = b.permutation.getState(AGE) ?? 0;
|
||||||
|
if (age >= 5) continue; // overripe stops
|
||||||
|
const outdoor = isAirAbove(dim, b.location);
|
||||||
|
let baseChance = 0;
|
||||||
|
if (outdoor) baseChance = GROWTH_CHANCE_OUTDOOR;
|
||||||
|
else if (findSunLampNear(dim, b.location)) baseChance = GROWTH_CHANCE_INDOOR;
|
||||||
|
else continue;
|
||||||
|
// Prime (age 4) lingers — slow the transition into overripe
|
||||||
|
const c = age === 4 ? baseChance * OVERRIPE_CHANCE_MULT : baseChance;
|
||||||
|
if (chance(c)) setAge(b, age + 1, outdoor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, GROWTH_INTERVAL_TICKS);
|
||||||
|
|
||||||
|
// --- Redstone power: scan known sources adjacent to a sun_lamp ---
|
||||||
|
const REDSTONE_FACES = [
|
||||||
|
[1, 0, 0], [-1, 0, 0],
|
||||||
|
[0, 1, 0], [0, -1, 0],
|
||||||
|
[0, 0, 1], [0, 0, -1],
|
||||||
|
];
|
||||||
|
function isPowerSource(b) {
|
||||||
|
if (!b) return false;
|
||||||
|
const t = b.typeId;
|
||||||
|
if (t === "minecraft:redstone_block") return true;
|
||||||
|
if (t === "minecraft:lit_redstone_torch" || t === "minecraft:redstone_torch") {
|
||||||
|
// torch lit state
|
||||||
|
try { return b.permutation.getState("toggle_bit") !== false; } catch (_) {}
|
||||||
|
return t === "minecraft:lit_redstone_torch";
|
||||||
|
}
|
||||||
|
if (t === "minecraft:powered_repeater") return true;
|
||||||
|
if (t === "minecraft:powered_comparator") return true;
|
||||||
|
if (t === "minecraft:lever") {
|
||||||
|
try { return b.permutation.getState("open_bit") === true; } catch (_) { return false; }
|
||||||
|
}
|
||||||
|
if (t.endsWith("_button") || t.includes(":wooden_button") || t.includes(":stone_button")) {
|
||||||
|
try { return b.permutation.getState("button_pressed_bit") === true; } catch (_) { return false; }
|
||||||
|
}
|
||||||
|
if (t === "minecraft:redstone_wire") {
|
||||||
|
try {
|
||||||
|
const p = b.permutation.getState("redstone_signal") ?? 0;
|
||||||
|
return p > 0;
|
||||||
|
} catch (_) { return false; }
|
||||||
|
}
|
||||||
|
if (t === "minecraft:daylight_detector_inverted") return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function lampShouldBePowered(lamp) {
|
||||||
|
// Try the script API redstone power first (newer servers expose it)
|
||||||
|
try {
|
||||||
|
const p = lamp.getRedstonePower();
|
||||||
|
if (typeof p === "number" && p > 0) return true;
|
||||||
|
} catch (_) {}
|
||||||
|
const dim = lamp.dimension;
|
||||||
|
for (const [dx, dy, dz] of REDSTONE_FACES) {
|
||||||
|
let n;
|
||||||
|
try { n = dim.getBlock({ x: lamp.location.x + dx, y: lamp.location.y + dy, z: lamp.location.z + dz }); } catch (_) { continue; }
|
||||||
|
if (isPowerSource(n)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LAMP_SCAN_INTERVAL_TICKS = 20; // 1s
|
||||||
|
system.runInterval(() => {
|
||||||
|
for (const player of world.getAllPlayers()) {
|
||||||
|
const dim = player.dimension;
|
||||||
|
const px = Math.floor(player.location.x);
|
||||||
|
const py = Math.floor(player.location.y);
|
||||||
|
const pz = Math.floor(player.location.z);
|
||||||
|
for (let dy = -SCAN_VERT; dy <= SCAN_VERT; dy++) {
|
||||||
|
for (let dx = -SCAN_RADIUS; dx <= SCAN_RADIUS; dx++) {
|
||||||
|
for (let dz = -SCAN_RADIUS; dz <= SCAN_RADIUS; dz++) {
|
||||||
|
let b;
|
||||||
|
try { b = dim.getBlock({ x: px + dx, y: py + dy, z: pz + dz }); } catch (_) { continue; }
|
||||||
|
if (!b || b.typeId !== SUN_LAMP) continue;
|
||||||
|
let cur = false;
|
||||||
|
try { cur = b.permutation.getState("silverlabs:powered") === true; } catch (_) {}
|
||||||
|
const want = lampShouldBePowered(b);
|
||||||
|
if (cur !== want) {
|
||||||
|
try {
|
||||||
|
const perm = BlockPermutation.resolve(SUN_LAMP, { "silverlabs:powered": want });
|
||||||
|
b.setPermutation(perm);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, LAMP_SCAN_INTERVAL_TICKS);
|
||||||
|
|
||||||
|
// --- Rabbit threat: damage outdoor hemp ---
|
||||||
|
system.runInterval(() => {
|
||||||
|
for (const player of world.getAllPlayers()) {
|
||||||
|
const dim = player.dimension;
|
||||||
|
let rabbits;
|
||||||
|
try {
|
||||||
|
rabbits = dim.getEntities({ type: "minecraft:rabbit", location: player.location, maxDistance: 48 });
|
||||||
|
} catch (_) { continue; }
|
||||||
|
for (const rabbit of rabbits) {
|
||||||
|
// For each rabbit, look at a small box around its feet for hemp_crop.
|
||||||
|
const rx = Math.floor(rabbit.location.x);
|
||||||
|
const ry = Math.floor(rabbit.location.y);
|
||||||
|
const rz = Math.floor(rabbit.location.z);
|
||||||
|
for (let dx = -1; dx <= 1; dx++) {
|
||||||
|
for (let dz = -1; dz <= 1; dz++) {
|
||||||
|
let b;
|
||||||
|
try { b = dim.getBlock({ x: rx + dx, y: ry, z: rz + dz }); } catch (_) { continue; }
|
||||||
|
if (!b || b.typeId !== CROP) continue;
|
||||||
|
const isTop = b.permutation.getState(TOP) === true;
|
||||||
|
if (isTop) continue;
|
||||||
|
if (chance(0.35)) {
|
||||||
|
const age = b.permutation.getState(AGE) ?? 0;
|
||||||
|
if (age <= 0) {
|
||||||
|
clearTopAbove(b);
|
||||||
|
try { b.setType("minecraft:air"); } catch (_) {}
|
||||||
|
} else {
|
||||||
|
clearTopAbove(b);
|
||||||
|
setAge(b, age - 1, isAirAbove(dim, b.location));
|
||||||
|
}
|
||||||
|
try { dim.runCommand(`particle minecraft:crit_particle ${rx + dx + 0.5} ${ry + 0.5} ${rz + dz + 0.5}`); } catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, RABBIT_INTERVAL_TICKS);
|
||||||
|
|
||||||
|
// --- Pillager raid threat: illagers carrying a banner steal hemp during raids ---
|
||||||
|
// Gate on either an active raid (detected via a nearby ominous_banner) or a
|
||||||
|
// pillager_captain so isolated tower pillagers don't constantly cull farms
|
||||||
|
// in render distance. When triggered, drops the crop's age by 1 (or removes
|
||||||
|
// it if age 0) and spawns 1 hemp_bud at the illager's feet so the player
|
||||||
|
// can recover the loot by killing the raider.
|
||||||
|
const RAID_INTERVAL_TICKS = 100;
|
||||||
|
const ILLAGER_TYPES = new Set([
|
||||||
|
"minecraft:pillager",
|
||||||
|
"minecraft:vindicator",
|
||||||
|
"minecraft:evocation_illager",
|
||||||
|
]);
|
||||||
|
const ILLAGER_HEMP_STEAL_CHANCE = 0.30;
|
||||||
|
|
||||||
|
function illagerIsRaiding(dim, ill) {
|
||||||
|
// Cheapest: check if the illager is wearing/carrying an ominous_banner
|
||||||
|
// (raid captain marker). Also accept any nearby ominous_banner block within
|
||||||
|
// 8 blocks as evidence of an ongoing raid the illager is participating in.
|
||||||
|
const equip = (() => { try { return ill.getComponent("minecraft:equippable"); } catch (_) { return null; } })();
|
||||||
|
if (equip) {
|
||||||
|
try {
|
||||||
|
const head = equip.getEquipmentSlot("Head")?.getItem();
|
||||||
|
if (head && head.typeId === "minecraft:ominous_banner") return true;
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
const ix = Math.floor(ill.location.x);
|
||||||
|
const iy = Math.floor(ill.location.y);
|
||||||
|
const iz = Math.floor(ill.location.z);
|
||||||
|
for (let dx = -8; dx <= 8; dx += 4) {
|
||||||
|
for (let dz = -8; dz <= 8; dz += 4) {
|
||||||
|
let b;
|
||||||
|
try { b = dim.getBlock({ x: ix + dx, y: iy, z: iz + dz }); } catch (_) { continue; }
|
||||||
|
if (b && (b.typeId === "minecraft:standing_banner" || b.typeId === "minecraft:wall_banner")) {
|
||||||
|
// Banners can be ominous via their NBT; we can't read it, so any banner
|
||||||
|
// within 8 blocks of an illager is treated as raid evidence. Still rare.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
system.runInterval(() => {
|
||||||
|
for (const player of world.getAllPlayers()) {
|
||||||
|
const dim = player.dimension;
|
||||||
|
let illagers;
|
||||||
|
try {
|
||||||
|
illagers = dim.getEntities({ families: [], location: player.location, maxDistance: 48 });
|
||||||
|
} catch (_) { continue; }
|
||||||
|
for (const ill of illagers) {
|
||||||
|
if (!ILLAGER_TYPES.has(ill.typeId)) continue;
|
||||||
|
if (!illagerIsRaiding(dim, ill)) continue;
|
||||||
|
const ix = Math.floor(ill.location.x);
|
||||||
|
const iy = Math.floor(ill.location.y);
|
||||||
|
const iz = Math.floor(ill.location.z);
|
||||||
|
for (let dx = -1; dx <= 1; dx++) {
|
||||||
|
for (let dz = -1; dz <= 1; dz++) {
|
||||||
|
let b;
|
||||||
|
try { b = dim.getBlock({ x: ix + dx, y: iy, z: iz + dz }); } catch (_) { continue; }
|
||||||
|
if (!b || b.typeId !== CROP) continue;
|
||||||
|
if (b.permutation.getState(TOP) === true) continue;
|
||||||
|
if (!chance(ILLAGER_HEMP_STEAL_CHANCE)) continue;
|
||||||
|
const age = b.permutation.getState(AGE) ?? 0;
|
||||||
|
const outdoor = isAirAbove(dim, b.location);
|
||||||
|
if (age <= 0) {
|
||||||
|
clearTopAbove(b);
|
||||||
|
try { b.setType("minecraft:air"); } catch (_) {}
|
||||||
|
} else {
|
||||||
|
clearTopAbove(b);
|
||||||
|
setAge(b, age - 1, outdoor);
|
||||||
|
}
|
||||||
|
// Drop a hemp_bud at the illager's feet — recoverable when killed.
|
||||||
|
spawnDrop(dim, ill.location, BUD, 1);
|
||||||
|
try { dim.runCommand(`particle minecraft:villager_angry ${ix + 0.5} ${iy + 1.0} ${iz + 0.5}`); } catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, RAID_INTERVAL_TICKS);
|
||||||
|
|
||||||
|
// --- Wandering trader buyback: hand off hemp products for emeralds ---
|
||||||
|
// Right-click a wandering_trader while holding hemp_bud / hemp_tincture /
|
||||||
|
// hemp_seeds. Avoids overriding vanilla trade tables (which would pin us to
|
||||||
|
// one Bedrock version) by acting as an off-menu interaction. Trader animates
|
||||||
|
// a "happy villager" particle and the player's inventory swaps the items
|
||||||
|
// for emeralds at the rates below.
|
||||||
|
const TRADER_BUYBACK = {
|
||||||
|
[BUD]: { perTrade: 2, emeralds: 1 },
|
||||||
|
[TINCTURE]: { perTrade: 1, emeralds: 3 },
|
||||||
|
[SEEDS]: { perTrade: 8, emeralds: 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
world.beforeEvents.playerInteractWithEntity.subscribe((event) => {
|
||||||
|
const target = event.target;
|
||||||
|
if (!target || target.typeId !== "minecraft:wandering_trader") return;
|
||||||
|
const stack = event.itemStack;
|
||||||
|
if (!stack) return;
|
||||||
|
const deal = TRADER_BUYBACK[stack.typeId];
|
||||||
|
if (!deal) return;
|
||||||
|
event.cancel = true; // suppress the vanilla trade window for this interaction
|
||||||
|
const player = event.player;
|
||||||
|
system.run(() => {
|
||||||
|
// Count what the player has of this item across the inventory
|
||||||
|
const inv = getInv(player);
|
||||||
|
if (!inv) return;
|
||||||
|
let have = 0;
|
||||||
|
for (let i = 0; i < inv.size; i++) {
|
||||||
|
const it = inv.getItem(i);
|
||||||
|
if (it && it.typeId === stack.typeId) have += it.amount;
|
||||||
|
}
|
||||||
|
if (have < deal.perTrade) {
|
||||||
|
player.sendMessage(`§7[Trader] Brings me at least §f${deal.perTrade}§7 of those and I'll pay you in emeralds.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const trades = Math.floor(have / deal.perTrade);
|
||||||
|
let consumed = 0;
|
||||||
|
for (let n = 0; n < trades * deal.perTrade; n++) {
|
||||||
|
if (!consumeOneOfType(player, stack.typeId)) break;
|
||||||
|
consumed++;
|
||||||
|
}
|
||||||
|
const actualTrades = Math.floor(consumed / deal.perTrade);
|
||||||
|
if (actualTrades <= 0) return;
|
||||||
|
giveItem(player, "minecraft:emerald", actualTrades * deal.emeralds);
|
||||||
|
const loc = target.location;
|
||||||
|
try { target.dimension.runCommand(`particle minecraft:villager_happy ${loc.x} ${loc.y + 1.5} ${loc.z}`); } catch (_) {}
|
||||||
|
try { target.dimension.runCommand(`playsound mob.villager.yes @a ${loc.x} ${loc.y} ${loc.z} 0.8 1.1`); } catch (_) {}
|
||||||
|
player.sendMessage(`§a[Trader] §fTraded §e${actualTrades * deal.perTrade}§f for §a${actualTrades * deal.emeralds} emerald${actualTrades * deal.emeralds === 1 ? "" : "s"}§f.`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- Outdoor detection on placement ---
|
||||||
|
world.afterEvents.playerPlaceBlock.subscribe((event) => {
|
||||||
|
const block = event.block;
|
||||||
|
if (!block || block.typeId !== CROP) return;
|
||||||
|
// newly-placed crop is age 0 by default — we don't need to set anything,
|
||||||
|
// outdoor status is computed live during ticks.
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- Cleanup: breaking either half of a tall plant removes the other ---
|
||||||
|
// Also: rare hemp_seeds drop from breaking vanilla grass / tall_grass /
|
||||||
|
// short_grass — gives players a way to bootstrap into hemp without
|
||||||
|
// already having seeds. Mirrors how vanilla wheat seeds work.
|
||||||
|
const GRASS_BLOCK_IDS = new Set([
|
||||||
|
"minecraft:short_grass",
|
||||||
|
"minecraft:tall_grass",
|
||||||
|
"minecraft:fern",
|
||||||
|
"minecraft:large_fern",
|
||||||
|
// Pre-1.21 alias kept for safety on mixed-version worlds
|
||||||
|
"minecraft:grass",
|
||||||
|
]);
|
||||||
|
const GRASS_HEMP_SEED_CHANCE = 0.04; // ~1 in 25 grass tufts
|
||||||
|
|
||||||
|
world.afterEvents.playerBreakBlock.subscribe((event) => {
|
||||||
|
const brokenType = event.brokenBlockPermutation?.type?.id;
|
||||||
|
|
||||||
|
// Hemp_crop tall-plant cleanup
|
||||||
|
if (brokenType === CROP) {
|
||||||
|
const block = event.block;
|
||||||
|
const dim = block.dimension;
|
||||||
|
const wasTop = event.brokenBlockPermutation.getState(TOP) === true;
|
||||||
|
const dy = wasTop ? -1 : 1;
|
||||||
|
let neighbor;
|
||||||
|
try { neighbor = dim.getBlock({ x: block.location.x, y: block.location.y + dy, z: block.location.z }); } catch (_) { return; }
|
||||||
|
if (!neighbor || neighbor.typeId !== CROP) return;
|
||||||
|
const neighborIsTop = neighbor.permutation.getState(TOP) === true;
|
||||||
|
if (wasTop === neighborIsTop) return;
|
||||||
|
try { neighbor.setType("minecraft:air"); } catch (_) {}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hemp seed bootstrap from grass blocks
|
||||||
|
if (brokenType && GRASS_BLOCK_IDS.has(brokenType)) {
|
||||||
|
if (!chance(GRASS_HEMP_SEED_CHANCE)) return;
|
||||||
|
const block = event.block;
|
||||||
|
const loc = block.location;
|
||||||
|
spawnDrop(block.dimension, loc, SEEDS, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Per-player debounce so a single click that fires the event twice
|
||||||
|
// (a known Bedrock quirk for some interact paths) only does work once.
|
||||||
|
const recentInteract = new Map(); // key: playerId|x|y|z -> system.currentTick
|
||||||
|
function consumeInteractToken(player, block) {
|
||||||
|
const key = `${player.id}|${block.location.x}|${block.location.y}|${block.location.z}`;
|
||||||
|
const last = recentInteract.get(key) ?? -999;
|
||||||
|
const now = system.currentTick;
|
||||||
|
if (now - last < 4) return false; // <200ms — treat as duplicate
|
||||||
|
recentInteract.set(key, now);
|
||||||
|
// Lazy cleanup: prune any entries older than ~4s on each successful claim
|
||||||
|
if (recentInteract.size > 64) {
|
||||||
|
for (const [k, t] of recentInteract) {
|
||||||
|
if (now - t > 80) recentInteract.delete(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Bonemeal on hemp_crop bumps growth ---
|
||||||
|
world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
|
||||||
|
const block = event.block;
|
||||||
|
const stack = event.itemStack;
|
||||||
|
const player = event.player;
|
||||||
|
if (!block || block.typeId !== CROP) return;
|
||||||
|
|
||||||
|
// Sheers harvest path
|
||||||
|
if (stack && stack.typeId === "minecraft:shears") {
|
||||||
|
event.cancel = true;
|
||||||
|
if (!consumeInteractToken(player, block)) return;
|
||||||
|
system.run(() => harvestWithShears(player, block, stack));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bone meal path
|
||||||
|
if (stack && stack.typeId === "minecraft:bone_meal") {
|
||||||
|
event.cancel = true;
|
||||||
|
if (!consumeInteractToken(player, block)) return;
|
||||||
|
system.run(() => {
|
||||||
|
// If the player clicked the top half, redirect to the base
|
||||||
|
let target = block;
|
||||||
|
if (block.permutation.getState(TOP) === true) {
|
||||||
|
const below = block.dimension.getBlock({ x: block.location.x, y: block.location.y - 1, z: block.location.z });
|
||||||
|
if (below && below.typeId === CROP) target = below;
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
const age = target.permutation.getState(AGE) ?? 0;
|
||||||
|
// Cap bone meal at age 4 (prime) — overripe (5) only via neglect
|
||||||
|
if (age >= 4) {
|
||||||
|
player.sendMessage("§e[Hemp] Already mature — harvest with shears.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Always consume the bone meal, but only 50% chance to advance
|
||||||
|
consumeOneOfType(player, "minecraft:bone_meal");
|
||||||
|
const loc = target.location;
|
||||||
|
try { target.dimension.runCommand(`particle minecraft:crop_growth_emitter ${loc.x + 0.5} ${loc.y + 0.5} ${loc.z + 0.5}`); } catch (_) {}
|
||||||
|
if (!chance(0.5)) return;
|
||||||
|
const outdoor = isAirAbove(target.dimension, loc);
|
||||||
|
setAge(target, age + 1, outdoor);
|
||||||
|
try { target.dimension.runCommand(`playsound random.fizz @a ${loc.x + 0.5} ${loc.y + 0.5} ${loc.z + 0.5} 0.6 1.6`); } catch (_) {}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function harvestWithShears(player, block, shearsStack) {
|
||||||
|
if (!block || block.typeId !== CROP) return; // already harvested / replaced
|
||||||
|
// Read state on the BASE block (not top)
|
||||||
|
let base = block;
|
||||||
|
if (block.permutation.getState(TOP) === true) {
|
||||||
|
const below = block.dimension.getBlock({ x: block.location.x, y: block.location.y - 1, z: block.location.z });
|
||||||
|
if (below && below.typeId === CROP) base = below;
|
||||||
|
}
|
||||||
|
const age = base.permutation.getState(AGE) ?? 0;
|
||||||
|
const dim = base.dimension;
|
||||||
|
const loc = base.location;
|
||||||
|
const outdoor = isAirAbove(dim, loc);
|
||||||
|
|
||||||
|
// Too early — leave the plant alone, don't damage shears
|
||||||
|
if (age <= 1) {
|
||||||
|
player.sendMessage("§7[Hemp] Too early — leave it to grow.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const yields = computeYield(age, outdoor);
|
||||||
|
if (yields.msg) player.sendMessage(yields.msg);
|
||||||
|
|
||||||
|
if (yields.bud > 0) spawnDrop(dim, loc, BUD, yields.bud);
|
||||||
|
if (yields.seeds > 0) spawnDrop(dim, loc, SEEDS, yields.seeds);
|
||||||
|
|
||||||
|
// Fully remove the plant — player replants from seeds
|
||||||
|
clearTopAbove(base);
|
||||||
|
try { base.setType("minecraft:air"); } catch (_) {}
|
||||||
|
|
||||||
|
damageShears(player, shearsStack);
|
||||||
|
try { dim.runCommand(`playsound mob.sheep.shear @a ${loc.x + 0.5} ${loc.y + 0.5} ${loc.z + 0.5}`); } catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeYield(age, outdoor) {
|
||||||
|
// Outdoor gets a bud bonus; indoor (sun-lamp grown) is baseline.
|
||||||
|
const out = outdoor ? 1 : 0;
|
||||||
|
switch (age) {
|
||||||
|
case 2: return { bud: 1, seeds: 1 + out };
|
||||||
|
case 3: return { bud: 2 + out, seeds: 1 + out };
|
||||||
|
case 4: return { bud: 3 + out * 2, seeds: 1 + out, msg: "§a[Hemp] Prime harvest." }; // peak
|
||||||
|
case 5: return { bud: rand(3), seeds: 3 + rand(3), msg: "§7[Hemp] Overripe — mostly seeds now." };
|
||||||
|
default: return { bud: 0, seeds: 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function spawnDrop(dim, loc, typeId, count) {
|
||||||
|
try {
|
||||||
|
const it = new ItemStack(typeId, count);
|
||||||
|
dim.spawnItem(it, { x: loc.x + 0.5, y: loc.y + 0.5, z: loc.z + 0.5 });
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function damageShears(player, shearsStack) {
|
||||||
|
try {
|
||||||
|
const equippable = player.getComponent("minecraft:equippable");
|
||||||
|
if (!equippable) return;
|
||||||
|
const slot = equippable.getEquipmentSlot("Mainhand");
|
||||||
|
if (!slot) return;
|
||||||
|
const item = slot.getItem();
|
||||||
|
if (!item || item.typeId !== "minecraft:shears") return;
|
||||||
|
const dur = item.getComponent("minecraft:durability");
|
||||||
|
if (!dur) return;
|
||||||
|
const damage = dur.damage + 1;
|
||||||
|
if (damage >= dur.maxDurability) {
|
||||||
|
slot.setItem(undefined);
|
||||||
|
try { player.dimension.runCommand(`playsound random.break @a ${player.location.x} ${player.location.y} ${player.location.z}`); } catch (_) {}
|
||||||
|
} else {
|
||||||
|
dur.damage = damage;
|
||||||
|
slot.setItem(item);
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Cauldron tincture brewing: hemp_bud + water cauldron + glass bottle => tincture ---
|
||||||
|
world.afterEvents.itemUse.subscribe((event) => {
|
||||||
|
const player = event.source;
|
||||||
|
const stack = event.itemStack;
|
||||||
|
if (!stack || stack.typeId !== BUD) return;
|
||||||
|
system.run(() => {
|
||||||
|
const target = player.getBlockFromViewDirection({ maxDistance: 6 });
|
||||||
|
const block = target?.block;
|
||||||
|
if (!block) return;
|
||||||
|
const isCauldron = block.typeId === "minecraft:cauldron" || block.typeId === "minecraft:water_cauldron";
|
||||||
|
if (!isCauldron) return;
|
||||||
|
|
||||||
|
// Need at least 3 buds total in inventory and 1 glass bottle
|
||||||
|
const inv = getInv(player);
|
||||||
|
if (!inv) return;
|
||||||
|
let budCount = 0, bottleCount = 0;
|
||||||
|
for (let i = 0; i < inv.size; i++) {
|
||||||
|
const it = inv.getItem(i);
|
||||||
|
if (!it) continue;
|
||||||
|
if (it.typeId === BUD) budCount += it.amount;
|
||||||
|
else if (it.typeId === "minecraft:glass_bottle") bottleCount += it.amount;
|
||||||
|
}
|
||||||
|
if (budCount < 3) {
|
||||||
|
player.sendMessage("§c[Hemp] Need 3 hemp buds to brew tincture.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bottleCount < 1) {
|
||||||
|
player.sendMessage("§c[Hemp] Need an empty glass bottle.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check water level (water cauldron has fill_level state 1-3; vanilla cauldron = empty)
|
||||||
|
let level = 0;
|
||||||
|
try { level = block.permutation.getState("fill_level") ?? 0; } catch (_) {}
|
||||||
|
if (block.typeId === "minecraft:cauldron") {
|
||||||
|
player.sendMessage("§c[Hemp] Cauldron must contain water.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level <= 0) {
|
||||||
|
player.sendMessage("§c[Hemp] Cauldron is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consume 3 buds, 1 bottle
|
||||||
|
for (let i = 0; i < 3; i++) consumeOneOfType(player, BUD);
|
||||||
|
consumeOneOfType(player, "minecraft:glass_bottle");
|
||||||
|
|
||||||
|
// Decrement water level
|
||||||
|
try {
|
||||||
|
const newLevel = level - 1;
|
||||||
|
if (newLevel <= 0) {
|
||||||
|
block.setType("minecraft:cauldron");
|
||||||
|
} else {
|
||||||
|
const perm = BlockPermutation.resolve("minecraft:water_cauldron", { fill_level: newLevel });
|
||||||
|
block.setPermutation(perm);
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
// Give tincture
|
||||||
|
giveItem(player, TINCTURE, 1);
|
||||||
|
const loc = block.location;
|
||||||
|
try { block.dimension.runCommand(`particle minecraft:water_splash_particle_manual ${loc.x + 0.5} ${loc.y + 1.0} ${loc.z + 0.5}`); } catch (_) {}
|
||||||
|
try { block.dimension.runCommand(`playsound bucket.fill_water @a ${loc.x + 0.5} ${loc.y + 0.5} ${loc.z + 0.5}`); } catch (_) {}
|
||||||
|
player.sendMessage("§a[Hemp] Hemp tincture brewed.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- Consumption effects ---
|
||||||
|
world.afterEvents.itemCompleteUse.subscribe((event) => {
|
||||||
|
const player = event.source;
|
||||||
|
const stack = event.itemStack;
|
||||||
|
if (!stack) return;
|
||||||
|
if (stack.typeId === TINCTURE) {
|
||||||
|
try {
|
||||||
|
player.addEffect("regeneration", 100, { amplifier: 1, showParticles: true });
|
||||||
|
player.addEffect("slowness", 200, { amplifier: 0, showParticles: true });
|
||||||
|
} catch (_) {}
|
||||||
|
player.sendMessage("§a[Hemp] You feel a warm, calming wave.");
|
||||||
|
} else if (stack.typeId === BROWNIE) {
|
||||||
|
try {
|
||||||
|
player.addEffect("regeneration", 200, { amplifier: 0, showParticles: true });
|
||||||
|
player.addEffect("slowness", 400, { amplifier: 0, showParticles: true });
|
||||||
|
} catch (_) {}
|
||||||
|
player.sendMessage("§a[Hemp] Mmm. You feel relaxed.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
system.run(() => {
|
||||||
|
world.sendMessage("§a[Hemp] §7Hemp pack loaded.");
|
||||||
|
});
|
||||||
5
hemp-addon/hemp_RP/blocks.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"format_version": [1, 1, 0],
|
||||||
|
"silverlabs:hemp_crop": { "sound": "grass" },
|
||||||
|
"silverlabs:sun_lamp": { "sound": "glass" }
|
||||||
|
}
|
||||||
29
hemp-addon/hemp_RP/manifest.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"format_version": 2,
|
||||||
|
"header": {
|
||||||
|
"name": "Hemp Plant Resources",
|
||||||
|
"description": "Textures, models, lang for the Hemp Plant addon",
|
||||||
|
"uuid": "8e5c46ac-3b16-4f51-89f7-673bd06600f4",
|
||||||
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"min_engine_version": [
|
||||||
|
1,
|
||||||
|
21,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
{
|
||||||
|
"type": "resources",
|
||||||
|
"uuid": "5fcc737f-d224-409d-85e9-99274afd72a9",
|
||||||
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
6
hemp-addon/hemp_RP/texts/en_US.lang
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
item.silverlabs:hemp_seeds.name=Hemp Seeds
|
||||||
|
item.silverlabs:hemp_bud.name=Hemp Bud
|
||||||
|
item.silverlabs:hemp_tincture.name=Hemp Tincture
|
||||||
|
item.silverlabs:hemp_brownie.name=Hemp Brownie
|
||||||
|
tile.silverlabs:hemp_crop.name=Hemp Plant
|
||||||
|
tile.silverlabs:sun_lamp.name=Sun Lamp
|
||||||
1
hemp-addon/hemp_RP/texts/languages.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
["en_US"]
|
||||||
BIN
hemp-addon/hemp_RP/textures/blocks/hemp_crop_0.png
Normal file
|
After Width: | Height: | Size: 108 B |
BIN
hemp-addon/hemp_RP/textures/blocks/hemp_crop_1.png
Normal file
|
After Width: | Height: | Size: 125 B |
BIN
hemp-addon/hemp_RP/textures/blocks/hemp_crop_2.png
Normal file
|
After Width: | Height: | Size: 156 B |
BIN
hemp-addon/hemp_RP/textures/blocks/hemp_crop_3.png
Normal file
|
After Width: | Height: | Size: 174 B |
BIN
hemp-addon/hemp_RP/textures/blocks/hemp_crop_4.png
Normal file
|
After Width: | Height: | Size: 316 B |
BIN
hemp-addon/hemp_RP/textures/blocks/hemp_crop_5.png
Normal file
|
After Width: | Height: | Size: 332 B |
BIN
hemp-addon/hemp_RP/textures/blocks/sun_lamp.png
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
hemp-addon/hemp_RP/textures/blocks/sun_lamp_off.png
Normal file
|
After Width: | Height: | Size: 298 B |
10
hemp-addon/hemp_RP/textures/item_texture.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"resource_pack_name": "hemp_RP",
|
||||||
|
"texture_name": "atlas.items",
|
||||||
|
"texture_data": {
|
||||||
|
"hemp_seeds": { "textures": "textures/items/hemp_seeds" },
|
||||||
|
"hemp_bud": { "textures": "textures/items/hemp_bud" },
|
||||||
|
"hemp_tincture": { "textures": "textures/items/hemp_tincture" },
|
||||||
|
"hemp_brownie": { "textures": "textures/items/hemp_brownie" }
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
hemp-addon/hemp_RP/textures/items/hemp_brownie.png
Normal file
|
After Width: | Height: | Size: 177 B |
BIN
hemp-addon/hemp_RP/textures/items/hemp_bud.png
Normal file
|
After Width: | Height: | Size: 198 B |
BIN
hemp-addon/hemp_RP/textures/items/hemp_seeds.png
Normal file
|
After Width: | Height: | Size: 139 B |
BIN
hemp-addon/hemp_RP/textures/items/hemp_tincture.png
Normal file
|
After Width: | Height: | Size: 152 B |
16
hemp-addon/hemp_RP/textures/terrain_texture.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"resource_pack_name": "hemp_RP",
|
||||||
|
"texture_name": "atlas.terrain",
|
||||||
|
"padding": 8,
|
||||||
|
"num_mip_levels": 4,
|
||||||
|
"texture_data": {
|
||||||
|
"hemp_crop_0": { "textures": "textures/blocks/hemp_crop_0" },
|
||||||
|
"hemp_crop_1": { "textures": "textures/blocks/hemp_crop_1" },
|
||||||
|
"hemp_crop_2": { "textures": "textures/blocks/hemp_crop_2" },
|
||||||
|
"hemp_crop_3": { "textures": "textures/blocks/hemp_crop_3" },
|
||||||
|
"hemp_crop_4": { "textures": "textures/blocks/hemp_crop_4" },
|
||||||
|
"hemp_crop_5": { "textures": "textures/blocks/hemp_crop_5" },
|
||||||
|
"sun_lamp": { "textures": "textures/blocks/sun_lamp" },
|
||||||
|
"sun_lamp_off": { "textures": "textures/blocks/sun_lamp_off" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,20 +4,36 @@
|
|||||||
"name": "Home Sweet Home",
|
"name": "Home Sweet Home",
|
||||||
"description": "Defines a 32-block home zone for tamed cats; quieter cat meows",
|
"description": "Defines a 32-block home zone for tamed cats; quieter cat meows",
|
||||||
"uuid": "c8e51d72-9a4f-4b3e-b8c1-2f7d3e6a4b80",
|
"uuid": "c8e51d72-9a4f-4b3e-b8c1-2f7d3e6a4b80",
|
||||||
"version": [1, 0, 0],
|
"version": [
|
||||||
"min_engine_version": [1, 21, 0]
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"min_engine_version": [
|
||||||
|
1,
|
||||||
|
21,
|
||||||
|
0
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"type": "data",
|
"type": "data",
|
||||||
"uuid": "c8e51d72-9a4f-4b3e-b8c1-2f7d3e6a4b81",
|
"uuid": "c8e51d72-9a4f-4b3e-b8c1-2f7d3e6a4b81",
|
||||||
"version": [1, 0, 0]
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "script",
|
"type": "script",
|
||||||
"language": "javascript",
|
"language": "javascript",
|
||||||
"uuid": "c8e51d72-9a4f-4b3e-b8c1-2f7d3e6a4b82",
|
"uuid": "c8e51d72-9a4f-4b3e-b8c1-2f7d3e6a4b82",
|
||||||
"version": [1, 0, 0],
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
"entry": "scripts/main.js"
|
"entry": "scripts/main.js"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -28,7 +44,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"uuid": "c8e51d72-9a4f-4b3e-b8c1-2f7d3e6a4b83",
|
"uuid": "c8e51d72-9a4f-4b3e-b8c1-2f7d3e6a4b83",
|
||||||
"version": [1, 0, 1]
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,33 @@ const ARRIVAL_RADIUS = 3;
|
|||||||
const HUD_TICK_INTERVAL = 5;
|
const HUD_TICK_INTERVAL = 5;
|
||||||
const ARROWS = ["\u2191", "\u2197", "\u2192", "\u2198", "\u2193", "\u2199", "\u2190", "\u2196"];
|
const ARROWS = ["\u2191", "\u2197", "\u2192", "\u2198", "\u2193", "\u2199", "\u2190", "\u2196"];
|
||||||
|
|
||||||
|
// Navigation HUD lives in the title/subtitle slot so it doesn't fight the
|
||||||
|
// vanilla mount UI for the action bar. The directional content goes in the
|
||||||
|
// TITLE position (large, central) with the waypoint label in the subtitle as
|
||||||
|
// a secondary line. Empty-string title gets suppressed by some Bedrock client
|
||||||
|
// versions, so we always pass a non-empty title — that's what causes the
|
||||||
|
// arrival message to render but a setActionBar-replacement subtitle not to.
|
||||||
|
function showNav(player, mainLine, subLine) {
|
||||||
|
try {
|
||||||
|
player.onScreenDisplay.setTitle(mainLine, {
|
||||||
|
subtitle: subLine ?? "",
|
||||||
|
fadeInDuration: 0,
|
||||||
|
stayDuration: HUD_TICK_INTERVAL * 4,
|
||||||
|
fadeOutDuration: 0,
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
function clearNav(player) {
|
||||||
|
try {
|
||||||
|
player.onScreenDisplay.setTitle(" ", {
|
||||||
|
subtitle: "",
|
||||||
|
fadeInDuration: 0,
|
||||||
|
stayDuration: 1,
|
||||||
|
fadeOutDuration: 0,
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
const recentTransfers = new Map();
|
const recentTransfers = new Map();
|
||||||
const spawnTimes = new Map();
|
const spawnTimes = new Map();
|
||||||
|
|
||||||
@@ -24,8 +51,22 @@ const spawnTimes = new Map();
|
|||||||
|
|
||||||
// Persisted: markers per player { [ownerId]: [ {x,y,z,dim,label,key}, ... ] }
|
// Persisted: markers per player { [ownerId]: [ {x,y,z,dim,label,key}, ... ] }
|
||||||
let markers = {};
|
let markers = {};
|
||||||
// Session-only: which marker each player is actively guiding toward
|
// Per-player active waypoint index, persisted via player dynamic property so
|
||||||
const active = new Map();
|
// it survives container restarts and reconnects.
|
||||||
|
const ACTIVE_PROP = "hub_active_waypoint_v1";
|
||||||
|
function getActiveIndex(player) {
|
||||||
|
try {
|
||||||
|
const v = player.getDynamicProperty(ACTIVE_PROP);
|
||||||
|
return typeof v === "number" ? v : null;
|
||||||
|
} catch (_) { return null; }
|
||||||
|
}
|
||||||
|
function setActiveIndex(player, idx) {
|
||||||
|
try {
|
||||||
|
if (idx == null) player.setDynamicProperty(ACTIVE_PROP, undefined);
|
||||||
|
else player.setDynamicProperty(ACTIVE_PROP, idx);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
function clearActiveIndex(player) { setActiveIndex(player, null); }
|
||||||
|
|
||||||
function keyOf(loc, dimensionId) {
|
function keyOf(loc, dimensionId) {
|
||||||
return `${Math.floor(loc.x)},${Math.floor(loc.y)},${Math.floor(loc.z)},${dimensionId}`;
|
return `${Math.floor(loc.x)},${Math.floor(loc.y)},${Math.floor(loc.z)},${dimensionId}`;
|
||||||
@@ -67,10 +108,16 @@ function findMarkerByKey(key) {
|
|||||||
function removeMarker(ownerId, index) {
|
function removeMarker(ownerId, index) {
|
||||||
const list = getMarkers(ownerId);
|
const list = getMarkers(ownerId);
|
||||||
list.splice(index, 1);
|
list.splice(index, 1);
|
||||||
const activeIdx = active.get(ownerId);
|
// Active index is stored on the owner's player dynamic property; update only
|
||||||
|
// if they're online (offline owner will revalidate their own index next tick).
|
||||||
|
for (const p of world.getAllPlayers()) {
|
||||||
|
if (p.id !== ownerId) continue;
|
||||||
|
const activeIdx = getActiveIndex(p);
|
||||||
if (activeIdx != null) {
|
if (activeIdx != null) {
|
||||||
if (activeIdx === index) active.delete(ownerId);
|
if (activeIdx === index) clearActiveIndex(p);
|
||||||
else if (activeIdx > index) active.set(ownerId, activeIdx - 1);
|
else if (activeIdx > index) setActiveIndex(p, activeIdx - 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
saveWaypoints();
|
saveWaypoints();
|
||||||
}
|
}
|
||||||
@@ -149,11 +196,8 @@ world.afterEvents.playerSpawn.subscribe((event) => {
|
|||||||
}, 20);
|
}, 20);
|
||||||
});
|
});
|
||||||
|
|
||||||
world.afterEvents.playerLeave.subscribe((event) => {
|
// Active waypoint is persisted as a player dynamic property, so playerLeave
|
||||||
// Clear session HUD state for whoever left (keyed by id)
|
// does not need to clear any in-memory session state.
|
||||||
// event.playerId exists; event.playerName for compat
|
|
||||||
if (event.playerId) active.delete(event.playerId);
|
|
||||||
});
|
|
||||||
|
|
||||||
// ─── Compass Menu ───────────────────────────────────────────────
|
// ─── Compass Menu ───────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -183,7 +227,7 @@ async function openCompassMenu(player) {
|
|||||||
actions.push({ kind: "select", index: i });
|
actions.push({ kind: "select", index: i });
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeIdx = active.get(player.id);
|
const activeIdx = getActiveIndex(player);
|
||||||
if (activeIdx != null && list[activeIdx]) {
|
if (activeIdx != null && list[activeIdx]) {
|
||||||
form.button(`§c\u274C Clear active waypoint`);
|
form.button(`§c\u274C Clear active waypoint`);
|
||||||
actions.push({ kind: "clear" });
|
actions.push({ kind: "clear" });
|
||||||
@@ -192,6 +236,9 @@ async function openCompassMenu(player) {
|
|||||||
if (list.length > 0) {
|
if (list.length > 0) {
|
||||||
form.button("\uD83D\uDDD1 Delete a waypoint…");
|
form.button("\uD83D\uDDD1 Delete a waypoint…");
|
||||||
actions.push({ kind: "delete_menu" });
|
actions.push({ kind: "delete_menu" });
|
||||||
|
|
||||||
|
form.button("\uD83D\uDCE4 Share with another player…");
|
||||||
|
actions.push({ kind: "share" });
|
||||||
}
|
}
|
||||||
|
|
||||||
form.button("\uD83E\uDDED Get a marker block");
|
form.button("\uD83E\uDDED Get a marker block");
|
||||||
@@ -212,14 +259,14 @@ async function openCompassMenu(player) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (a.kind === "select") {
|
if (a.kind === "select") {
|
||||||
active.set(player.id, a.index);
|
setActiveIndex(player, a.index);
|
||||||
const m = list[a.index];
|
const m = list[a.index];
|
||||||
player.sendMessage(`§b[Waypoints] §fGuiding you to §d${m.label}§f.`);
|
player.sendMessage(`§b[Waypoints] §fGuiding you to §d${m.label}§f. §8(arrow appears at the top of your screen)`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (a.kind === "clear") {
|
if (a.kind === "clear") {
|
||||||
active.delete(player.id);
|
clearActiveIndex(player);
|
||||||
player.onScreenDisplay.setActionBar("");
|
clearNav(player);
|
||||||
player.sendMessage("§b[Waypoints] §fActive waypoint cleared.");
|
player.sendMessage("§b[Waypoints] §fActive waypoint cleared.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -227,6 +274,10 @@ async function openCompassMenu(player) {
|
|||||||
await openDeleteMenu(player);
|
await openDeleteMenu(player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (a.kind === "share") {
|
||||||
|
await openShareMenu(player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (a.kind === "give_marker") {
|
if (a.kind === "give_marker") {
|
||||||
giveMarkerBlock(player);
|
giveMarkerBlock(player);
|
||||||
return;
|
return;
|
||||||
@@ -286,6 +337,102 @@ async function openDeleteMenu(player) {
|
|||||||
player.sendMessage(`§b[Waypoints] §fDeleted §d${chosen.label}§f.`);
|
player.sendMessage(`§b[Waypoints] §fDeleted §d${chosen.label}§f.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Share Waypoint ─────────────────────────────────────────────
|
||||||
|
// Pick one of your waypoints, pick an online player in this world, send
|
||||||
|
// them a confirm prompt. On accept, the waypoint is copied into the
|
||||||
|
// recipient's list with a `(from <sender>)` suffix so it's clearly
|
||||||
|
// attributed. Cross-world shares are blocked here — a player on the lyla
|
||||||
|
// server can't be reached from jamie. Same dimension is preferred but
|
||||||
|
// cross-dim is allowed; the HUD already labels "different dimension".
|
||||||
|
|
||||||
|
async function openShareMenu(sender) {
|
||||||
|
const list = getMarkers(sender.id);
|
||||||
|
if (list.length === 0) {
|
||||||
|
sender.sendMessage("§7[Share] You have no waypoints to share.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const others = world.getAllPlayers().filter((p) => p.id !== sender.id);
|
||||||
|
if (others.length === 0) {
|
||||||
|
sender.sendMessage("§7[Share] No other players are online in this world.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wpForm = new ActionFormData()
|
||||||
|
.title("Share a Waypoint")
|
||||||
|
.body("§7Pick which waypoint to share:");
|
||||||
|
for (const m of list) {
|
||||||
|
wpForm.button(`§f${m.label}\n§7${m.x}, ${m.y}, ${m.z}`);
|
||||||
|
}
|
||||||
|
wpForm.button("§7Cancel");
|
||||||
|
|
||||||
|
let wpRes;
|
||||||
|
try { wpRes = await wpForm.show(sender); } catch (_) { return; }
|
||||||
|
if (wpRes.canceled || wpRes.selection === undefined) return;
|
||||||
|
if (wpRes.selection >= list.length) return;
|
||||||
|
const marker = list[wpRes.selection];
|
||||||
|
|
||||||
|
const recipForm = new ActionFormData()
|
||||||
|
.title(`Share "${marker.label}"`)
|
||||||
|
.body("§7Who should receive this waypoint?");
|
||||||
|
for (const p of others) recipForm.button(`§f${p.name}`);
|
||||||
|
recipForm.button("§7Cancel");
|
||||||
|
|
||||||
|
let rRes;
|
||||||
|
try { rRes = await recipForm.show(sender); } catch (_) { return; }
|
||||||
|
if (rRes.canceled || rRes.selection === undefined) return;
|
||||||
|
if (rRes.selection >= others.length) return;
|
||||||
|
const recipient = others[rRes.selection];
|
||||||
|
|
||||||
|
// Receiver capacity check before bothering them with a prompt
|
||||||
|
const recList = getMarkers(recipient.id);
|
||||||
|
if (recList.length >= MAX_MARKERS_PER_PLAYER) {
|
||||||
|
sender.sendMessage(`§c[Share] §f${recipient.name}'s waypoint slots are full.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(`§b[Share] §fSent §d${marker.label}§f to §e${recipient.name}§f — waiting for them to accept…`);
|
||||||
|
|
||||||
|
const offer = new MessageFormData()
|
||||||
|
.title("Waypoint Shared")
|
||||||
|
.body(`§e${sender.name}§r wants to share a waypoint with you:\n\n§f${marker.label}\n§7${marker.x}, ${marker.y}, ${marker.z}\n\nAdd to your compass?`)
|
||||||
|
.button1("§aAccept")
|
||||||
|
.button2("§cDecline");
|
||||||
|
|
||||||
|
let oRes;
|
||||||
|
try { oRes = await offer.show(recipient); } catch (_) {
|
||||||
|
sender.sendMessage(`§c[Share] §f${recipient.name} couldn't be reached.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (oRes.canceled || oRes.selection !== 0) {
|
||||||
|
sender.sendMessage(`§7[Share] §f${recipient.name} declined.`);
|
||||||
|
recipient.sendMessage(`§7[Share] §fDeclined waypoint from §e${sender.name}§f.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-check capacity after the await — markers may have changed
|
||||||
|
if (recList.length >= MAX_MARKERS_PER_PLAYER) {
|
||||||
|
sender.sendMessage(`§c[Share] §f${recipient.name}'s waypoint slots are full.`);
|
||||||
|
recipient.sendMessage(`§c[Share] §fYour waypoint slots are full — couldn't accept §d${marker.label}§f.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sharedLabel = `${marker.label} (from ${sender.name})`.slice(0, 40);
|
||||||
|
// Use a key that won't collide with the receiver's own lodestones
|
||||||
|
const sharedKey = `shared:${sender.id}:${marker.key}`;
|
||||||
|
recList.push({
|
||||||
|
x: marker.x,
|
||||||
|
y: marker.y,
|
||||||
|
z: marker.z,
|
||||||
|
dim: marker.dim,
|
||||||
|
label: sharedLabel,
|
||||||
|
key: sharedKey,
|
||||||
|
});
|
||||||
|
saveWaypoints();
|
||||||
|
|
||||||
|
sender.sendMessage(`§a[Share] §f${recipient.name} accepted §d${marker.label}§f.`);
|
||||||
|
recipient.sendMessage(`§a[Share] §fAdded §d${sharedLabel}§f. Type §e!nav§f to find it.`);
|
||||||
|
}
|
||||||
|
|
||||||
// ─── Placement → Label Prompt ───────────────────────────────────
|
// ─── Placement → Label Prompt ───────────────────────────────────
|
||||||
|
|
||||||
world.afterEvents.playerPlaceBlock.subscribe((event) => {
|
world.afterEvents.playerPlaceBlock.subscribe((event) => {
|
||||||
@@ -402,17 +549,17 @@ function distanceXZ(a, b) {
|
|||||||
|
|
||||||
system.runInterval(() => {
|
system.runInterval(() => {
|
||||||
for (const player of world.getAllPlayers()) {
|
for (const player of world.getAllPlayers()) {
|
||||||
const idx = active.get(player.id);
|
const idx = getActiveIndex(player);
|
||||||
if (idx == null) continue;
|
if (idx == null) continue;
|
||||||
|
|
||||||
const list = markers[player.id];
|
const list = markers[player.id];
|
||||||
const m = list && list[idx];
|
const m = list && list[idx];
|
||||||
if (!m) {
|
if (!m) {
|
||||||
active.delete(player.id);
|
clearActiveIndex(player);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m.dim !== player.dimension.id) {
|
if (m.dim !== player.dimension.id) {
|
||||||
player.onScreenDisplay.setActionBar(`§b\u27A4 §f${m.label} §7• §cdifferent dimension`);
|
showNav(player, `§c⚠ Different Dimension`, `§7${m.label}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,10 +569,9 @@ system.runInterval(() => {
|
|||||||
const distXZ = Math.sqrt(dx * dx + dz * dz);
|
const distXZ = Math.sqrt(dx * dx + dz * dz);
|
||||||
|
|
||||||
if (distXZ <= ARRIVAL_RADIUS) {
|
if (distXZ <= ARRIVAL_RADIUS) {
|
||||||
active.delete(player.id);
|
clearActiveIndex(player);
|
||||||
try {
|
try {
|
||||||
player.onScreenDisplay.setTitle(`§aArrived`, { subtitle: `§f${m.label}`, fadeInDuration: 5, stayDuration: 30, fadeOutDuration: 10 });
|
player.onScreenDisplay.setTitle(`§aArrived`, { subtitle: `§f${m.label}`, fadeInDuration: 5, stayDuration: 30, fadeOutDuration: 10 });
|
||||||
player.onScreenDisplay.setActionBar("");
|
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -439,11 +585,7 @@ system.runInterval(() => {
|
|||||||
const bucket = ((Math.round(relative / 45) % 8) + 8) % 8;
|
const bucket = ((Math.round(relative / 45) % 8) + 8) % 8;
|
||||||
const arrow = ARROWS[bucket];
|
const arrow = ARROWS[bucket];
|
||||||
|
|
||||||
try {
|
showNav(player, `§a${arrow} §f${Math.round(distXZ)}m`, `§7${m.label}`);
|
||||||
player.onScreenDisplay.setActionBar(
|
|
||||||
`§b\u27A4 §f${m.label} §7• §f${Math.round(distXZ)}m §8[§a${arrow}§8]`
|
|
||||||
);
|
|
||||||
} catch (_) {}
|
|
||||||
}
|
}
|
||||||
}, HUD_TICK_INTERVAL);
|
}, HUD_TICK_INTERVAL);
|
||||||
|
|
||||||
@@ -515,6 +657,52 @@ function handleChatCommand(player, msg) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msg === "!share") {
|
||||||
|
system.run(() => openShareMenu(player));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg === "!nav" || msg.startsWith("!nav ")) {
|
||||||
|
const list = getMarkers(player.id);
|
||||||
|
const arg = msg.slice(4).trim();
|
||||||
|
if (arg === "off" || arg === "clear") {
|
||||||
|
clearActiveIndex(player);
|
||||||
|
clearNav(player);
|
||||||
|
player.sendMessage("§b[Waypoints] §fNavigation cleared.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (arg) {
|
||||||
|
const n = Number.parseInt(arg, 10);
|
||||||
|
if (Number.isFinite(n) && n >= 1 && n <= list.length) {
|
||||||
|
setActiveIndex(player, n - 1);
|
||||||
|
const m = list[n - 1];
|
||||||
|
player.sendMessage(`§b[Waypoints] §fGuiding you to §d${m.label}§f. §8(arrow at top of screen)`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
player.sendMessage(`§c[Waypoints] §fNo waypoint #${arg} — type §e!nav§f to list yours.`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (list.length === 0) {
|
||||||
|
player.sendMessage("§7[Waypoints] No waypoints yet — place a §dlodestone§7 to set one.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const idx = getActiveIndex(player);
|
||||||
|
const cur = idx != null ? list[idx] : null;
|
||||||
|
if (cur) {
|
||||||
|
const dist = Math.round(distanceXZ(player.location, cur));
|
||||||
|
player.sendMessage(`§b[Waypoints] §fActive: §d${cur.label}§f (${dist}m). Type §e!nav off§f to clear, or §e!nav <number>§f to switch.`);
|
||||||
|
} else {
|
||||||
|
player.sendMessage("§b[Waypoints] §fNo active waypoint. Pick one:");
|
||||||
|
}
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
const m = list[i];
|
||||||
|
const here = m.dim === player.dimension.id;
|
||||||
|
const tag = here ? `§7${Math.round(distanceXZ(player.location, m))}m` : "§8(other dim)";
|
||||||
|
player.sendMessage(` §e${i + 1}§7. §f${m.label} ${tag}`);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (msg === "!clearwaypoints") {
|
if (msg === "!clearwaypoints") {
|
||||||
system.run(async () => {
|
system.run(async () => {
|
||||||
const confirm = new MessageFormData()
|
const confirm = new MessageFormData()
|
||||||
@@ -526,7 +714,7 @@ function handleChatCommand(player, msg) {
|
|||||||
try { res = await confirm.show(player); } catch (_) { return; }
|
try { res = await confirm.show(player); } catch (_) { return; }
|
||||||
if (res.canceled || res.selection !== 0) return;
|
if (res.canceled || res.selection !== 0) return;
|
||||||
markers[player.id] = [];
|
markers[player.id] = [];
|
||||||
active.delete(player.id);
|
clearActiveIndex(player);
|
||||||
saveWaypoints();
|
saveWaypoints();
|
||||||
player.sendMessage("§b[Waypoints] §fAll your waypoints were cleared.");
|
player.sendMessage("§b[Waypoints] §fAll your waypoints were cleared.");
|
||||||
});
|
});
|
||||||
@@ -606,5 +794,5 @@ system.runTimeout(() => {
|
|||||||
|
|
||||||
system.run(() => {
|
system.run(() => {
|
||||||
loadWaypoints();
|
loadWaypoints();
|
||||||
world.sendMessage("§b[World] §fHub return system loaded! Place a §dlodestone§f to set a waypoint; right-click your compass to navigate.");
|
world.sendMessage("§b[World] §fHub return system loaded! Place a §dlodestone§f to set a waypoint, then right-click your compass and pick one — the §anavigation arrow§f shows at the §atop§f of your screen. (Type §e!nav§f for chat fallback.)");
|
||||||
});
|
});
|
||||||
|
|||||||
29
hub-return-addon/hub_return_transfer_RP/manifest.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"format_version": 2,
|
||||||
|
"header": {
|
||||||
|
"name": "Hub Return Resources",
|
||||||
|
"description": "Recovery compass icon override + future hub-return assets",
|
||||||
|
"uuid": "b1f7e2a4-3c5d-49b8-9d22-6a4f0c87e511",
|
||||||
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"min_engine_version": [
|
||||||
|
1,
|
||||||
|
21,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
{
|
||||||
|
"type": "resources",
|
||||||
|
"uuid": "c4a13e85-2f96-4d1a-b772-9e0f3b4d6c21",
|
||||||
|
"version": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.alligator.evict_riders": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"eject_rider": "query.has_target"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"eject_rider": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "(1.0)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"on_entry": [
|
||||||
|
"/ride @s evict_riders"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.anteater": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": ["/effect @s clear slowness"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"not_move": "q.is_interested || q.timer_flag_1 || query.property('silverlabs_nat:on_defensive_mode') == 'enabled'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"not_move": {
|
||||||
|
"on_entry": ["/effect @s slowness infinite 255 true"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "!q.is_interested && !q.timer_flag_1 && query.property('silverlabs_nat:on_defensive_mode') != 'enabled'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.badger.daylight_controller": {
|
||||||
|
"initial_state": "init",
|
||||||
|
"states": {
|
||||||
|
"init": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"daylight_tamed": "((q.time_of_day - 0.25) <= 0.5) && q.is_tamed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"daylight_untamed": "((q.time_of_day - 0.25) <= 0.5)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"night": "((q.time_of_day - 0.25) > 0.5)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"daylight_tamed": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:badger_daytime_tamed"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"daylight_tamed": "((q.time_of_day - 0.25) <= 0.5) && q.is_tamed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"daylight_untamed": "((q.time_of_day - 0.25) <= 0.5)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"night": "((q.time_of_day - 0.25) > 0.5)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"daylight_untamed": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:badger_daytime_wild"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"daylight_tamed": "((q.time_of_day - 0.25) <= 0.5) && q.is_tamed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"daylight_untamed": "((q.time_of_day - 0.25) <= 0.5)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"night": "((q.time_of_day - 0.25) > 0.5)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"night": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:badger_nighttime"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"daylight_tamed": "((q.time_of_day - 0.25) <= 0.5) && q.is_tamed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"daylight_untamed": "((q.time_of_day - 0.25) <= 0.5)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"night": "((q.time_of_day - 0.25) > 0.5)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.bear.eat": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"can_use": "query.property('silverlabs_nat:is_sitting')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"can_use": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "!query.property('silverlabs_nat:is_sitting')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"configure_eating": "!math.random_integer(0, 79)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"configure_eating": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:configure_eating"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "!query.property('silverlabs_nat:is_sitting')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.beaver.chew_watcher": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "chewing": "query.property('silverlabs_nat:is_chewing')" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"chewing": {
|
||||||
|
"on_exit": [
|
||||||
|
"/scriptevent silverlabs_nat:beaver_chew"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "!query.property('silverlabs_nat:is_chewing')" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.bird.landing_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.switch_chance = 200;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"walking": "query.property('silverlabs_nat:movement_mode') == 'walk'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"flying": "query.property('silverlabs_nat:movement_mode') == 'fly'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"walking": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.switch_delay = query.life_time + Math.random_integer(5, 10);"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"start_flying": "!q.is_baby && (Math.random_integer(0, (v.switch_chance ?? 1)) == (v.switch_chance ?? 1) && (query.life_time > (v.switch_delay ?? 0))) && !query.property('silverlabs_nat:is_tempted') && !q.is_sitting && !q.is_in_love"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"flying": "query.property('silverlabs_nat:movement_mode') == 'fly'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start_flying": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:bird_set_flying_mode"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"flying": "query.property('silverlabs_nat:movement_mode') == 'fly'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"flying": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.switch_delay = query.life_time + Math.random_integer(5, 10);"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"landing_check": "q.is_baby || (Math.random_integer(0, (v.switch_chance ?? 1)) == (v.switch_chance ?? 1) && (query.life_time > (v.switch_delay ?? 0)) && !q.has_target) || query.property('silverlabs_nat:is_tempted') || q.is_sitting || q.is_in_love"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"walking": "query.property('silverlabs_nat:movement_mode') == 'walk'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"landing_check": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:bird_landing_check"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.bird.tempt_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:not_tempted"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"tempted": "q.is_interested"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tempted": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:is_tempted"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "!q.is_interested"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.bird.smooth_landing": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"tempted": "!q.is_on_ground"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tempted": {
|
||||||
|
"on_entry": [
|
||||||
|
"/effect @s slow_falling 2 1 true"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.blobfish": {
|
||||||
|
"initial_state": "init",
|
||||||
|
"states": {
|
||||||
|
"init": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"normal_blobfish": "query.is_in_water && q.position(1) < 30"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"land_blobfish": "q.position(1) > 30"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"normal_blobfish": {
|
||||||
|
"animations": [
|
||||||
|
"blobfish.duration"
|
||||||
|
],
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:blobfish_normal"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"land_blobfish": "q.anim_time > 3.0 && q.position(1) > 30"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"land_blobfish": {
|
||||||
|
"animations": [
|
||||||
|
"blobfish.duration"
|
||||||
|
],
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:blobfish_land"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"normal_blobfish": "q.anim_time > 3.0 && query.is_in_water && q.position(1) < 30"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.bucketable_entity": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"on_bucket": "q.has_any_family('silverlabs_nat:bucketable_entity') && query.property('silverlabs_nat:on_bucket')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"on_bucket": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:bucketable_entity_interaction @initiator"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.clam.launch": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"before_open": "query.property('silverlabs_nat:before_open')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"before_open": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:clam_launch"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "!query.property('silverlabs_nat:before_open')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.clam.took_item": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"has_item": "query.property('silverlabs_nat:has_item')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"has_item": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"took_item": "query.property('silverlabs_nat:took_item')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"took_item": {
|
||||||
|
"on_entry": [
|
||||||
|
"/replaceitem entity @s slot.weapon.mainhand 0 minecraft:air"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.crab": {
|
||||||
|
"initial_state": "on_load",
|
||||||
|
"states": {
|
||||||
|
"on_load": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:crab_is_not_dancing"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"try_collect_sand": "query.property('silverlabs_nat:sand_block_interaction_state') == 'try_collect_sand'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"try_place_sand": "query.property('silverlabs_nat:sand_block_interaction_state') == 'try_place_sand'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"try_collect_sand": {
|
||||||
|
"on_entry": ["/scriptevent silverlabs_nat:crab_try_collect_sand"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"on_load": "query.property('silverlabs_nat:sand_block_interaction_state') != 'try_collect_sand'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"try_place_sand": {
|
||||||
|
"on_entry": ["/scriptevent silverlabs_nat:crab_try_place_sand"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"on_load": "query.property('silverlabs_nat:sand_block_interaction_state') != 'try_place_sand'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.eel_water_land": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"land": "!q.is_in_water"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"water": "q.is_in_water"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"land": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:eel_on_land"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"water": "q.is_in_water"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"water": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:eel_in_water"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"land": "!q.is_in_water"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.emperor_penguin.fall": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"fall": "query.property('silverlabs_nat:slip_anim') == 'none' && q.is_on_ground && !q.is_in_water && q.modified_move_speed > 0.05 && !query.property('silverlabs_nat:egg_protector') && math.random_integer(0, 333) == 0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fall": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:emperor_penguin_fall",
|
||||||
|
"v.cooldown_timer = query.life_time;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "query.life_time >= (v.cooldown_timer + 16.0)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.emperor_penguin.egg_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.cooldown_timer = 0;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"remove": "query.property('silverlabs_nat:egg_protector') && q.has_rider"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cooldown": "query.property('silverlabs_nat:egg_protector') && !q.has_target"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"cooldown": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.cooldown_timer = query.life_time;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"remove": "q.has_rider"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "!query.property('silverlabs_nat:egg_protector') || q.has_target"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"egg_check": "query.life_time >= (v.cooldown_timer + 6.0)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"egg_check": {
|
||||||
|
"on_entry": [
|
||||||
|
"/execute unless entity @e[type=silverlabs_nat:emperor_penguin_egg,c=1,r=24] run event entity @s silverlabs_nat:remove_egg_protector"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:remove_egg_protector"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.light": {
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:reset_all"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"reset": "q.is_shaking"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"on": "!q.is_shaking"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"on": {
|
||||||
|
"on_entry": [
|
||||||
|
"/tag @s add silverlabs_nat:light_source",
|
||||||
|
"/function sf/nba/lighting/setup"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "query.property('silverlabs_nat:furniture_variant') == 1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reset": "q.is_shaking"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"reset": {
|
||||||
|
"on_entry": [
|
||||||
|
"/function sf/nba/lighting/remove",
|
||||||
|
"/tag @s remove silverlabs_nat:light_source"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.furniture_moved": {
|
||||||
|
"initial_state": "not_moving",
|
||||||
|
"states": {
|
||||||
|
"not_moving": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"moving": "math.abs(q.position_delta(0)) > 0.01 || math.abs(q.position_delta(1)) > 0.01 || math.abs(q.position_delta(2)) > 0.01 || q.is_in_lava"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"moving": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:drop_egg"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.furniture_hit": {
|
||||||
|
"initial_state": "not_hit",
|
||||||
|
"states": {
|
||||||
|
"not_hit": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"hit": "query.property('silverlabs_nat:furniture_hit')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"destroy": "query.is_shaking"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hit": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:furniture_not_hit",
|
||||||
|
"/playsound dig.stone @a[r=16] ~ ~ ~ 0.75 1.45"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"destroy": "query.is_shaking"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"not_hit": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"destroy": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.furniture_spawn": {
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"just_spawned": "query.property('silverlabs_nat:just_spawned')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"just_spawned": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:finish_spawned",
|
||||||
|
"/playsound dig.stone @a[r=16] ~ ~ ~ 0.75 1.45"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.firefly_jar.furniture_remove": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"egg_drop": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"egg_drop": {
|
||||||
|
"on_entry": [
|
||||||
|
"/loot spawn ~0.5 ~0.5 ~0.5 loot \"sf/nba/items/firefly_jar.loot\""
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"dropped_egg": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dropped_egg": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:remove"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.giraffe.head_collision": {
|
||||||
|
"initial_state": "head_normal",
|
||||||
|
"states": {
|
||||||
|
"head_normal": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:set_head_normal"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"head_low": "q.has_rider && q.rider_head_x_rotation(0) >= 45"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"head_low": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:set_head_low"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"head_normal": "!q.has_rider || q.rider_head_x_rotation(0) < 45"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.hamster.riding_check": {
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:remove_move_away"],
|
||||||
|
"transitions": [
|
||||||
|
{ "riding": "q.is_riding" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"riding": {
|
||||||
|
"transitions": [
|
||||||
|
{ "unriding": "!q.is_riding" }
|
||||||
|
],
|
||||||
|
"on_exit": ["@s silverlabs_nat:move_away"]
|
||||||
|
},
|
||||||
|
"unriding": {
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "q.state_time >= 3.0" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.hamster.variant_fixer": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "variant_0": "q.had_component_group('silverlabs_nat:variant_0')" },
|
||||||
|
{ "variant_1": "q.had_component_group('silverlabs_nat:variant_1')" },
|
||||||
|
{ "variant_2": "q.had_component_group('silverlabs_nat:variant_2')" },
|
||||||
|
{ "variant_3": "q.had_component_group('silverlabs_nat:variant_3')" },
|
||||||
|
{ "variant_4": "q.had_component_group('silverlabs_nat:variant_4')" },
|
||||||
|
{ "variant_5": "q.had_component_group('silverlabs_nat:variant_5')" },
|
||||||
|
{ "variant_6": "q.had_component_group('silverlabs_nat:variant_6')" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variant_0": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:set_variant_black"]
|
||||||
|
},
|
||||||
|
"variant_1": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:set_variant_blackwhite"]
|
||||||
|
},
|
||||||
|
"variant_2": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:set_variant_brown"]
|
||||||
|
},
|
||||||
|
"variant_3": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:set_variant_grey"]
|
||||||
|
},
|
||||||
|
"variant_4": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:set_variant_orange"]
|
||||||
|
},
|
||||||
|
"variant_5": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:set_variant_peach"]
|
||||||
|
},
|
||||||
|
"variant_6": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:set_variant_white"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.hamster_wheel.initialize": {
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"initialize": "!query.property('silverlabs_nat:initialized')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"initialize": {
|
||||||
|
"on_entry": [
|
||||||
|
"/function sf/nba/cardinal_orientation",
|
||||||
|
"@s silverlabs_nat:initialized"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.hedgehog.hit": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"hit": "query.property('silverlabs_nat:hit')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hit": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:hedgehog_hit",
|
||||||
|
"@s silverlabs_nat:remove_projectile"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"fallback": "q.state_time > 3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fallback": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:hedgehog_hit",
|
||||||
|
"@s silverlabs_nat:remove_projectile"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.block_animals.hippo.ram_watcher": {
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "ram_attack": "q.is_casting" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ram_attack": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:hippo_ram_attack",
|
||||||
|
"v.ram_attack_delay = query.life_time + 1.5;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "query.life_time > (v.ram_attack_delay ?? 0)" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.info_book.orient": {
|
||||||
|
"initial_state": "not_oriented",
|
||||||
|
"states": {
|
||||||
|
"not_oriented": {
|
||||||
|
"on_entry": [
|
||||||
|
"/function sf/nba/cardinal_orientation"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"oriented": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"oriented": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:oriented"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.info_book.hit": {
|
||||||
|
"initial_state": "not_hit",
|
||||||
|
"states": {
|
||||||
|
"not_hit": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"hit": "query.property('silverlabs_nat:hit')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hit": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:not_hit"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"not_hit": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.kiwi.digging_control": {
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"init": "!q.is_tamed"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"on_entry": [
|
||||||
|
"/event entity @s silverlabs_nat:end_feeling_happy",
|
||||||
|
"/event entity @s silverlabs_nat:scenting"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"test_digging_success": "query.property('silverlabs_nat:digging_states') == 'test_digging_success'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"test_digging_success": {
|
||||||
|
"on_entry": [
|
||||||
|
"/function sf/nba/gameplay/digging/init_digging"
|
||||||
|
],
|
||||||
|
"on_exit": [
|
||||||
|
"v.stand_delay_trigger = query.life_time + 2;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"digging_successful": "query.property('silverlabs_nat:digging_states') == 'successful'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"digging_unsuccessful": "query.property('silverlabs_nat:digging_states') == 'unsuccessful'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"digging_successful": {
|
||||||
|
"on_entry": [
|
||||||
|
"/function sf/nba/gameplay/digging/digging_loot"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"feeling_happy": "query.life_time >= v.stand_delay_trigger"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"digging_unsuccessful": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "query.life_time >= v.stand_delay_trigger"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"feeling_happy": {
|
||||||
|
"on_entry": [
|
||||||
|
"/event entity @s silverlabs_nat:feeling_happy"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.kiwi.sniffing_control": {
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"start_sniffing": "!q.is_tamed && (query.property('silverlabs_nat:digging_states') == 'trigger_digging')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start_sniffing": {
|
||||||
|
"on_entry": [
|
||||||
|
"/function sf/nba/gameplay/digging/init_sniffing"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "query.property('silverlabs_nat:digging_states') != 'trigger_digging'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.kiwi.pickup_control": {
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"start_sniffing": "q.is_tamed && !q.is_item_name_any('slot.weapon.mainhand', 'minecraft:wheat')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start_sniffing": {
|
||||||
|
"on_entry": [
|
||||||
|
"/replaceitem entity @s slot.weapon.mainhand 0 wheat"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"start_sniffing": "!q.is_tamed || q.is_item_name_any('slot.weapon.mainhand', 'minecraft:wheat')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.kiwi.following_owner_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:not_following_owner"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "following": "!q.is_sitting && q.is_tamed" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"following": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:is_following_owner"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "q.is_sitting || !q.is_tamed" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.reptile_tail.flop": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"flop": "q.is_on_ground && !q.is_in_water"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"flop": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:reptile_tail_flop"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "!q.is_on_ground || q.is_in_water"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.mole.trail": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"state_check": "(math.abs(q.position_delta(0)) > 0.01|| math.abs(q.position_delta(2)) > 0.01) && query.property('silverlabs_nat:mole_state') != 'unrolled'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state_check_baby": "(math.abs(q.position_delta(0)) > 0.01|| math.abs(q.position_delta(2)) > 0.01) && query.property('silverlabs_nat:mole_state') != 'unrolled' && q.is_baby"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"state_check": {
|
||||||
|
"on_entry": [
|
||||||
|
"/execute positioned ~~~ unless entity @e[type=silverlabs_nat:dirt_trail,r=0.5] run summon silverlabs_nat:dirt_trail ~ ~ ~"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "(1.0)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"state_check_baby": {
|
||||||
|
"on_entry": [
|
||||||
|
"/execute positioned ~~~ unless entity @e[type=silverlabs_nat:dirt_trail,r=0.5] run summon silverlabs_nat:dirt_trail ~ ~ ~ ~ ~ silverlabs_nat:baby"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "(1.0)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.ostrich.egg_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.cooldown_timer = 0;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"remove": "query.property('silverlabs_nat:egg_protector') && q.has_rider"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cooldown": "query.property('silverlabs_nat:egg_protector') && !q.has_target"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"cooldown": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.cooldown_timer = query.life_time;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"remove": "q.has_rider"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "!query.property('silverlabs_nat:egg_protector') || q.has_target"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"egg_check": "query.life_time >= (v.cooldown_timer + 6.0)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"egg_check": {
|
||||||
|
"on_entry": [
|
||||||
|
"/execute unless entity @e[type=silverlabs_nat:ostrich_egg,c=1,r=24] run event entity @s silverlabs_nat:remove_egg_protector"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:remove_egg_protector"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.ostrich.flap": {
|
||||||
|
"initial_state": "grounded",
|
||||||
|
"states": {
|
||||||
|
"grounded": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"flapping": "query.property('silverlabs_nat:has_rider') && !q.is_on_ground"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"flapping": {
|
||||||
|
"on_entry": [
|
||||||
|
"/effect @s slow_falling 2 0 true"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"grounded": "q.is_on_ground || !query.property('silverlabs_nat:has_rider')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.ostrich_egg.on_hatch": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"on_hatch": "q.is_transforming"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"on_hatch": {
|
||||||
|
"on_entry": [
|
||||||
|
"/event entity @e[c=1,type=silverlabs_nat:ostrich,r=12] silverlabs_nat:remove_egg_protector"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.otter.eat": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.eat_step = 0;",
|
||||||
|
"v.float_delay = query.life_time + 1;",
|
||||||
|
"@s silverlabs_nat:not_floating"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"float": "(query.life_time > (v.float_delay ?? 0)) && q.is_item_equipped(0) && q.is_in_water && (math.random_integer(1,100) == 100)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"give_to_player": "(query.life_time > (v.float_delay ?? 0)) && q.is_item_equipped(0) && (math.random_integer(1,100) == 100)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"float": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:is_floating",
|
||||||
|
"v.eat_delay = query.life_time + math.random(2,5);"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "!q.is_item_equipped(0) || !q.is_in_water || (q.modified_move_speed >= 0.075)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"eat": "(query.life_time > (v.eat_delay ?? 0))"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"eat": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.eat_step = (v.eat_step ?? 0) + 1;",
|
||||||
|
"v.eat_delay = query.life_time + 0.15;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"munch": "((v.eat_step ?? 0) < 3) && (query.life_time > (v.eat_delay ?? 0))"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"digest": "(query.life_time > (v.eat_delay ?? 0))"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"munch": {
|
||||||
|
"on_entry": ["/playsound mob.fox.eat @a ~ ~ ~"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"eat": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"digest": {
|
||||||
|
"on_entry": [
|
||||||
|
"/playsound mob.fox.eat @a ~ ~ ~ 1 1.2",
|
||||||
|
"/replaceitem entity @s slot.inventory 0 air",
|
||||||
|
"/replaceitem entity @s slot.weapon.mainhand 0 air",
|
||||||
|
"@s silverlabs_nat:otter_on_finish_eat",
|
||||||
|
"@s silverlabs_nat:not_floating"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"give_to_player": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:give_item_to_player"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "!q.is_item_equipped(0)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.otter.item_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"test": "q.is_item_equipped(0)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"on_entry": ["/scriptevent silverlabs_nat:otter_check"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "!q.is_item_equipped(0)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.piranha.attack": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.attack_start = 0.0;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "attack": "q.is_delayed_attacking" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"attack": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.attack_start = q.life_time;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "apply_damage": "q.life_time >= v.attack_start + 0.3" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"apply_damage": {
|
||||||
|
"on_entry": [
|
||||||
|
"/damage @e[family=!silverlabs_nat:piranha, r=2, c=1] 1 none",
|
||||||
|
"v.despawn_time = q.life_time;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "despawn": "q.life_time >= v.despawn_time + 0.25" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"despawn": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:despawn"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "1" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.raccoon": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"is_searching_item": "query.property('silverlabs_nat:search_state') == 'searching_item'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"is_searching_item": {
|
||||||
|
"on_entry": ["/scriptevent silverlabs_nat:raccoon_searching_item"],
|
||||||
|
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"cancel_searching_item": "query.property('silverlabs_nat:search_state') == 'cancel_searching_item'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "query.property('silverlabs_nat:search_state') != 'searching_item'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"cancel_searching_item": {
|
||||||
|
"on_entry": ["/scriptevent silverlabs_nat:raccoon_cancel_searching_item"],
|
||||||
|
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "query.property('silverlabs_nat:search_state') != 'cancel_searching_item'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.ray.main": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:complete_attack"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "escape": "!q.is_powered && q.is_avoiding_mobs" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"escape": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.escape_timer = query.life_time + 3;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "hide": "query.life_time > (v.escape_timer ?? 0)" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hide": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.hide_timer = query.life_time + 3;",
|
||||||
|
"@s silverlabs_nat:start_hide"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "(query.life_time > (v.hide_timer ?? 0)) || !q.is_powered"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.red_panda.sleep_stand": {
|
||||||
|
"initial_state": "init",
|
||||||
|
"states": {
|
||||||
|
"init": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"wake_up": "query.property('silverlabs_nat:red_panda_energy') >= 10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fall_asleep": "query.property('silverlabs_nat:red_panda_energy') < 10 && !query.property('silverlabs_nat:red_panda_jolt_awake') && !q.is_moving && !q.is_in_water_or_rain"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"wake_up": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:awake"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"awake": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"awake": {
|
||||||
|
"animations": [
|
||||||
|
"duration"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"fall_asleep": "query.property('silverlabs_nat:red_panda_energy') < 10 && !query.property('silverlabs_nat:red_panda_jolt_awake') && !q.is_moving && !q.is_in_water_or_rain"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"awake_2": "q.anim_time >= 1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"awake_2": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:decrement_energy"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"standing": "math.random_integer(0, 20) == 0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"awake": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"standing": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:start_standing"
|
||||||
|
],
|
||||||
|
"on_exit": [
|
||||||
|
"@s silverlabs_nat:stop_standing"
|
||||||
|
],
|
||||||
|
"animations": [
|
||||||
|
"duration"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"awake": "q.anim_time >= math.die_roll(3, 0.5, 4) || q.is_moving"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fall_asleep": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:sleeping"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"sleeping": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sleeping": {
|
||||||
|
"animations": [
|
||||||
|
"duration"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"wake_up": "query.property('silverlabs_nat:red_panda_energy') >= 960 || query.property('silverlabs_nat:red_panda_jolt_awake')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sleeping_2": "q.anim_time >= 1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sleeping_2": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:increment_energy"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"sleeping": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.block_animals.rhino.ram_watcher": {
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"/tag @s remove ram_attack",
|
||||||
|
"@s silverlabs_nat:stop_ram"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "start_ram_attack": "q.is_casting" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start_ram_attack": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.ram_attack_delay = query.life_time + 2.2;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "!q.is_casting" },
|
||||||
|
{
|
||||||
|
"using_ram_attack": "query.life_time > (v.ram_attack_delay ?? 0)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"using_ram_attack": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:rhino_ram_attack",
|
||||||
|
"/tag @s add ram_attack",
|
||||||
|
"@s silverlabs_nat:start_ram",
|
||||||
|
"v.ram_attack_end_delay = query.life_time + 1.95;"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "query.life_time > (v.ram_attack_end_delay ?? 0)" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.block_animals.rhino.angry_watcher": {
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "scared": "q.has_target" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"scared": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:rhino_angry"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "!q.has_target" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.skunk_spray": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"spraying": "query.property('silverlabs_nat:is_spraying') == true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"spraying": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "query.property('silverlabs_nat:is_spraying') == false"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:skunk_spray"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.skunk.breed_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:set_not_breeding"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "breeding": "q.is_in_love" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"breeding": {
|
||||||
|
"on_entry": [
|
||||||
|
"@s silverlabs_nat:set_is_breeding"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "!q.is_in_love" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.slug.bounce": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:can_detect_bounce"],
|
||||||
|
"transitions": [
|
||||||
|
{ "bounce": "query.property('silverlabs_nat:bounce')" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"bounce": {
|
||||||
|
"on_entry": [
|
||||||
|
"v.delay = 2;",
|
||||||
|
"v.current_delay = query.life_time;",
|
||||||
|
"/scriptevent silverlabs_nat:should_bounce_player @p"
|
||||||
|
],
|
||||||
|
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "(query.life_time - v.current_delay >= v.delay)" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.snail.crush_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "test": "query.property('silverlabs_nat:was_stepped_on')" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:snail_crush_check"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "!query.property('silverlabs_nat:was_stepped_on')" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.snail.catch_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "test": "query.property('silverlabs_nat:was_caught')" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:snail_bucket"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "!query.property('silverlabs_nat:was_caught')" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.snail.lay_egg": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "ready": "q.is_pregnant" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ready": {
|
||||||
|
"transitions": [
|
||||||
|
{ "done": "!q.is_pregnant" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"done": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:snailegg_formed"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "1" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.snake.digest": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "digest": "query.property('silverlabs_nat:digested_item')" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"digest": {
|
||||||
|
"on_entry": [
|
||||||
|
"/replaceitem entity @s slot.inventory 0 air",
|
||||||
|
"/replaceitem entity @s slot.weapon.mainhand 0 air",
|
||||||
|
"@s silverlabs_nat:snake_on_finish_eat"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "1" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.snake.food_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "test": "q.is_item_equipped(0)" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"on_entry": [
|
||||||
|
"/scriptevent silverlabs_nat:snake_check"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "!q.is_item_equipped(0)" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"controller.animation.silverlabs_nat.snake.wake_up_check": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "wake_up": "q.is_in_love" },
|
||||||
|
{ "can_sleep": "!q.is_in_love" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"wake_up": {
|
||||||
|
"on_entry": [
|
||||||
|
"/tag @s add woken_up"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "can_sleep": "!q.is_in_love" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"can_sleep": {
|
||||||
|
"on_entry": [
|
||||||
|
"/tag @s remove woken_up"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "wake_up": "q.is_in_love" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.termite.chew_watcher": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{ "chewing": "query.property('silverlabs_nat:is_chewing')" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"chewing": {
|
||||||
|
"on_exit": [
|
||||||
|
"/scriptevent silverlabs_nat:termite_chew"
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{ "default": "!query.property('silverlabs_nat:is_chewing')" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.vulture.item_equipped": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"on_equip": "!query.property('silverlabs_nat:is_item_equipped') && q.is_item_equipped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"on_unequip": "query.property('silverlabs_nat:is_item_equipped') && !q.is_item_equipped"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"on_equip": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:set_item_equipped"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "query.property('silverlabs_nat:is_item_equipped')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"on_unequip": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:set_item_equipped"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"default": "!query.property('silverlabs_nat:is_item_equipped')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animation_controllers": {
|
||||||
|
"controller.animation.silverlabs_nat.water_drinkable": {
|
||||||
|
"initial_state": "default",
|
||||||
|
"states": {
|
||||||
|
"default": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"can_use": "!q.is_baby"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"can_use": {
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"can_drink": "q.is_on_ground ? {t.x_offset = -math.sin(q.body_y_rotation) * 2.5; t.z_offset = math.cos(q.body_y_rotation) * 2.5; v.can_drink = q.relative_block_has_any_tag(t.x_offset, -1.0, t.z_offset, 'water');}: {v.can_drink = 0;}; return (v.can_drink ?? 0) && !query.property('silverlabs_nat:can_drink');"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"can_move_to_water": "query.property('silverlabs_nat:can_drink') && !(v.can_drink ?? 0)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"can_drink": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:can_drink"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"can_use": "query.property('silverlabs_nat:can_drink')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"can_move_to_water": {
|
||||||
|
"on_entry": ["@s silverlabs_nat:can_move_to_water"],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"can_use": "!query.property('silverlabs_nat:can_drink')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animations": {
|
||||||
|
"animation.silverlabs_nat.alligator.defensive_mode_check": {
|
||||||
|
"loop": true,
|
||||||
|
"animation_length": 1.0,
|
||||||
|
"timeline": {
|
||||||
|
"0.0": [
|
||||||
|
"/execute at @s if entity @e[family=silverlabs_nat:alligator_egg,r=10] run event entity @s silverlabs_nat:defending_eggs",
|
||||||
|
"/execute at @s unless entity @e[family=silverlabs_nat:alligator_egg,r=10] run event entity @s silverlabs_nat:not_defending_eggs"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animations": {
|
||||||
|
"animation.silverlabs_nat.bear.harvest_sensor": {
|
||||||
|
"loop": true,
|
||||||
|
"animation_length": 3.0,
|
||||||
|
"timeline": {
|
||||||
|
"1.5": [
|
||||||
|
"@s silverlabs_nat:harvest_sensor"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"format_version": "1.10.0",
|
||||||
|
"animations": {
|
||||||
|
"animation.silverlabs_nat.beaver.get_stick": {
|
||||||
|
"loop": true,
|
||||||
|
"animation_length": 1.0,
|
||||||
|
"timeline": {
|
||||||
|
"0.0": [
|
||||||
|
"/replaceitem entity @s slot.weapon.mainhand 0 stick"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"animation.silverlabs_nat.beaver.find_stick": {
|
||||||
|
"loop": true,
|
||||||
|
"animation_length": 1.0,
|
||||||
|
"timeline": {
|
||||||
|
"0.0": [
|
||||||
|
"@s silverlabs_nat:find_stick"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||