diff --git a/.gitignore b/.gitignore index 94af6ee..48b4aca 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,16 @@ Thumbs.db *.swp *.swo +# Build artifacts +*.mcaddon +*.mcpack +addon/build/ + +# Environment +.env + +# Server data (Docker volumes are external, but just in case) +server-data/ + # Claude Code .claude/ diff --git a/CLAUDE.md b/CLAUDE.md index 7e1ba32..c7a3605 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,50 +1,64 @@ -# Minecraft AI World - -This is a Claude Code workspace for interacting with a Minecraft Bedrock world via the mc-ai-bridge MCP server. - -## Connection - -The mc-ai-bridge runs at `10.0.0.247`: -- **WebSocket** (Minecraft → Bridge): port `3001` -- **MCP HTTP** (Claude → Bridge): port `3002` - -To connect Minecraft Bedrock to the bridge, run this command in-game: -``` -/connect 10.0.0.247:3001 -``` - -## Available MCP Tools - -### `minecraft_command` -Execute any slash command in Minecraft. Do NOT include the leading `/`. -- `command` (string): e.g. `"give @p diamond 64"`, `"tp @p 100 64 200"`, `"time set night"` - -### `minecraft_chat` -Send a chat message visible in Minecraft. -- `message` (string): The message to send -- `player` (string, optional): Target player for `/tell`. Omit to broadcast with `/say`. - -### `minecraft_build` -Execute a batch of build commands with rate limiting. Max 200 commands per call. Only `setblock`, `fill`, `clone`, and `structure` commands are allowed. -- `commands` (string[]): e.g. `["setblock 10 64 10 stone", "fill 10 64 10 20 64 20 glass"]` - -### `minecraft_get_events` -Get recent game events from the in-memory event buffer. -- `count` (number, optional): Number of events to return (default 20, max 100) -- `type` (string, optional): Filter by event type, e.g. `"PlayerMessage"`, `"BlockChanged"` - -### `minecraft_get_status` -Check if Minecraft is connected and get status info (player name, uptime, subscriptions, queue stats). No parameters. - -### `minecraft_subscribe` -Subscribe to Bedrock event types. Available events: -`PlayerMessage`, `BlockChanged`, `PlayerTransform`, `ItemUsed`, `ItemAcquired`, `ItemCrafted`, `MobKilled`, `MobInteracted`, `PlayerTravelled`, `PlayerDied`, `BossKilled` - -- `event` (string): Event type to subscribe to - -## Tips - -- Always call `minecraft_get_status` first to verify Minecraft is connected before issuing commands. -- Subscribe to `PlayerMessage` to receive chat from the player. -- Use `minecraft_build` for multi-block constructions — it handles rate limiting automatically. -- Coordinates in Minecraft are (X, Y, Z) where Y is vertical height. +# Minecraft AI World + +This is a Claude Code workspace for interacting with a Minecraft Bedrock world via the mc-ai-bridge MCP server. + +## Multi-World Architecture + +Four Bedrock servers on `10.0.0.247`, connected via native `/transfer` (no proxy): + +| Server | Port | Purpose | +|--------|------|---------| +| Lobby | 19132 | Main entry point (adventure mode) | +| Jamie | 19133 | Jamie's survival world | +| Lyla | 19134 | Lyla's survival world | +| Mya | 19135 | Mya's survival world | + +Players connect to `10.0.0.247:19132` (lobby) and use portal zones to transfer to child worlds. +Child worlds have a hub-return addon (compass, `!hub`/`!lobby` commands, portal zone) to transfer back. + +## Connection + +The mc-ai-bridge runs at `10.0.0.247`: +- **WebSocket** (Minecraft → Bridge): port `3001` +- **MCP HTTP** (Claude → Bridge): port `3002` + +To connect Minecraft Bedrock to the bridge, run this command in-game: +``` +/connect 10.0.0.247:3001 +``` + +## Available MCP Tools + +### `minecraft_command` +Execute any slash command in Minecraft. Do NOT include the leading `/`. +- `command` (string): e.g. `"give @p diamond 64"`, `"tp @p 100 64 200"`, `"time set night"` + +### `minecraft_chat` +Send a chat message visible in Minecraft. +- `message` (string): The message to send +- `player` (string, optional): Target player for `/tell`. Omit to broadcast with `/say`. + +### `minecraft_build` +Execute a batch of build commands with rate limiting. Max 200 commands per call. Only `setblock`, `fill`, `clone`, and `structure` commands are allowed. +- `commands` (string[]): e.g. `["setblock 10 64 10 stone", "fill 10 64 10 20 64 20 glass"]` + +### `minecraft_get_events` +Get recent game events from the in-memory event buffer. +- `count` (number, optional): Number of events to return (default 20, max 100) +- `type` (string, optional): Filter by event type, e.g. `"PlayerMessage"`, `"BlockChanged"` + +### `minecraft_get_status` +Check if Minecraft is connected and get status info (player name, uptime, subscriptions, queue stats). No parameters. + +### `minecraft_subscribe` +Subscribe to Bedrock event types. Available events: +`PlayerMessage`, `BlockChanged`, `PlayerTransform`, `ItemUsed`, `ItemAcquired`, `ItemCrafted`, `MobKilled`, `MobInteracted`, `PlayerTravelled`, `PlayerDied`, `BossKilled` + +- `event` (string): Event type to subscribe to + +## Tips + +- Always call `minecraft_get_status` first to verify Minecraft is connected before issuing commands. +- Subscribe to `PlayerMessage` to receive chat from the player. +- Use `minecraft_build` for multi-block constructions — it handles rate limiting automatically. +- Coordinates in Minecraft are (X, Y, Z) where Y is vertical height. diff --git a/addon/README.md b/addon/README.md new file mode 100644 index 0000000..94d5a61 --- /dev/null +++ b/addon/README.md @@ -0,0 +1,51 @@ +# Spark Dragon Pet Addon + +A custom Minecraft Bedrock addon that adds **Spark** — a tameable mini dragon pet with real personality. + +## Features + +- **Tameable**: Feed fish or salmon (33% chance per feed) to tame +- **Home Zone System**: Use a Dragon Whistle to set a home location +- **Daily Routine**: Explores by day, returns home at dusk, sleeps at night +- **Follow Mode**: Crouch + interact to toggle between follow and home-routine modes +- **Leashable & Nameable**: Full pet functionality +- **Fall Damage Immune**: Dragons don't take fall damage +- **Healable**: Feed fish/salmon to restore health + +## Building + +```bash +cd addon +bash build.sh +``` + +This produces `build/spark_dragon_pet.mcaddon`. + +## Installation + +1. **Windows**: Double-click the `.mcaddon` file to auto-import into Minecraft +2. **Manual**: Copy the packs to: + - `com.mojang/development_behavior_packs/spark_pet_BP/` + - `com.mojang/development_resource_packs/spark_pet_RP/` +3. Activate both packs on your world (Create/Edit World → Add-Ons) + +## Usage + +1. **Spawn**: `/summon silverlabs:spark_dragon ~ ~ ~` or use the spawn egg in creative +2. **Tame**: Hold fish or salmon and interact with the dragon +3. **Set Home**: Craft a Dragon Whistle, hold it, and interact with your tamed Spark +4. **Toggle Follow/Stay**: Crouch + interact with your tamed Spark +5. **Heal**: Feed fish (+4 HP) or salmon (+6 HP) + +## Daily Cycle (when home is set) + +| Time | Behavior | +|------|----------| +| Dawn–Noon (0–12000) | Exploring within 32 blocks of home | +| Dusk (12000–13000) | Navigating back home | +| Night (13000–23000) | Sleeping at home | +| Pre-dawn (23000–24000) | Waking up | + +## Entity ID + +`silverlabs:spark_dragon` diff --git a/addon/build.sh b/addon/build.sh new file mode 100644 index 0000000..aea67a9 --- /dev/null +++ b/addon/build.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BUILD_DIR="$SCRIPT_DIR/build" + +rm -rf "$BUILD_DIR" +mkdir -p "$BUILD_DIR" + +echo "Packaging Behavior Pack..." +cd "$SCRIPT_DIR/spark_pet_BP" +zip -r "$BUILD_DIR/spark_pet_BP.mcpack" . -x ".*" + +echo "Packaging Resource Pack..." +cd "$SCRIPT_DIR/spark_pet_RP" +zip -r "$BUILD_DIR/spark_pet_RP.mcpack" . -x ".*" + +echo "Creating .mcaddon bundle..." +cd "$BUILD_DIR" +zip -r "$BUILD_DIR/pets_4_jamies_stars.mcaddon" spark_pet_BP.mcpack spark_pet_RP.mcpack + +echo "" +echo "Build complete!" +echo " Output: $BUILD_DIR/pets_4_jamies_stars.mcaddon" +echo "" +echo "To install:" +echo " - Double-click the .mcaddon file on Windows to auto-import" +echo " - Or copy packs to com.mojang/development_behavior_packs/ and development_resource_packs/" diff --git a/addon/spark_pet_BP/blocks/dragon_basket.json b/addon/spark_pet_BP/blocks/dragon_basket.json new file mode 100644 index 0000000..987d372 --- /dev/null +++ b/addon/spark_pet_BP/blocks/dragon_basket.json @@ -0,0 +1,36 @@ +{ + "format_version": "1.21.0", + "minecraft:block": { + "description": { + "identifier": "silverlabs:dragon_basket", + "menu_category": { + "category": "items", + "group": "itemGroup.name.bed" + } + }, + "components": { + "minecraft:geometry": "geometry.dragon_basket", + "minecraft:material_instances": { + "*": { + "texture": "dragon_basket", + "render_method": "alpha_test" + } + }, + "minecraft:collision_box": { + "origin": [-7, 0, -7], + "size": [14, 5, 14] + }, + "minecraft:selection_box": { + "origin": [-7, 0, -7], + "size": [14, 5, 14] + }, + "minecraft:destructible_by_mining": { + "seconds_to_destroy": 1.0 + }, + "minecraft:destructible_by_explosion": { + "explosion_resistance": 2.0 + }, + "minecraft:map_color": "#8B5E3C" + } + } +} diff --git a/addon/spark_pet_BP/entities/dragon_egg.json b/addon/spark_pet_BP/entities/dragon_egg.json new file mode 100644 index 0000000..da2190a --- /dev/null +++ b/addon/spark_pet_BP/entities/dragon_egg.json @@ -0,0 +1,396 @@ +{ + "format_version": "1.21.0", + "minecraft:entity": { + "description": { + "identifier": "silverlabs:dragon_egg", + "is_spawnable": false, + "is_summonable": true, + "is_experimental": false, + "properties": { + "silverlabs:egg_stage": { + "type": "int", + "default": 0, + "range": [0, 3], + "client_sync": true + } + } + }, + "component_groups": { + "silverlabs:egg_cold": { + "minecraft:damage_sensor": { + "triggers": [ + { + "cause": "fire", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_warming", + "target": "self" + } + }, + { + "cause": "fire_tick", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_warming", + "target": "self" + } + }, + { + "cause": "lava", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_warming", + "target": "self" + } + }, + { + "cause": "magma", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_warming", + "target": "self" + } + }, + { + "cause": "entity_attack", + "deals_damage": true + }, + { + "cause": "all", + "deals_damage": false + } + ] + }, + "minecraft:timer": { + "time": 120, + "looping": false, + "time_down_event": { + "event": "silverlabs:advance_to_warming", + "target": "self" + } + }, + "minecraft:interact": { + "interactions": [ + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "blaze_powder" } + ] + }, + "event": "silverlabs:advance_to_warming", + "target": "self" + }, + "use_item": true, + "interact_text": "Warm Egg", + "play_sounds": "fire.fire" + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" } + ] + }, + "event": "", + "target": "self" + }, + "use_item": false, + "interact_text": "The egg feels cold..." + } + ] + } + }, + + "silverlabs:egg_warming": { + "minecraft:damage_sensor": { + "triggers": [ + { + "cause": "fire", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_hot", + "target": "self" + } + }, + { + "cause": "fire_tick", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_hot", + "target": "self" + } + }, + { + "cause": "lava", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_hot", + "target": "self" + } + }, + { + "cause": "magma", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_hot", + "target": "self" + } + }, + { + "cause": "entity_attack", + "deals_damage": true + }, + { + "cause": "all", + "deals_damage": false + } + ] + }, + "minecraft:timer": { + "time": 120, + "looping": false, + "time_down_event": { + "event": "silverlabs:advance_to_hot", + "target": "self" + } + }, + "minecraft:interact": { + "interactions": [ + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "blaze_powder" } + ] + }, + "event": "silverlabs:advance_to_hot", + "target": "self" + }, + "use_item": true, + "interact_text": "Heat Egg", + "play_sounds": "fire.fire" + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" } + ] + }, + "event": "", + "target": "self" + }, + "use_item": false, + "interact_text": "The egg is getting warmer..." + } + ] + } + }, + + "silverlabs:egg_hot": { + "minecraft:damage_sensor": { + "triggers": [ + { + "cause": "fire", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_hatching", + "target": "self" + } + }, + { + "cause": "fire_tick", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_hatching", + "target": "self" + } + }, + { + "cause": "lava", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_hatching", + "target": "self" + } + }, + { + "cause": "magma", + "deals_damage": false, + "on_damage": { + "event": "silverlabs:advance_to_hatching", + "target": "self" + } + }, + { + "cause": "entity_attack", + "deals_damage": true + }, + { + "cause": "all", + "deals_damage": false + } + ] + }, + "minecraft:timer": { + "time": 120, + "looping": false, + "time_down_event": { + "event": "silverlabs:advance_to_hatching", + "target": "self" + } + }, + "minecraft:interact": { + "interactions": [ + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "blaze_powder" } + ] + }, + "event": "silverlabs:advance_to_hatching", + "target": "self" + }, + "use_item": true, + "interact_text": "Ignite Egg", + "play_sounds": "fire.fire" + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" } + ] + }, + "event": "", + "target": "self" + }, + "use_item": false, + "interact_text": "The egg is almost ready!" + } + ] + } + }, + + "silverlabs:egg_hatching": { + "minecraft:damage_sensor": { + "triggers": [ + { + "cause": "all", + "deals_damage": false + } + ] + }, + "minecraft:spawn_entity": { + "entities": [ + { + "min_wait_time": 0, + "max_wait_time": 1, + "spawn_sound": "mob.enderdragon.growl", + "spawn_entity": "silverlabs:spark_dragon", + "num_to_spawn": 1, + "single_use": true + } + ] + }, + "minecraft:timer": { + "time": 3, + "looping": false, + "time_down_event": { + "event": "silverlabs:despawn_egg", + "target": "self" + } + } + }, + + "silverlabs:egg_despawning": { + "minecraft:instant_despawn": {} + } + }, + + "components": { + "minecraft:type_family": { + "family": ["dragon_egg"] + }, + "minecraft:physics": {}, + "minecraft:collision_box": { + "width": 0.5, + "height": 0.6 + }, + "minecraft:pushable": { + "is_pushable": false, + "is_pushable_by_piston": false + }, + "minecraft:knockback_resistance": { + "value": 1.0 + }, + "minecraft:persistent": {}, + "minecraft:scale": { + "value": 1.0 + }, + "minecraft:health": { + "value": 4, + "max": 4 + }, + "minecraft:loot": { + "table": "loot_tables/gameplay/egg_pickup.json" + }, + "minecraft:behavior.look_at_player": { + "priority": 7, + "look_distance": 6.0, + "probability": 0.02 + } + }, + + "events": { + "minecraft:entity_spawned": { + "add": { + "component_groups": ["silverlabs:egg_cold"] + } + }, + "silverlabs:advance_to_warming": { + "remove": { + "component_groups": ["silverlabs:egg_cold"] + }, + "add": { + "component_groups": ["silverlabs:egg_warming"] + }, + "set_property": { + "silverlabs:egg_stage": 1 + } + }, + "silverlabs:advance_to_hot": { + "remove": { + "component_groups": ["silverlabs:egg_warming"] + }, + "add": { + "component_groups": ["silverlabs:egg_hot"] + }, + "set_property": { + "silverlabs:egg_stage": 2 + } + }, + "silverlabs:advance_to_hatching": { + "remove": { + "component_groups": ["silverlabs:egg_hot"] + }, + "add": { + "component_groups": ["silverlabs:egg_hatching"] + }, + "set_property": { + "silverlabs:egg_stage": 3 + } + }, + "silverlabs:despawn_egg": { + "add": { + "component_groups": ["silverlabs:egg_despawning"] + } + } + } + } +} diff --git a/addon/spark_pet_BP/entities/dragon_gravestone.json b/addon/spark_pet_BP/entities/dragon_gravestone.json new file mode 100644 index 0000000..db6dac9 --- /dev/null +++ b/addon/spark_pet_BP/entities/dragon_gravestone.json @@ -0,0 +1,84 @@ +{ + "format_version": "1.21.0", + "minecraft:entity": { + "description": { + "identifier": "silverlabs:dragon_gravestone", + "is_spawnable": false, + "is_summonable": true, + "is_experimental": false + }, + "component_groups": { + "silverlabs:active": { + "minecraft:interact": { + "interactions": [ + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" } + ] + }, + "event": "silverlabs:break_gravestone", + "target": "self" + }, + "use_item": false, + "interact_text": "Collect Memorial", + "play_sounds": "random.anvil_land" + } + ] + } + }, + "silverlabs:breaking": { + "minecraft:loot": { + "table": "loot_tables/gameplay/gravestone_break.json" + }, + "minecraft:instant_despawn": {} + } + }, + "components": { + "minecraft:type_family": { + "family": ["dragon_gravestone"] + }, + "minecraft:physics": {}, + "minecraft:collision_box": { + "width": 0.5, + "height": 0.8 + }, + "minecraft:pushable": { + "is_pushable": false, + "is_pushable_by_piston": false + }, + "minecraft:knockback_resistance": { + "value": 1.0 + }, + "minecraft:damage_sensor": { + "triggers": [ + { "cause": "all", "deals_damage": false } + ] + }, + "minecraft:persistent": {}, + "minecraft:scale": { + "value": 0.8 + }, + "minecraft:health": { + "value": 999, + "max": 999 + } + }, + "events": { + "minecraft:entity_spawned": { + "add": { + "component_groups": ["silverlabs:active"] + } + }, + "silverlabs:break_gravestone": { + "remove": { + "component_groups": ["silverlabs:active"] + }, + "add": { + "component_groups": ["silverlabs:breaking"] + } + } + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_BP/entities/dragon_toy.json b/addon/spark_pet_BP/entities/dragon_toy.json new file mode 100644 index 0000000..8785c8d --- /dev/null +++ b/addon/spark_pet_BP/entities/dragon_toy.json @@ -0,0 +1,86 @@ +{ + "format_version": "1.21.0", + "minecraft:entity": { + "description": { + "identifier": "silverlabs:dragon_toy", + "is_spawnable": false, + "is_summonable": true, + "is_experimental": false + }, + "component_groups": { + "silverlabs:airborne": { + "minecraft:projectile": { + "on_hit": { + "definition_event": { + "event_trigger": { + "event": "silverlabs:on_landed", + "target": "self" + } + } + }, + "power": 1.5, + "gravity": 0.04, + "offset": [0, 0.5, 0], + "should_bounce": true + } + }, + "silverlabs:landed": { + "minecraft:physics": {}, + "minecraft:health": { + "value": 1, + "max": 1 + }, + "minecraft:pushable": { + "is_pushable": true, + "is_pushable_by_piston": true + }, + "minecraft:loot": { + "table": "loot_tables/gameplay/toy_return.json" + }, + "minecraft:timer": { + "time": 60, + "looping": false, + "time_down_event": { + "event": "silverlabs:despawn", + "target": "self" + } + } + }, + "silverlabs:despawning": { + "minecraft:instant_despawn": {} + } + }, + "components": { + "minecraft:type_family": { + "family": ["dragon_toy"] + }, + "minecraft:collision_box": { + "width": 0.3, + "height": 0.3 + }, + "minecraft:scale": { + "value": 0.6 + } + }, + "events": { + "minecraft:entity_spawned": { + "add": { + "component_groups": ["silverlabs:airborne"] + } + }, + "silverlabs:on_landed": { + "remove": { + "component_groups": ["silverlabs:airborne"] + }, + "add": { + "component_groups": ["silverlabs:landed"] + } + }, + "silverlabs:despawn": { + "add": { + "component_groups": ["silverlabs:despawning"] + } + } + } + } +} diff --git a/addon/spark_pet_BP/entities/spark_dragon.json b/addon/spark_pet_BP/entities/spark_dragon.json new file mode 100644 index 0000000..3228c10 --- /dev/null +++ b/addon/spark_pet_BP/entities/spark_dragon.json @@ -0,0 +1,992 @@ +{ + "format_version": "1.21.0", + "minecraft:entity": { + "description": { + "identifier": "silverlabs:spark_dragon", + "is_spawnable": true, + "is_summonable": true, + "is_experimental": false, + "properties": { + "silverlabs:growth_stage": { + "type": "int", + "default": 0, + "range": [0, 2], + "client_sync": true + }, + "silverlabs:beacon_active": { + "type": "bool", + "default": false, + "client_sync": true + }, + "silverlabs:mood": { + "type": "int", + "default": 1, + "range": [0, 2], + "client_sync": true + } + } + }, + "component_groups": { + "silverlabs:wild": { + "minecraft:behavior.tempt": { + "priority": 3, + "speed_multiplier": 0.8, + "items": ["fish", "salmon"], + "can_tempt_vertically": true + }, + "minecraft:behavior.avoid_mob_type": { + "priority": 4, + "max_dist": 8, + "walk_speed_multiplier": 1.0, + "entity_types": [ + { + "filters": { + "test": "is_family", + "subject": "other", + "value": "monster" + }, + "max_dist": 8, + "walk_speed_multiplier": 1.0 + } + ] + } + }, + + "silverlabs:tamed": { + "minecraft:is_tamed": {}, + "minecraft:behavior.follow_owner": { + "priority": 4, + "speed_multiplier": 0.8, + "start_distance": 8, + "stop_distance": 3 + }, + "minecraft:behavior.tempt": { + "priority": 3, + "speed_multiplier": 0.8, + "items": ["fish", "salmon"], + "can_tempt_vertically": true + }, + "minecraft:sittable": {}, + "minecraft:persistent": {}, + "minecraft:behavior.nearest_attackable_target": { + "priority": 3, + "entity_types": [ + { + "filters": { + "test": "is_family", + "subject": "other", + "value": "dragon_toy" + }, + "max_dist": 32 + } + ], + "must_see": false, + "reselect_targets": true + }, + "minecraft:entity_sensor": { + "sensor_range": 500, + "relative_range": false, + "minimum_count": 1, + "event_filters": { + "test": "is_family", + "subject": "other", + "value": "whistle_signal" + }, + "event": "silverlabs:whistle_called" + }, + "minecraft:behavior.melee_attack": { + "priority": 2, + "speed_multiplier": 1.0, + "reach_multiplier": 1.0, + "track_target": true + }, + "minecraft:attack": { + "damage": 1 + }, + "minecraft:on_target_escape": { + "event": "silverlabs:ball_caught", + "target": "self" + } + }, + + "silverlabs:tamed_following": { + "minecraft:is_tamed": {}, + "minecraft:behavior.follow_owner": { + "priority": 2, + "speed_multiplier": 0.8, + "start_distance": 8, + "stop_distance": 3 + }, + "minecraft:sittable": {}, + "minecraft:persistent": {}, + "minecraft:teleport": { + "dark_teleport_chance": 0.0, + "light_teleport_chance": 0.1, + "max_random_teleport_time": 10, + "min_random_teleport_time": 5, + "random_teleport_cube_size": [10, 5, 10], + "target_distance": 64, + "target_teleport_chance": 0.3 + } + }, + + "silverlabs:returning_fetch": { + "minecraft:behavior.follow_owner": { + "priority": 1, + "speed_multiplier": 1.0, + "start_distance": 15, + "stop_distance": 2 + }, + "minecraft:behavior.drop_item_for": { + "priority": 0, + "seconds_before_pickup": 0, + "cooldown": 60, + "drop_item_chance": 1.0, + "offering_distance": 5.0, + "speed_multiplier": 1.0, + "search_range": 20, + "search_height": 4, + "target_range": [5, 5, 5], + "time_of_day_range": [0.0, 1.0], + "loot_table": "loot_tables/gameplay/toy_return.json", + "entity_types": [ + { + "filters": { + "test": "is_family", + "subject": "other", + "value": "player" + }, + "max_dist": 20 + } + ] + }, + "minecraft:timer": { + "time": 5, + "looping": false, + "time_down_event": { + "event": "silverlabs:fetch_complete", + "target": "self" + } + } + }, + + "silverlabs:has_home": { + "minecraft:home": { + "restriction_radius": 32 + }, + "minecraft:scheduler": { + "min_delay_secs": 0, + "max_delay_secs": 0, + "scheduled_events": [ + { + "filters": { + "all_of": [ + { "test": "hourly_clock_time", "operator": ">=", "value": 0 }, + { "test": "hourly_clock_time", "operator": "<", "value": 12000 } + ] + }, + "event": "silverlabs:start_exploring" + }, + { + "filters": { + "all_of": [ + { "test": "hourly_clock_time", "operator": ">=", "value": 12000 }, + { "test": "hourly_clock_time", "operator": "<", "value": 13000 } + ] + }, + "event": "silverlabs:go_home" + }, + { + "filters": { + "all_of": [ + { "test": "hourly_clock_time", "operator": ">=", "value": 13000 }, + { "test": "hourly_clock_time", "operator": "<", "value": 23000 } + ] + }, + "event": "silverlabs:start_sleeping" + }, + { + "filters": { + "all_of": [ + { "test": "hourly_clock_time", "operator": ">=", "value": 23000 } + ] + }, + "event": "silverlabs:start_exploring" + } + ] + } + }, + + "silverlabs:exploring": { + "minecraft:behavior.random_stroll": { + "priority": 6, + "speed_multiplier": 0.5, + "xz_dist": 12, + "y_dist": 2 + }, + "minecraft:behavior.random_look_around": { + "priority": 8 + } + }, + + "silverlabs:going_home": { + "minecraft:behavior.go_home": { + "priority": 2, + "speed_multiplier": 0.8, + "interval": 1, + "goal_radius": 2, + "on_home": [ + { + "event": "silverlabs:start_sleeping", + "target": "self" + } + ] + } + }, + + "silverlabs:sleeping": { + "minecraft:is_sitting": {}, + "minecraft:behavior.look_at_player": { + "priority": 8, + "look_distance": 4.0 + } + }, + + "silverlabs:sitting": { + "minecraft:is_sitting": {} + }, + + "silverlabs:beacon_on": { + "minecraft:timer": { + "time": 12, + "looping": false, + "time_down_event": { + "event": "silverlabs:beacon_off", + "target": "self" + } + } + }, + + "silverlabs:tamed_called": { + "minecraft:is_tamed": {}, + "minecraft:behavior.follow_owner": { + "priority": 1, + "speed_multiplier": 1.0, + "start_distance": 200, + "stop_distance": 3 + }, + "minecraft:sittable": {}, + "minecraft:persistent": {}, + "minecraft:teleport": { + "dark_teleport_chance": 0.0, + "light_teleport_chance": 1.0, + "max_random_teleport_time": 3, + "min_random_teleport_time": 1, + "random_teleport_cube_size": [20, 10, 20], + "target_distance": 24, + "target_teleport_chance": 1.0 + } + }, + + "silverlabs:tamed_loot": { + "minecraft:loot": { + "table": "loot_tables/gameplay/dragon_death.json" + } + }, + + "silverlabs:guide_drop": { + "minecraft:behavior.drop_item_for": { + "priority": 1, + "seconds_before_pickup": 0, + "cooldown": 99999, + "drop_item_chance": 1.0, + "offering_distance": 5.0, + "speed_multiplier": 1.0, + "search_range": 10, + "search_height": 4, + "target_range": [5, 5, 5], + "time_of_day_range": [0.0, 1.0], + "loot_table": "loot_tables/gameplay/dragon_guide.json", + "entity_types": [ + { + "filters": { + "test": "is_family", + "subject": "other", + "value": "player" + }, + "max_dist": 16 + } + ] + }, + "minecraft:timer": { + "time": 10, + "looping": false, + "time_down_event": { + "event": "silverlabs:guide_dropped", + "target": "self" + } + } + }, + + "silverlabs:mood_happy": { + "minecraft:timer": { + "time": [480, 720], + "looping": false, + "time_down_event": { + "event": "silverlabs:mood_decay_to_content", + "target": "self" + } + } + }, + + "silverlabs:mood_content": { + "minecraft:timer": { + "time": [360, 600], + "looping": false, + "time_down_event": { + "event": "silverlabs:mood_decay_to_needy", + "target": "self" + } + } + }, + + "silverlabs:mood_needy": { + "minecraft:behavior.look_at_player": { + "priority": 3, + "look_distance": 10.0, + "probability": 0.1 + } + }, + + "silverlabs:stage_baby": { + "minecraft:is_baby": {}, + "minecraft:ageable": { + "duration": 1200, + "feed_items": ["fish", "salmon"], + "grow_up": { + "event": "silverlabs:grow_to_juvenile", + "target": "self" + } + }, + "minecraft:scale": { + "value": 0.4 + }, + "minecraft:collision_box": { + "width": 0.35, + "height": 0.3 + }, + "minecraft:movement": { + "value": 0.15 + }, + "minecraft:health": { + "value": 10, + "max": 10 + }, + "minecraft:behavior.drop_item_for": { + "priority": 5, + "seconds_before_pickup": 0, + "cooldown": 600, + "drop_item_chance": 0.6, + "offering_distance": 5.0, + "minimum_teleport_distance": 2.0, + "speed_multiplier": 1.0, + "search_range": 10, + "search_height": 2, + "target_range": [5, 5, 5], + "teleport_offset": [0, 1, 0], + "time_of_day_range": [0.0, 0.5], + "loot_table": "loot_tables/gameplay/gift_baby.json", + "entity_types": [ + { + "filters": { + "test": "is_family", + "subject": "other", + "value": "player" + }, + "max_dist": 16 + } + ] + }, + "minecraft:behavior.play": { + "priority": 5, + "speed_multiplier": 0.7, + "friend_types": [ + { + "filters": { + "test": "is_family", + "subject": "other", + "value": "spark_dragon" + } + } + ] + } + }, + + "silverlabs:stage_juvenile": { + "minecraft:scale": { + "value": 0.7 + }, + "minecraft:collision_box": { + "width": 0.5, + "height": 0.4 + }, + "minecraft:movement": { + "value": 0.2 + }, + "minecraft:health": { + "value": 20, + "max": 20 + }, + "minecraft:jump.static": { + "jump_power": 0.5 + }, + "minecraft:timer": { + "time": 1200, + "looping": false, + "time_down_event": { + "event": "silverlabs:grow_to_adult", + "target": "self" + } + }, + "minecraft:behavior.drop_item_for": { + "priority": 5, + "seconds_before_pickup": 0, + "cooldown": 480, + "drop_item_chance": 0.7, + "offering_distance": 5.0, + "minimum_teleport_distance": 2.0, + "speed_multiplier": 1.0, + "search_range": 12, + "search_height": 2, + "target_range": [5, 5, 5], + "teleport_offset": [0, 1, 0], + "time_of_day_range": [0.0, 0.5], + "loot_table": "loot_tables/gameplay/gift_juvenile.json", + "entity_types": [ + { + "filters": { + "test": "is_family", + "subject": "other", + "value": "player" + }, + "max_dist": 16 + } + ] + }, + "minecraft:behavior.play": { + "priority": 5, + "speed_multiplier": 0.8, + "friend_types": [ + { + "filters": { + "test": "is_family", + "subject": "other", + "value": "spark_dragon" + } + } + ] + }, + "minecraft:behavior.raid_garden": { + "priority": 6, + "speed_multiplier": 1.0, + "search_range": 12, + "search_height": 2, + "goal_radius": 1.0, + "max_to_eat": 2, + "initial_eat_delay": 20 + } + }, + + "silverlabs:stage_adult": { + "minecraft:scale": { + "value": 1.0 + }, + "minecraft:collision_box": { + "width": 0.6, + "height": 0.5 + }, + "minecraft:movement": { + "value": 0.25 + }, + "minecraft:health": { + "value": 30, + "max": 30 + }, + "minecraft:can_fly": {}, + "minecraft:navigation.fly": { + "can_path_over_water": true, + "can_path_from_air": true + }, + "minecraft:movement.fly": {}, + "minecraft:flying_speed": { + "value": 0.04 + }, + "minecraft:behavior.drop_item_for": { + "priority": 5, + "seconds_before_pickup": 0, + "cooldown": 300, + "drop_item_chance": 0.8, + "offering_distance": 5.0, + "minimum_teleport_distance": 2.0, + "speed_multiplier": 1.0, + "search_range": 16, + "search_height": 4, + "target_range": [5, 5, 5], + "teleport_offset": [0, 1, 0], + "time_of_day_range": [0.0, 0.5], + "loot_table": "loot_tables/gameplay/gift_adult.json", + "entity_types": [ + { + "filters": { + "test": "is_family", + "subject": "other", + "value": "player" + }, + "max_dist": 16 + } + ] + } + } + }, + + "components": { + "minecraft:type_family": { + "family": ["spark_dragon", "pet", "mob"] + }, + "minecraft:physics": {}, + "minecraft:pushable": { + "is_pushable": true, + "is_pushable_by_piston": true + }, + "minecraft:can_climb": {}, + "minecraft:navigation.walk": { + "can_path_over_water": true, + "avoid_water": true, + "avoid_damage_blocks": true + }, + "minecraft:movement.basic": { + "max_turn": 20.0 + }, + "minecraft:jump.static": {}, + "minecraft:tameable": { + "probability": 0.33, + "tame_items": ["fish", "salmon"], + "tame_event": { + "event": "silverlabs:on_tamed", + "target": "self" + } + }, + "minecraft:healable": { + "items": [ + { "item": "fish", "heal_amount": 4 }, + { "item": "salmon", "heal_amount": 6 } + ] + }, + "minecraft:leashable": { + "soft_distance": 4.0, + "hard_distance": 6.0, + "max_distance": 10.0 + }, + "minecraft:nameable": {}, + "minecraft:breathable": { + "total_supply": 15, + "suffocate_time": 0, + "breathes_air": true, + "breathes_water": false + }, + "minecraft:damage_sensor": { + "triggers": [ + { + "cause": "fall", + "deals_damage": false + } + ] + }, + "minecraft:behavior.float": { + "priority": 0 + }, + "minecraft:behavior.look_at_player": { + "priority": 7, + "look_distance": 8.0, + "probability": 0.02 + }, + "minecraft:behavior.random_look_around": { + "priority": 9 + }, + "minecraft:behavior.random_stroll": { + "priority": 8, + "speed_multiplier": 0.4, + "xz_dist": 7, + "y_dist": 2 + }, + "minecraft:interact": { + "interactions": [ + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "fish" }, + { "test": "has_component", "value": "minecraft:is_tamed" } + ] + }, + "event": "silverlabs:mood_boost", + "target": "self" + }, + "use_item": false + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "salmon" }, + { "test": "has_component", "value": "minecraft:is_tamed" } + ] + }, + "event": "silverlabs:mood_boost", + "target": "self" + }, + "use_item": false + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "potion" }, + { "test": "has_component", "value": "minecraft:is_tamed" } + ] + }, + "event": "silverlabs:mood_boost", + "target": "self" + }, + "use_item": true, + "interact_text": "Give Water" + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "amethyst_shard" }, + { "test": "has_component", "value": "minecraft:is_tamed" } + ] + }, + "event": "silverlabs:request_guide", + "target": "self" + }, + "use_item": true, + "interact_text": "Request Guide", + "play_sounds": "random.orb" + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "operator": "not", "value": "name_tag" }, + { "test": "is_sneaking", "subject": "other", "value": false }, + { "test": "has_component", "value": "minecraft:is_tamed" }, + { "test": "has_component", "value": "minecraft:is_sitting" } + ] + }, + "event": "silverlabs:on_stand", + "target": "self" + }, + "use_item": false, + "interact_text": "Get Up", + "play_sounds": "mob.wolf.bark" + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "operator": "not", "value": "name_tag" }, + { "test": "is_sneaking", "subject": "other", "value": false }, + { "test": "has_component", "value": "minecraft:is_tamed" }, + { "test": "has_component", "operator": "!=", "value": "minecraft:is_sitting" } + ] + }, + "event": "silverlabs:command_follow", + "target": "self" + }, + "use_item": false, + "interact_text": "Follow Me", + "play_sounds": "mob.wolf.bark" + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "bone" }, + { "test": "is_sneaking", "subject": "other", "value": true }, + { "test": "has_component", "value": "minecraft:is_tamed" }, + { "test": "has_component", "operator": "!=", "value": "minecraft:is_sitting" } + ] + }, + "event": "silverlabs:set_home", + "target": "self" + }, + "use_item": false, + "interact_text": "Set Home", + "play_sounds": "random.levelup" + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "bone" }, + { "test": "is_sneaking", "subject": "other", "value": true }, + { "test": "has_component", "value": "minecraft:is_tamed" }, + { "test": "has_component", "value": "minecraft:is_sitting" }, + { "test": "has_component", "value": "minecraft:home" } + ] + }, + "event": "silverlabs:command_go_home", + "target": "self" + }, + "use_item": false, + "interact_text": "Go Home", + "play_sounds": "note.pling" + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "operator": "not", "value": "name_tag" }, + { "test": "is_sneaking", "subject": "other", "value": true }, + { "test": "has_component", "value": "minecraft:is_tamed" }, + { "test": "has_component", "operator": "!=", "value": "minecraft:is_sitting" } + ] + }, + "event": "silverlabs:on_sit", + "target": "self" + }, + "use_item": false, + "interact_text": "Stay" + }, + { + "on_interact": { + "filters": { + "all_of": [ + { "test": "is_family", "subject": "other", "value": "player" }, + { "test": "has_equipment", "subject": "other", "domain": "hand", "operator": "not", "value": "name_tag" }, + { "test": "is_sneaking", "subject": "other", "value": true }, + { "test": "has_component", "value": "minecraft:is_tamed" }, + { "test": "has_component", "value": "minecraft:is_sitting" } + ] + }, + "event": "silverlabs:on_stand", + "target": "self" + }, + "use_item": false, + "interact_text": "Stand" + } + ] + }, + "minecraft:spawn_entity": {} + }, + + "events": { + "minecraft:entity_spawned": { + "add": { + "component_groups": ["silverlabs:wild", "silverlabs:stage_baby"] + } + }, + "silverlabs:on_tamed": { + "remove": { + "component_groups": ["silverlabs:wild"] + }, + "add": { + "component_groups": ["silverlabs:tamed", "silverlabs:tamed_loot", "silverlabs:guide_drop", "silverlabs:mood_happy"] + }, + "set_property": { + "silverlabs:mood": 2 + } + }, + "silverlabs:request_guide": { + "add": { "component_groups": ["silverlabs:guide_drop"] } + }, + "silverlabs:guide_dropped": { + "remove": { + "component_groups": ["silverlabs:guide_drop"] + } + }, + "silverlabs:mood_boost": { + "remove": { + "component_groups": ["silverlabs:mood_happy", "silverlabs:mood_content", "silverlabs:mood_needy"] + }, + "add": { + "component_groups": ["silverlabs:mood_happy"] + }, + "set_property": { + "silverlabs:mood": 2 + } + }, + "silverlabs:mood_decay_to_content": { + "remove": { + "component_groups": ["silverlabs:mood_happy"] + }, + "add": { + "component_groups": ["silverlabs:mood_content"] + }, + "set_property": { + "silverlabs:mood": 1 + } + }, + "silverlabs:mood_decay_to_needy": { + "remove": { + "component_groups": ["silverlabs:mood_content"] + }, + "add": { + "component_groups": ["silverlabs:mood_needy"] + }, + "set_property": { + "silverlabs:mood": 0 + } + }, + "silverlabs:grow_to_juvenile": { + "remove": { + "component_groups": ["silverlabs:stage_baby", "silverlabs:mood_happy", "silverlabs:mood_content", "silverlabs:mood_needy"] + }, + "add": { + "component_groups": ["silverlabs:stage_juvenile"] + }, + "set_property": { + "silverlabs:growth_stage": 1, + "silverlabs:mood": 1 + } + }, + "silverlabs:grow_to_adult": { + "remove": { + "component_groups": ["silverlabs:stage_juvenile"] + }, + "add": { + "component_groups": ["silverlabs:stage_adult", "silverlabs:mood_content"] + }, + "set_property": { + "silverlabs:growth_stage": 2, + "silverlabs:mood": 1 + } + }, + "silverlabs:ball_caught": { + "add": { + "component_groups": ["silverlabs:returning_fetch"] + } + }, + "silverlabs:fetch_complete": { + "remove": { + "component_groups": ["silverlabs:returning_fetch", "silverlabs:mood_happy", "silverlabs:mood_content", "silverlabs:mood_needy"] + }, + "add": { + "component_groups": ["silverlabs:tamed_following", "silverlabs:mood_happy"] + }, + "set_property": { + "silverlabs:mood": 2 + } + }, + "silverlabs:command_follow": { + "add": { + "component_groups": ["silverlabs:tamed_following", "silverlabs:beacon_on"] + }, + "remove": { + "component_groups": ["silverlabs:exploring", "silverlabs:sleeping", "silverlabs:going_home", "silverlabs:sitting", "silverlabs:returning_fetch", "silverlabs:tamed_called"] + }, + "set_property": { + "silverlabs:beacon_active": true + } + }, + "silverlabs:whistle_called": { + "add": { + "component_groups": ["silverlabs:tamed_called", "silverlabs:beacon_on"] + }, + "remove": { + "component_groups": ["silverlabs:exploring", "silverlabs:sleeping", "silverlabs:going_home", "silverlabs:sitting", "silverlabs:returning_fetch", "silverlabs:tamed_following"] + }, + "set_property": { + "silverlabs:beacon_active": true + } + }, + "silverlabs:activate_beacon": { + "add": { + "component_groups": ["silverlabs:beacon_on"] + }, + "set_property": { + "silverlabs:beacon_active": true + } + }, + "silverlabs:beacon_off": { + "remove": { + "component_groups": ["silverlabs:beacon_on", "silverlabs:tamed_called"] + }, + "add": { + "component_groups": ["silverlabs:tamed_following"] + }, + "set_property": { + "silverlabs:beacon_active": false + } + }, + "silverlabs:command_go_home": { + "add": { + "component_groups": ["silverlabs:going_home"] + }, + "remove": { + "component_groups": ["silverlabs:exploring", "silverlabs:tamed_following", "silverlabs:sitting", "silverlabs:returning_fetch"] + } + }, + "silverlabs:set_home": { + "add": { + "component_groups": ["silverlabs:has_home", "silverlabs:exploring"] + }, + "remove": { + "component_groups": ["silverlabs:tamed_following", "silverlabs:sleeping", "silverlabs:going_home", "silverlabs:sitting", "silverlabs:returning_fetch"] + } + }, + "silverlabs:start_exploring": { + "add": { + "component_groups": ["silverlabs:exploring"] + }, + "remove": { + "component_groups": ["silverlabs:sleeping", "silverlabs:going_home", "silverlabs:sitting", "silverlabs:returning_fetch"] + } + }, + "silverlabs:go_home": { + "add": { + "component_groups": ["silverlabs:going_home"] + }, + "remove": { + "component_groups": ["silverlabs:exploring", "silverlabs:sleeping", "silverlabs:returning_fetch"] + } + }, + "silverlabs:start_sleeping": { + "add": { + "component_groups": ["silverlabs:sleeping"] + }, + "remove": { + "component_groups": ["silverlabs:exploring", "silverlabs:going_home", "silverlabs:returning_fetch"] + } + }, + "silverlabs:on_sit": { + "add": { + "component_groups": ["silverlabs:sitting"] + }, + "remove": { + "component_groups": ["silverlabs:exploring", "silverlabs:going_home", "silverlabs:tamed_following", "silverlabs:returning_fetch"] + } + }, + "silverlabs:on_stand": { + "remove": { + "component_groups": ["silverlabs:sitting", "silverlabs:sleeping", "silverlabs:returning_fetch"] + }, + "add": { + "component_groups": ["silverlabs:tamed_following"] + } + } + } + } +} diff --git a/addon/spark_pet_BP/entities/whistle_signal.json b/addon/spark_pet_BP/entities/whistle_signal.json new file mode 100644 index 0000000..b7fe500 --- /dev/null +++ b/addon/spark_pet_BP/entities/whistle_signal.json @@ -0,0 +1,82 @@ +{ + "format_version": "1.21.0", + "minecraft:entity": { + "description": { + "identifier": "silverlabs:whistle_signal", + "is_spawnable": false, + "is_summonable": true, + "is_experimental": false + }, + "component_groups": { + "silverlabs:airborne": { + "minecraft:projectile": { + "on_hit": { + "definition_event": { + "event_trigger": { + "event": "silverlabs:on_landed", + "target": "self" + } + } + }, + "power": 1.2, + "gravity": 0.05, + "offset": [0, 0.5, 0], + "should_bounce": false + } + }, + "silverlabs:landed": { + "minecraft:physics": {}, + "minecraft:health": { + "value": 1, + "max": 1 + }, + "minecraft:loot": { + "table": "loot_tables/gameplay/whistle_return.json" + }, + "minecraft:timer": { + "time": 2, + "looping": false, + "time_down_event": { + "event": "silverlabs:despawn", + "target": "self" + } + } + }, + "silverlabs:despawning": { + "minecraft:instant_despawn": {} + } + }, + "components": { + "minecraft:type_family": { + "family": ["whistle_signal"] + }, + "minecraft:collision_box": { + "width": 0.1, + "height": 0.1 + }, + "minecraft:scale": { + "value": 0.01 + } + }, + "events": { + "minecraft:entity_spawned": { + "add": { + "component_groups": ["silverlabs:airborne"] + } + }, + "silverlabs:on_landed": { + "remove": { + "component_groups": ["silverlabs:airborne"] + }, + "add": { + "component_groups": ["silverlabs:landed"] + } + }, + "silverlabs:despawn": { + "add": { + "component_groups": ["silverlabs:despawning"] + } + } + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_BP/items/dragon_bones.json b/addon/spark_pet_BP/items/dragon_bones.json new file mode 100644 index 0000000..8d0eef6 --- /dev/null +++ b/addon/spark_pet_BP/items/dragon_bones.json @@ -0,0 +1,19 @@ +{ + "format_version": "1.21.120", + "minecraft:item": { + "description": { + "identifier": "silverlabs:dragon_bones", + "menu_category": { + "category": "items" + } + }, + "components": { + "minecraft:icon": "dragon_bones", + "minecraft:display_name": { + "value": "item.silverlabs:dragon_bones.name" + }, + "minecraft:max_stack_size": 1, + "minecraft:glint": true + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_BP/items/dragon_egg.json b/addon/spark_pet_BP/items/dragon_egg.json new file mode 100644 index 0000000..b336e77 --- /dev/null +++ b/addon/spark_pet_BP/items/dragon_egg.json @@ -0,0 +1,22 @@ +{ + "format_version": "1.21.120", + "minecraft:item": { + "description": { + "identifier": "silverlabs:dragon_egg", + "menu_category": { + "category": "items" + } + }, + "components": { + "minecraft:icon": "dragon_egg", + "minecraft:display_name": { + "value": "item.silverlabs:dragon_egg.name" + }, + "minecraft:max_stack_size": 1, + "minecraft:glint": true, + "minecraft:entity_placer": { + "entity": "silverlabs:dragon_egg" + } + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_BP/items/dragon_gravestone.json b/addon/spark_pet_BP/items/dragon_gravestone.json new file mode 100644 index 0000000..c71a0ba --- /dev/null +++ b/addon/spark_pet_BP/items/dragon_gravestone.json @@ -0,0 +1,22 @@ +{ + "format_version": "1.21.120", + "minecraft:item": { + "description": { + "identifier": "silverlabs:dragon_gravestone", + "menu_category": { + "category": "items" + } + }, + "components": { + "minecraft:icon": "dragon_gravestone", + "minecraft:display_name": { + "value": "item.silverlabs:dragon_gravestone.name" + }, + "minecraft:max_stack_size": 1, + "minecraft:glint": true, + "minecraft:entity_placer": { + "entity": "silverlabs:dragon_gravestone" + } + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_BP/items/dragon_toy.json b/addon/spark_pet_BP/items/dragon_toy.json new file mode 100644 index 0000000..456bb4f --- /dev/null +++ b/addon/spark_pet_BP/items/dragon_toy.json @@ -0,0 +1,26 @@ +{ + "format_version": "1.21.0", + "minecraft:item": { + "description": { + "identifier": "silverlabs:dragon_toy", + "menu_category": { + "category": "items" + } + }, + "components": { + "minecraft:icon": "dragon_toy", + "minecraft:display_name": { + "value": "item.silverlabs:dragon_toy.name" + }, + "minecraft:max_stack_size": 16, + "minecraft:throwable": { + "do_swing_animation": true, + "max_draw_duration": 0, + "scale_power_by_draw_duration": false + }, + "minecraft:projectile": { + "projectile_entity": "silverlabs:dragon_toy" + } + } + } +} diff --git a/addon/spark_pet_BP/items/dragon_whistle.json b/addon/spark_pet_BP/items/dragon_whistle.json new file mode 100644 index 0000000..567279b --- /dev/null +++ b/addon/spark_pet_BP/items/dragon_whistle.json @@ -0,0 +1,26 @@ +{ + "format_version": "1.21.0", + "minecraft:item": { + "description": { + "identifier": "silverlabs:dragon_whistle", + "menu_category": { + "category": "items" + } + }, + "components": { + "minecraft:icon": "dragon_whistle", + "minecraft:display_name": { + "value": "item.silverlabs:dragon_whistle.name" + }, + "minecraft:max_stack_size": 16, + "minecraft:throwable": { + "do_swing_animation": true, + "max_draw_duration": 0, + "scale_power_by_draw_duration": false + }, + "minecraft:projectile": { + "projectile_entity": "silverlabs:whistle_signal" + } + } + } +} diff --git a/addon/spark_pet_BP/loot_tables/gameplay/dragon_death.json b/addon/spark_pet_BP/loot_tables/gameplay/dragon_death.json new file mode 100644 index 0000000..a9250b3 --- /dev/null +++ b/addon/spark_pet_BP/loot_tables/gameplay/dragon_death.json @@ -0,0 +1,22 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { "type": "item", "name": "silverlabs:dragon_bones", "weight": 1 } + ] + }, + { + "rolls": 1, + "entries": [ + { "type": "item", "name": "silverlabs:dragon_gravestone", "weight": 1 } + ] + }, + { + "rolls": 1, + "entries": [ + { "type": "item", "name": "minecraft:name_tag", "weight": 1 } + ] + } + ] +} \ No newline at end of file diff --git a/addon/spark_pet_BP/loot_tables/gameplay/dragon_guide.json b/addon/spark_pet_BP/loot_tables/gameplay/dragon_guide.json new file mode 100644 index 0000000..f1c2fb9 --- /dev/null +++ b/addon/spark_pet_BP/loot_tables/gameplay/dragon_guide.json @@ -0,0 +1,33 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:written_book", + "weight": 1, + "functions": [ + { + "function": "set_book_contents", + "author": "SilverLABS", + "title": "Spark Dragon Guide", + "pages": [ + "§l§5Spark Dragon Guide§r\n\nWelcome, Dragon Keeper!\n\nThis guide covers everything you need to know about caring for your Spark Dragon companion.\n\n§oTurn the page to begin...§r", + "§l§6Getting Started§r\n\nTo hatch a Spark Dragon:\n\n§f1. Craft a §eDragon Basket§f and place it\n§f2. Place a §dSpark Dragon Egg§f nearby\n§f3. The egg will hatch into a baby!\n\nTo tame:\n§f• Hold §bRaw Cod§f or §cRaw Salmon§f\n§f• Interact with the baby dragon\n§f• Each attempt has a §a33%§f chance\n§f• Hearts appear when tamed!\n\n§7Name your dragon with a §eName Tag§7!§r", + "§l§6Commands§r\n\nOnce tamed, interact to command:\n\n§f• §eFollow Me§f - interact (standing)\n§f• §eStay§f - sneak + interact (sits)\n§f• §eStand§f - sneak + interact (sitting)\n§f• §eGet Up§f - interact while sitting\n§f• §eSet Home§f - sneak + bone (standing)\n§f• §eGo Home§f - sneak + bone (sitting)\n\n§7Commands cycle based on current state.§r", + "§l§6Feeding & Healing§r\n\nFeed your dragon to heal it:\n\n§f• §bRaw Cod§f: restores §a4 HP§f\n§f• §cRaw Salmon§f: restores §a6 HP§f\n\nFeeding fish and giving §9Water Bottles§f both §dimprove your dragon's mood§r!\n\n§7Tip: Water bottles are an easy mood boost — just brew or fill one at a water source.§r", + "§l§6Home & Basket§r\n\nSet up a home for your dragon:\n\n§f1. Place a §eDragon Basket§f\n§f2. Stand near it with your dragon\n§f3. Hold a §eBone§f and sneak + interact\n\nWith a home set, your dragon will:\n§f• Explore by day (32 block radius)\n§f• Return home at dusk\n§f• Sleep through the night\n§f• Wake at dawn to explore\n\n§7Send it home: sneak + bone while sitting.§r", + "§l§6Growth Stages§r\n\nDragons grow through 3 stages:\n\n§a1. Baby§f (small, 10 HP)\n Grows up by feeding or waiting\n\n§e2. Juvenile§f (medium, 20 HP)\n Timer-based growth (~20 min)\n May raid gardens!\n\n§c3. Adult§f (full size, 30 HP)\n Can fly! Drops better gifts.\n\n§7Feed fish to speed up baby growth.§r", + "§l§6Mood System§r\n\nYour dragon has feelings!\n\n§a★ Happy§f - Green star particles\n Recently fed, watered, or played\n\n§7● Content§f - No particles\n Default calm state\n\n§4♨ Needy§f - Gray smoke particles\n Wants food or attention!\n\n§dBoost mood with:§f fish, §9water bottles§f, or fetch!\nMood decays over time.\n\n§7Juveniles are always content.§r", + "§l§6Playing Fetch§r\n\nCraft a §dSpark Ball§f:\n String around Leather\n (shaped recipe, crafting table)\n\n§f• Throw the ball (use item)\n§f• Dragon chases and catches it\n§f• Returns the ball to you!\n§f• Resets mood to §aHappy§r\n\n§7Great way to bond with your dragon and keep it happy!§r", + "§l§6Death & Gravestones§r\n\nIf your dragon dies, it leaves a §7Dragon Gravestone§f at the death location.\n\n§f• Look for the §ebeacon column§f of particles rising into the sky\n§f• The gravestone glows to help you find it\n§f• Collect §7Dragon Bones§f as a memorial\n\n§7The beacon makes gravestones visible from far away.§r", + "§l§6Tips & Tricks§r\n\n§f• Dragons are §afall immune§f\n§f• Use a §eLead§f to guide them\n§f• §eName Tags§f work normally\n§f• Craft a §dDragon Whistle§f for ranged recall (throw it!)\n§f• Give an §dAmethyst Shard§f to get another copy of this guide\n§f• §9Water Bottles§f boost mood without using food\n\n§5Enjoy your Spark Dragon!§r\n§7- SilverLABS§r" + ] + } + ] + } + ] + } + ] +} diff --git a/addon/spark_pet_BP/loot_tables/gameplay/egg_pickup.json b/addon/spark_pet_BP/loot_tables/gameplay/egg_pickup.json new file mode 100644 index 0000000..23cac7f --- /dev/null +++ b/addon/spark_pet_BP/loot_tables/gameplay/egg_pickup.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "silverlabs:dragon_egg", + "weight": 1 + } + ] + } + ] +} diff --git a/addon/spark_pet_BP/loot_tables/gameplay/gift_adult.json b/addon/spark_pet_BP/loot_tables/gameplay/gift_adult.json new file mode 100644 index 0000000..0d19057 --- /dev/null +++ b/addon/spark_pet_BP/loot_tables/gameplay/gift_adult.json @@ -0,0 +1,23 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { "type": "item", "name": "minecraft:diamond", "weight": 5 }, + { "type": "item", "name": "minecraft:emerald", "weight": 8 }, + { "type": "item", "name": "minecraft:gold_ingot", "weight": 15 }, + { "type": "item", "name": "minecraft:iron_ingot", "weight": 20 }, + { "type": "item", "name": "minecraft:amethyst_shard", "weight": 12 }, + { "type": "item", "name": "minecraft:lapis_lazuli", "weight": 15, + "functions": [{ "function": "set_count", "count": { "min": 2, "max": 5 } }] + }, + { "type": "item", "name": "minecraft:redstone", "weight": 15, + "functions": [{ "function": "set_count", "count": { "min": 2, "max": 4 } }] + }, + { "type": "item", "name": "minecraft:golden_apple", "weight": 3 }, + { "type": "item", "name": "minecraft:name_tag", "weight": 7 }, + { "type": "item", "name": "silverlabs:dragon_egg", "weight": 1 } + ] + } + ] +} diff --git a/addon/spark_pet_BP/loot_tables/gameplay/gift_baby.json b/addon/spark_pet_BP/loot_tables/gameplay/gift_baby.json new file mode 100644 index 0000000..1836ffe --- /dev/null +++ b/addon/spark_pet_BP/loot_tables/gameplay/gift_baby.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { "type": "item", "name": "minecraft:feather", "weight": 20 }, + { "type": "item", "name": "minecraft:wheat_seeds", "weight": 20 }, + { "type": "item", "name": "minecraft:string", "weight": 15 }, + { "type": "item", "name": "minecraft:bone", "weight": 15 }, + { "type": "item", "name": "minecraft:yellow_flower", "weight": 10 }, + { "type": "item", "name": "minecraft:red_flower", "weight": 10 }, + { "type": "item", "name": "minecraft:stick", "weight": 10 } + ] + } + ] +} diff --git a/addon/spark_pet_BP/loot_tables/gameplay/gift_juvenile.json b/addon/spark_pet_BP/loot_tables/gameplay/gift_juvenile.json new file mode 100644 index 0000000..a3537dc --- /dev/null +++ b/addon/spark_pet_BP/loot_tables/gameplay/gift_juvenile.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { "type": "item", "name": "minecraft:iron_nugget", "weight": 20 }, + { "type": "item", "name": "minecraft:gold_nugget", "weight": 15 }, + { "type": "item", "name": "minecraft:coal", "weight": 20 }, + { "type": "item", "name": "minecraft:redstone", "weight": 15 }, + { "type": "item", "name": "minecraft:lapis_lazuli", "weight": 10 }, + { "type": "item", "name": "minecraft:flint", "weight": 10 }, + { "type": "item", "name": "minecraft:copper_ingot", "weight": 10 } + ] + } + ] +} diff --git a/addon/spark_pet_BP/loot_tables/gameplay/gravestone_break.json b/addon/spark_pet_BP/loot_tables/gameplay/gravestone_break.json new file mode 100644 index 0000000..953f75e --- /dev/null +++ b/addon/spark_pet_BP/loot_tables/gameplay/gravestone_break.json @@ -0,0 +1,10 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { "type": "item", "name": "silverlabs:dragon_gravestone", "weight": 1 } + ] + } + ] +} \ No newline at end of file diff --git a/addon/spark_pet_BP/loot_tables/gameplay/toy_return.json b/addon/spark_pet_BP/loot_tables/gameplay/toy_return.json new file mode 100644 index 0000000..32b6917 --- /dev/null +++ b/addon/spark_pet_BP/loot_tables/gameplay/toy_return.json @@ -0,0 +1,10 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { "type": "item", "name": "silverlabs:dragon_toy", "weight": 1 } + ] + } + ] +} diff --git a/addon/spark_pet_BP/loot_tables/gameplay/whistle_return.json b/addon/spark_pet_BP/loot_tables/gameplay/whistle_return.json new file mode 100644 index 0000000..8c3c47b --- /dev/null +++ b/addon/spark_pet_BP/loot_tables/gameplay/whistle_return.json @@ -0,0 +1,10 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { "type": "item", "name": "silverlabs:dragon_whistle", "weight": 1 } + ] + } + ] +} \ No newline at end of file diff --git a/addon/spark_pet_BP/manifest.json b/addon/spark_pet_BP/manifest.json new file mode 100644 index 0000000..97f2097 --- /dev/null +++ b/addon/spark_pet_BP/manifest.json @@ -0,0 +1,23 @@ +{ + "format_version": 2, + "header": { + "name": "Pets 4 Jamie's STARS", + "description": "Tameable dragon pets with eggs, gravestones and personality — built for Jamie's STARS!", + "uuid": "7cf924ce-e246-4c8c-998c-f420edb26451", + "version": [1, 0, 0], + "min_engine_version": [1, 21, 0] + }, + "modules": [ + { + "type": "data", + "uuid": "6806e843-c0b4-4a4d-9cb3-d5352e396fe5", + "version": [1, 0, 0] + } + ], + "dependencies": [ + { + "uuid": "5f25d547-00bb-49ce-8be3-d86cd3941c9b", + "version": [1, 0, 0] + } + ] +} diff --git a/addon/spark_pet_BP/pack_icon.png b/addon/spark_pet_BP/pack_icon.png new file mode 100644 index 0000000..a507642 Binary files /dev/null and b/addon/spark_pet_BP/pack_icon.png differ diff --git a/addon/spark_pet_BP/recipes/dragon_basket.json b/addon/spark_pet_BP/recipes/dragon_basket.json new file mode 100644 index 0000000..65df0f5 --- /dev/null +++ b/addon/spark_pet_BP/recipes/dragon_basket.json @@ -0,0 +1,22 @@ +{ + "format_version": "1.21.0", + "minecraft:recipe_shaped": { + "description": { + "identifier": "silverlabs:dragon_basket_recipe" + }, + "tags": ["crafting_table"], + "pattern": [ + "S S", + "WLW", + "SSS" + ], + "key": { + "S": { "item": "minecraft:stick" }, + "W": { "item": "minecraft:wool" }, + "L": { "item": "minecraft:leather" } + }, + "result": { + "item": "silverlabs:dragon_basket" + } + } +} diff --git a/addon/spark_pet_BP/recipes/dragon_egg.json b/addon/spark_pet_BP/recipes/dragon_egg.json new file mode 100644 index 0000000..8704d18 --- /dev/null +++ b/addon/spark_pet_BP/recipes/dragon_egg.json @@ -0,0 +1,23 @@ +{ + "format_version": "1.20.10", + "minecraft:recipe_shaped": { + "description": { + "identifier": "silverlabs:dragon_egg" + }, + "tags": ["crafting_table"], + "pattern": [ + " B ", + "AGA", + " A " + ], + "key": { + "B": { "item": "minecraft:blaze_powder" }, + "A": { "item": "minecraft:amethyst_shard" }, + "G": { "item": "minecraft:gold_ingot" } + }, + "result": { + "item": "silverlabs:dragon_egg", + "count": 1 + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_BP/recipes/dragon_toy.json b/addon/spark_pet_BP/recipes/dragon_toy.json new file mode 100644 index 0000000..f03b6f9 --- /dev/null +++ b/addon/spark_pet_BP/recipes/dragon_toy.json @@ -0,0 +1,22 @@ +{ + "format_version": "1.20.10", + "minecraft:recipe_shaped": { + "description": { + "identifier": "silverlabs:dragon_toy" + }, + "tags": ["crafting_table"], + "pattern": [ + " S ", + "SLS", + " S " + ], + "key": { + "S": { "item": "minecraft:string" }, + "L": { "item": "minecraft:leather" } + }, + "result": { + "item": "silverlabs:dragon_toy", + "count": 4 + } + } +} diff --git a/addon/spark_pet_RP/animation_controllers/dragon_egg.animation_controllers.json b/addon/spark_pet_RP/animation_controllers/dragon_egg.animation_controllers.json new file mode 100644 index 0000000..a8a6554 --- /dev/null +++ b/addon/spark_pet_RP/animation_controllers/dragon_egg.animation_controllers.json @@ -0,0 +1,41 @@ +{ + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.dragon_egg": { + "initial_state": "cold", + "states": { + "cold": { + "animations": ["idle"], + "transitions": [ + { "warming": "query.property('silverlabs:egg_stage') == 1" } + ] + }, + "warming": { + "animations": ["wobble"], + "particle_effects": [ + { "effect": "smoke" } + ], + "transitions": [ + { "hot": "query.property('silverlabs:egg_stage') == 2" } + ] + }, + "hot": { + "animations": ["shake"], + "particle_effects": [ + { "effect": "flame" }, + { "effect": "smoke" } + ], + "transitions": [ + { "hatching": "query.property('silverlabs:egg_stage') == 3" } + ] + }, + "hatching": { + "animations": ["shake"], + "particle_effects": [ + { "effect": "flame" } + ] + } + } + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_RP/animation_controllers/dragon_gravestone.animation_controllers.json b/addon/spark_pet_RP/animation_controllers/dragon_gravestone.animation_controllers.json new file mode 100644 index 0000000..b3ecfd9 --- /dev/null +++ b/addon/spark_pet_RP/animation_controllers/dragon_gravestone.animation_controllers.json @@ -0,0 +1,26 @@ +{ + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.dragon_gravestone": { + "initial_state": "active", + "states": { + "active": { + "animations": ["idle"], + "particle_effects": [ + { "effect": "memorial_glow" } + ] + } + } + }, + "controller.animation.dragon_gravestone.beacon": { + "initial_state": "active", + "states": { + "active": { + "particle_effects": [ + { "effect": "beacon_beam" } + ] + } + } + } + } +} diff --git a/addon/spark_pet_RP/animation_controllers/spark_dragon.animation_controllers.json b/addon/spark_pet_RP/animation_controllers/spark_dragon.animation_controllers.json new file mode 100644 index 0000000..95c6d22 --- /dev/null +++ b/addon/spark_pet_RP/animation_controllers/spark_dragon.animation_controllers.json @@ -0,0 +1,95 @@ +{ + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.spark_dragon.beacon": { + "initial_state": "inactive", + "states": { + "inactive": { + "transitions": [ + { "active": "query.property('silverlabs:beacon_active')" } + ] + }, + "active": { + "particle_effects": [ + { "effect": "beacon_beam" } + ], + "transitions": [ + { "inactive": "!query.property('silverlabs:beacon_active')" } + ] + } + } + }, + "controller.animation.spark_dragon": { + "initial_state": "idle", + "states": { + "idle": { + "animations": ["idle"], + "transitions": [ + { "flying": "!query.is_on_ground && query.property('silverlabs:growth_stage') == 2" }, + { "walking": "query.modified_move_speed > 0.1" }, + { "sleeping": "query.is_sitting && (query.day_light_level < 4)" }, + { "sitting": "query.is_sitting" } + ] + }, + "walking": { + "animations": ["walk"], + "transitions": [ + { "flying": "!query.is_on_ground && query.property('silverlabs:growth_stage') == 2" }, + { "idle": "query.modified_move_speed <= 0.1" }, + { "sitting": "query.is_sitting" } + ] + }, + "sitting": { + "animations": ["sit"], + "transitions": [ + { "idle": "!query.is_sitting" }, + { "sleeping": "query.is_sitting && (query.day_light_level < 4)" } + ] + }, + "sleeping": { + "animations": ["sleep"], + "transitions": [ + { "idle": "!query.is_sitting" }, + { "sitting": "query.is_sitting && (query.day_light_level >= 4)" } + ] + }, + "flying": { + "animations": ["fly"], + "transitions": [ + { "idle": "query.is_on_ground && query.modified_move_speed <= 0.1" }, + { "walking": "query.is_on_ground && query.modified_move_speed > 0.1" } + ] + } + } + }, + "controller.animation.spark_dragon.mood": { + "initial_state": "content", + "states": { + "happy": { + "particle_effects": [ + { "effect": "mood_happy" } + ], + "transitions": [ + { "content": "query.property('silverlabs:mood') == 1" }, + { "needy": "query.property('silverlabs:mood') == 0" } + ] + }, + "content": { + "transitions": [ + { "happy": "query.property('silverlabs:mood') == 2" }, + { "needy": "query.property('silverlabs:mood') == 0" } + ] + }, + "needy": { + "particle_effects": [ + { "effect": "mood_needy" } + ], + "transitions": [ + { "happy": "query.property('silverlabs:mood') == 2" }, + { "content": "query.property('silverlabs:mood') == 1" } + ] + } + } + } + } +} diff --git a/addon/spark_pet_RP/animations/dragon_egg.animation.json b/addon/spark_pet_RP/animations/dragon_egg.animation.json new file mode 100644 index 0000000..5e8af09 --- /dev/null +++ b/addon/spark_pet_RP/animations/dragon_egg.animation.json @@ -0,0 +1,58 @@ +{ + "format_version": "1.8.0", + "animations": { + "animation.dragon_egg.idle": { + "loop": true, + "animation_length": 4.0, + "bones": { + "egg": { + "position": { + "0.0": [0, 0, 0], + "2.0": [0, 0.3, 0], + "4.0": [0, 0, 0] + } + } + } + }, + "animation.dragon_egg.wobble": { + "loop": true, + "animation_length": 2.0, + "bones": { + "egg": { + "rotation": { + "0.0": [0, 0, 0], + "0.5": [0, 0, 5], + "1.0": [0, 0, 0], + "1.5": [0, 0, -5], + "2.0": [0, 0, 0] + }, + "position": { + "0.0": [0, 0, 0], + "1.0": [0, 0.2, 0], + "2.0": [0, 0, 0] + } + } + } + }, + "animation.dragon_egg.shake": { + "loop": true, + "animation_length": 0.4, + "bones": { + "egg": { + "rotation": { + "0.0": [0, 0, -10], + "0.1": [0, 0, 10], + "0.2": [0, 0, -10], + "0.3": [0, 0, 10], + "0.4": [0, 0, -10] + }, + "position": { + "0.0": [0, 0.5, 0], + "0.2": [0, 0, 0], + "0.4": [0, 0.5, 0] + } + } + } + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_RP/animations/dragon_gravestone.animation.json b/addon/spark_pet_RP/animations/dragon_gravestone.animation.json new file mode 100644 index 0000000..482ec78 --- /dev/null +++ b/addon/spark_pet_RP/animations/dragon_gravestone.animation.json @@ -0,0 +1,18 @@ +{ + "format_version": "1.8.0", + "animations": { + "animation.dragon_gravestone.idle": { + "loop": true, + "animation_length": 4.0, + "bones": { + "stone": { + "scale": { + "0.0": [1, 1, 1], + "2.0": [1, 1.02, 1], + "4.0": [1, 1, 1] + } + } + } + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_RP/animations/spark_dragon.animation.json b/addon/spark_pet_RP/animations/spark_dragon.animation.json new file mode 100644 index 0000000..9fdfc7a --- /dev/null +++ b/addon/spark_pet_RP/animations/spark_dragon.animation.json @@ -0,0 +1,246 @@ +{ + "format_version": "1.8.0", + "animations": { + "animation.spark_dragon.idle": { + "loop": true, + "animation_length": 2.0, + "bones": { + "wing_left": { + "rotation": { + "0.0": [0, 0, -5], + "1.0": [0, 0, -15], + "2.0": [0, 0, -5] + } + }, + "wing_right": { + "rotation": { + "0.0": [0, 0, 5], + "1.0": [0, 0, 15], + "2.0": [0, 0, 5] + } + }, + "body": { + "position": { + "0.0": [0, 0, 0], + "1.0": [0, 0.3, 0], + "2.0": [0, 0, 0] + } + }, + "tail": { + "rotation": { + "0.0": [0, -5, 0], + "1.0": [0, 5, 0], + "2.0": [0, -5, 0] + } + } + } + }, + "animation.spark_dragon.walk": { + "loop": true, + "animation_length": 0.8, + "bones": { + "leg_front_left": { + "rotation": { + "0.0": [20, 0, 0], + "0.2": [0, 0, 0], + "0.4": [-20, 0, 0], + "0.6": [0, 0, 0], + "0.8": [20, 0, 0] + } + }, + "leg_front_right": { + "rotation": { + "0.0": [-20, 0, 0], + "0.2": [0, 0, 0], + "0.4": [20, 0, 0], + "0.6": [0, 0, 0], + "0.8": [-20, 0, 0] + } + }, + "leg_back_left": { + "rotation": { + "0.0": [-20, 0, 0], + "0.2": [0, 0, 0], + "0.4": [20, 0, 0], + "0.6": [0, 0, 0], + "0.8": [-20, 0, 0] + } + }, + "leg_back_right": { + "rotation": { + "0.0": [20, 0, 0], + "0.2": [0, 0, 0], + "0.4": [-20, 0, 0], + "0.6": [0, 0, 0], + "0.8": [20, 0, 0] + } + }, + "wing_left": { + "rotation": { + "0.0": [0, 0, -10], + "0.2": [0, 0, -30], + "0.4": [0, 0, -10], + "0.6": [0, 0, -30], + "0.8": [0, 0, -10] + } + }, + "wing_right": { + "rotation": { + "0.0": [0, 0, 10], + "0.2": [0, 0, 30], + "0.4": [0, 0, 10], + "0.6": [0, 0, 30], + "0.8": [0, 0, 10] + } + }, + "tail": { + "rotation": { + "0.0": [0, -10, 0], + "0.4": [0, 10, 0], + "0.8": [0, -10, 0] + } + }, + "body": { + "position": { + "0.0": [0, 0, 0], + "0.2": [0, 0.5, 0], + "0.4": [0, 0, 0], + "0.6": [0, 0.5, 0], + "0.8": [0, 0, 0] + } + } + } + }, + "animation.spark_dragon.sit": { + "loop": true, + "animation_length": 2.0, + "bones": { + "body": { + "position": [0, -1.5, 0] + }, + "leg_front_left": { + "rotation": [-60, 0, 0] + }, + "leg_front_right": { + "rotation": [-60, 0, 0] + }, + "leg_back_left": { + "rotation": [-90, 20, 0] + }, + "leg_back_right": { + "rotation": [-90, -20, 0] + }, + "wing_left": { + "rotation": [0, 0, 5], + "position": [0, 0, 1] + }, + "wing_right": { + "rotation": [0, 0, -5], + "position": [0, 0, 1] + }, + "tail": { + "rotation": { + "0.0": [10, -30, 0], + "1.0": [10, -25, 0], + "2.0": [10, -30, 0] + } + } + } + }, + "animation.spark_dragon.sleep": { + "loop": true, + "animation_length": 4.0, + "bones": { + "body": { + "position": [0, -2, 0], + "scale": { + "0.0": [1, 1, 1], + "2.0": [1, 1.04, 1], + "4.0": [1, 1, 1] + } + }, + "head": { + "rotation": [20, 40, 10], + "position": [0, -1, 2] + }, + "leg_front_left": { + "rotation": [-90, 0, 0] + }, + "leg_front_right": { + "rotation": [-90, 0, 0] + }, + "leg_back_left": { + "rotation": [-90, 30, 0] + }, + "leg_back_right": { + "rotation": [-90, -30, 0] + }, + "wing_left": { + "rotation": [30, 0, 10], + "position": [0, -1, 1] + }, + "wing_right": { + "rotation": [30, 0, -10], + "position": [0, -1, 1] + }, + "tail": { + "rotation": [20, -60, 0] + } + } + }, + "animation.spark_dragon.fly": { + "loop": true, + "animation_length": 0.6, + "bones": { + "body": { + "rotation": [-15, 0, 0], + "position": { + "0.0": [0, 0, 0], + "0.3": [0, 0.4, 0], + "0.6": [0, 0, 0] + } + }, + "wing_left": { + "rotation": { + "0.0": [-10, 0, -60], + "0.15": [10, 0, -10], + "0.3": [-10, 0, -60], + "0.45": [10, 0, -10], + "0.6": [-10, 0, -60] + } + }, + "wing_right": { + "rotation": { + "0.0": [-10, 0, 60], + "0.15": [10, 0, 10], + "0.3": [-10, 0, 60], + "0.45": [10, 0, 10], + "0.6": [-10, 0, 60] + } + }, + "leg_front_left": { + "rotation": [-45, 0, 0] + }, + "leg_front_right": { + "rotation": [-45, 0, 0] + }, + "leg_back_left": { + "rotation": [-60, 10, 0] + }, + "leg_back_right": { + "rotation": [-60, -10, 0] + }, + "tail": { + "rotation": { + "0.0": [15, -3, 0], + "0.3": [15, 3, 0], + "0.6": [15, -3, 0] + } + }, + "head": { + "rotation": [10, 0, 0] + } + } + } + } +} diff --git a/addon/spark_pet_RP/blocks.json b/addon/spark_pet_RP/blocks.json new file mode 100644 index 0000000..7fd8a45 --- /dev/null +++ b/addon/spark_pet_RP/blocks.json @@ -0,0 +1,6 @@ +{ + "format_version": [1, 1, 0], + "silverlabs:dragon_basket": { + "sound": "wood" + } +} diff --git a/addon/spark_pet_RP/entity/dragon_egg.entity.json b/addon/spark_pet_RP/entity/dragon_egg.entity.json new file mode 100644 index 0000000..30017dd --- /dev/null +++ b/addon/spark_pet_RP/entity/dragon_egg.entity.json @@ -0,0 +1,33 @@ +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "silverlabs:dragon_egg", + "materials": { + "default": "entity_alphatest" + }, + "textures": { + "default": "textures/entity/dragon_egg" + }, + "geometry": { + "default": "geometry.dragon_egg" + }, + "render_controllers": [ + "controller.render.dragon_egg" + ], + "animations": { + "idle": "animation.dragon_egg.idle", + "wobble": "animation.dragon_egg.wobble", + "shake": "animation.dragon_egg.shake", + "controller": "controller.animation.dragon_egg" + }, + "scripts": { + "animate": ["controller"] + }, + "particle_effects": { + "flame": "minecraft:basic_flame_particle", + "smoke": "minecraft:basic_smoke_particle" + } + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_RP/entity/dragon_gravestone.entity.json b/addon/spark_pet_RP/entity/dragon_gravestone.entity.json new file mode 100644 index 0000000..2e31b5c --- /dev/null +++ b/addon/spark_pet_RP/entity/dragon_gravestone.entity.json @@ -0,0 +1,32 @@ +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "silverlabs:dragon_gravestone", + "materials": { + "default": "entity_alphatest" + }, + "textures": { + "default": "textures/entity/dragon_gravestone" + }, + "geometry": { + "default": "geometry.dragon_gravestone" + }, + "render_controllers": [ + "controller.render.dragon_gravestone" + ], + "animations": { + "idle": "animation.dragon_gravestone.idle", + "controller": "controller.animation.dragon_gravestone", + "beacon_controller": "controller.animation.dragon_gravestone.beacon" + }, + "scripts": { + "animate": ["controller", "beacon_controller"] + }, + "particle_effects": { + "memorial_glow": "minecraft:endrod", + "beacon_beam": "minecraft:endrod" + } + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_RP/entity/dragon_toy.entity.json b/addon/spark_pet_RP/entity/dragon_toy.entity.json new file mode 100644 index 0000000..f844c46 --- /dev/null +++ b/addon/spark_pet_RP/entity/dragon_toy.entity.json @@ -0,0 +1,20 @@ +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "silverlabs:dragon_toy", + "materials": { + "default": "entity_alphatest" + }, + "textures": { + "default": "textures/entity/dragon_toy" + }, + "geometry": { + "default": "geometry.dragon_toy" + }, + "render_controllers": [ + "controller.render.dragon_toy" + ] + } + } +} diff --git a/addon/spark_pet_RP/entity/spark_dragon.entity.json b/addon/spark_pet_RP/entity/spark_dragon.entity.json new file mode 100644 index 0000000..34ad70a --- /dev/null +++ b/addon/spark_pet_RP/entity/spark_dragon.entity.json @@ -0,0 +1,42 @@ +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "silverlabs:spark_dragon", + "materials": { + "default": "entity_alphatest" + }, + "textures": { + "default": "textures/entity/spark_dragon" + }, + "geometry": { + "default": "geometry.spark_dragon" + }, + "render_controllers": [ + "controller.render.spark_dragon" + ], + "animations": { + "idle": "animation.spark_dragon.idle", + "walk": "animation.spark_dragon.walk", + "sit": "animation.spark_dragon.sit", + "sleep": "animation.spark_dragon.sleep", + "fly": "animation.spark_dragon.fly", + "controller": "controller.animation.spark_dragon", + "beacon_controller": "controller.animation.spark_dragon.beacon", + "mood_controller": "controller.animation.spark_dragon.mood" + }, + "scripts": { + "animate": ["controller", "beacon_controller", "mood_controller"] + }, + "particle_effects": { + "beacon_beam": "minecraft:endrod", + "mood_happy": "minecraft:villager_happy", + "mood_needy": "minecraft:large_smoke" + }, + "spawn_egg": { + "base_color": "#7B2FBE", + "overlay_color": "#F5A623" + } + } + } +} diff --git a/addon/spark_pet_RP/entity/whistle_signal.entity.json b/addon/spark_pet_RP/entity/whistle_signal.entity.json new file mode 100644 index 0000000..77d5774 --- /dev/null +++ b/addon/spark_pet_RP/entity/whistle_signal.entity.json @@ -0,0 +1,20 @@ +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "silverlabs:whistle_signal", + "materials": { + "default": "entity_alphatest" + }, + "textures": { + "default": "textures/entity/dragon_toy" + }, + "geometry": { + "default": "geometry.dragon_toy" + }, + "render_controllers": [ + "controller.render.dragon_toy" + ] + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_RP/manifest.json b/addon/spark_pet_RP/manifest.json new file mode 100644 index 0000000..2c0f311 --- /dev/null +++ b/addon/spark_pet_RP/manifest.json @@ -0,0 +1,23 @@ +{ + "format_version": 2, + "header": { + "name": "Pets 4 Jamie's STARS Resources", + "description": "Textures, models and animations for Pets 4 Jamie's STARS", + "uuid": "5f25d547-00bb-49ce-8be3-d86cd3941c9b", + "version": [1, 0, 0], + "min_engine_version": [1, 21, 0] + }, + "modules": [ + { + "type": "resources", + "uuid": "6adc20cd-25a5-4ca5-aa12-f5e43ee9ea22", + "version": [1, 0, 0] + } + ], + "dependencies": [ + { + "uuid": "7cf924ce-e246-4c8c-998c-f420edb26451", + "version": [1, 0, 0] + } + ] +} diff --git a/addon/spark_pet_RP/models/blocks/dragon_basket.geo.json b/addon/spark_pet_RP/models/blocks/dragon_basket.geo.json new file mode 100644 index 0000000..c0c2dc6 --- /dev/null +++ b/addon/spark_pet_RP/models/blocks/dragon_basket.geo.json @@ -0,0 +1,52 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.dragon_basket", + "texture_width": 16, + "texture_height": 16 + }, + "bones": [ + { + "name": "basket", + "pivot": [0, 0, 0], + "cubes": [ + { + "origin": [-7, 0, -7], + "size": [14, 2, 14], + "uv": [0, 0], + "inflate": 0 + }, + { + "origin": [-7, 2, -7], + "size": [14, 3, 1], + "uv": [0, 0] + }, + { + "origin": [-7, 2, 6], + "size": [14, 3, 1], + "uv": [0, 0] + }, + { + "origin": [-7, 2, -6], + "size": [1, 3, 12], + "uv": [0, 0] + }, + { + "origin": [6, 2, -6], + "size": [1, 3, 12], + "uv": [0, 0] + }, + { + "origin": [-5, 1, -5], + "size": [10, 1, 10], + "uv": [0, 8], + "inflate": 0 + } + ] + } + ] + } + ] +} diff --git a/addon/spark_pet_RP/models/entity/dragon_egg.geo.json b/addon/spark_pet_RP/models/entity/dragon_egg.geo.json new file mode 100644 index 0000000..74ab011 --- /dev/null +++ b/addon/spark_pet_RP/models/entity/dragon_egg.geo.json @@ -0,0 +1,53 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.dragon_egg", + "texture_width": 32, + "texture_height": 32, + "visible_bounds_width": 1.0, + "visible_bounds_height": 1.0, + "visible_bounds_offset": [0, 0.4, 0] + }, + "bones": [ + { + "name": "root", + "pivot": [0, 0, 0] + }, + { + "name": "egg", + "parent": "root", + "pivot": [0, 0, 0], + "cubes": [ + { + "origin": [-2, 0, -2], + "size": [4, 2, 4], + "uv": [0, 18] + }, + { + "origin": [-3, 2, -3], + "size": [6, 3, 6], + "uv": [0, 8] + }, + { + "origin": [-2.5, 5, -2.5], + "size": [5, 3, 5], + "uv": [0, 0] + }, + { + "origin": [-1.5, 8, -1.5], + "size": [3, 2, 3], + "uv": [18, 0] + }, + { + "origin": [-0.5, 10, -0.5], + "size": [1, 1, 1], + "uv": [20, 8] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/addon/spark_pet_RP/models/entity/dragon_gravestone.geo.json b/addon/spark_pet_RP/models/entity/dragon_gravestone.geo.json new file mode 100644 index 0000000..eefc997 --- /dev/null +++ b/addon/spark_pet_RP/models/entity/dragon_gravestone.geo.json @@ -0,0 +1,55 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.dragon_gravestone", + "texture_width": 32, + "texture_height": 32, + "visible_bounds_width": 1.0, + "visible_bounds_height": 1.5, + "visible_bounds_offset": [0, 0.5, 0] + }, + "bones": [ + { + "name": "root", + "pivot": [0, 0, 0] + }, + { + "name": "base", + "parent": "root", + "pivot": [0, 0, 0], + "cubes": [ + { + "origin": [-4, 0, -2], + "size": [8, 2, 4], + "uv": [0, 20] + } + ] + }, + { + "name": "stone", + "parent": "base", + "pivot": [0, 2, 0], + "cubes": [ + { + "origin": [-3, 2, -1], + "size": [6, 8, 2], + "uv": [0, 0] + }, + { + "origin": [-2, 10, -1], + "size": [4, 2, 2], + "uv": [0, 10] + }, + { + "origin": [-1, 12, -1], + "size": [2, 1, 2], + "uv": [0, 14] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/addon/spark_pet_RP/models/entity/dragon_toy.geo.json b/addon/spark_pet_RP/models/entity/dragon_toy.geo.json new file mode 100644 index 0000000..1c5cc1b --- /dev/null +++ b/addon/spark_pet_RP/models/entity/dragon_toy.geo.json @@ -0,0 +1,26 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.dragon_toy", + "texture_width": 16, + "texture_height": 16 + }, + "bones": [ + { + "name": "body", + "pivot": [0, 2, 0], + "cubes": [ + { + "origin": [-2, 0, -2], + "size": [4, 4, 4], + "uv": [0, 0], + "inflate": 0.5 + } + ] + } + ] + } + ] +} diff --git a/addon/spark_pet_RP/models/entity/spark_dragon.geo.json b/addon/spark_pet_RP/models/entity/spark_dragon.geo.json new file mode 100644 index 0000000..8f9bfcb --- /dev/null +++ b/addon/spark_pet_RP/models/entity/spark_dragon.geo.json @@ -0,0 +1,149 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.spark_dragon", + "texture_width": 64, + "texture_height": 32, + "visible_bounds_width": 1.5, + "visible_bounds_height": 1.0, + "visible_bounds_offset": [0, 0.25, 0] + }, + "bones": [ + { + "name": "root", + "pivot": [0, 0, 0] + }, + { + "name": "body", + "parent": "root", + "pivot": [0, 4, 0], + "cubes": [ + { + "origin": [-3, 2, -4], + "size": [6, 5, 8], + "uv": [0, 0] + } + ] + }, + { + "name": "head", + "parent": "body", + "pivot": [0, 6, -4], + "cubes": [ + { + "origin": [-2.5, 4.5, -9], + "size": [5, 5, 5], + "uv": [20, 0] + }, + { + "origin": [-1.5, 4.5, -11], + "size": [3, 3, 2], + "uv": [40, 0] + }, + { + "origin": [-0.5, 9.5, -8], + "size": [1, 2, 1], + "uv": [50, 0] + }, + { + "origin": [0.5, 9.5, -7], + "size": [1, 2, 1], + "uv": [54, 0] + } + ] + }, + { + "name": "leg_front_left", + "parent": "body", + "pivot": [2, 2, -2], + "cubes": [ + { + "origin": [1, 0, -3], + "size": [2, 3, 2], + "uv": [0, 13] + } + ] + }, + { + "name": "leg_front_right", + "parent": "body", + "pivot": [-2, 2, -2], + "cubes": [ + { + "origin": [-3, 0, -3], + "size": [2, 3, 2], + "uv": [8, 13] + } + ] + }, + { + "name": "leg_back_left", + "parent": "body", + "pivot": [2, 2, 3], + "cubes": [ + { + "origin": [1, 0, 2], + "size": [2, 3, 2], + "uv": [16, 13] + } + ] + }, + { + "name": "leg_back_right", + "parent": "body", + "pivot": [-2, 2, 3], + "cubes": [ + { + "origin": [-3, 0, 2], + "size": [2, 3, 2], + "uv": [24, 13] + } + ] + }, + { + "name": "tail", + "parent": "body", + "pivot": [0, 4, 4], + "cubes": [ + { + "origin": [-1, 3, 4], + "size": [2, 2, 6], + "uv": [32, 13] + }, + { + "origin": [-0.5, 3.5, 10], + "size": [1, 1, 3], + "uv": [48, 13] + } + ] + }, + { + "name": "wing_left", + "parent": "body", + "pivot": [3, 7, 0], + "cubes": [ + { + "origin": [3, 6.5, -2], + "size": [6, 0.5, 4], + "uv": [0, 19] + } + ] + }, + { + "name": "wing_right", + "parent": "body", + "pivot": [-3, 7, 0], + "cubes": [ + { + "origin": [-9, 6.5, -2], + "size": [6, 0.5, 4], + "uv": [0, 24] + } + ] + } + ] + } + ] +} diff --git a/addon/spark_pet_RP/pack_icon.png b/addon/spark_pet_RP/pack_icon.png new file mode 100644 index 0000000..a507642 Binary files /dev/null and b/addon/spark_pet_RP/pack_icon.png differ diff --git a/addon/spark_pet_RP/render_controllers/dragon_egg.render_controllers.json b/addon/spark_pet_RP/render_controllers/dragon_egg.render_controllers.json new file mode 100644 index 0000000..2729da3 --- /dev/null +++ b/addon/spark_pet_RP/render_controllers/dragon_egg.render_controllers.json @@ -0,0 +1,14 @@ +{ + "format_version": "1.8.0", + "render_controllers": { + "controller.render.dragon_egg": { + "geometry": "Geometry.default", + "materials": [ + { + "*": "Material.default" + } + ], + "textures": ["Texture.default"] + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_RP/render_controllers/dragon_gravestone.render_controllers.json b/addon/spark_pet_RP/render_controllers/dragon_gravestone.render_controllers.json new file mode 100644 index 0000000..6fb7496 --- /dev/null +++ b/addon/spark_pet_RP/render_controllers/dragon_gravestone.render_controllers.json @@ -0,0 +1,14 @@ +{ + "format_version": "1.8.0", + "render_controllers": { + "controller.render.dragon_gravestone": { + "geometry": "Geometry.default", + "materials": [ + { + "*": "Material.default" + } + ], + "textures": ["Texture.default"] + } + } +} \ No newline at end of file diff --git a/addon/spark_pet_RP/render_controllers/dragon_toy.render_controllers.json b/addon/spark_pet_RP/render_controllers/dragon_toy.render_controllers.json new file mode 100644 index 0000000..a06adfb --- /dev/null +++ b/addon/spark_pet_RP/render_controllers/dragon_toy.render_controllers.json @@ -0,0 +1,14 @@ +{ + "format_version": "1.8.0", + "render_controllers": { + "controller.render.dragon_toy": { + "geometry": "Geometry.default", + "materials": [ + { + "*": "Material.default" + } + ], + "textures": ["Texture.default"] + } + } +} diff --git a/addon/spark_pet_RP/render_controllers/spark_dragon.render_controllers.json b/addon/spark_pet_RP/render_controllers/spark_dragon.render_controllers.json new file mode 100644 index 0000000..e470538 --- /dev/null +++ b/addon/spark_pet_RP/render_controllers/spark_dragon.render_controllers.json @@ -0,0 +1,14 @@ +{ + "format_version": "1.8.0", + "render_controllers": { + "controller.render.spark_dragon": { + "geometry": "Geometry.default", + "materials": [ + { + "*": "Material.default" + } + ], + "textures": ["Texture.default"] + } + } +} diff --git a/addon/spark_pet_RP/texts/en_US.lang b/addon/spark_pet_RP/texts/en_US.lang new file mode 100644 index 0000000..b3c8bc8 --- /dev/null +++ b/addon/spark_pet_RP/texts/en_US.lang @@ -0,0 +1,12 @@ +entity.silverlabs:spark_dragon.name=Spark Dragon +item.spawn_egg.entity.silverlabs:spark_dragon.name=Spawn Spark Dragon +item.silverlabs:dragon_whistle.name=Dragon Whistle +tile.silverlabs:dragon_basket.name=Dragon Basket +item.silverlabs:dragon_egg.name=Spark Dragon Egg +entity.silverlabs:dragon_egg.name=Spark Dragon Egg +item.silverlabs:dragon_bones.name=Dragon Bones +item.silverlabs:dragon_gravestone.name=Dragon Gravestone +entity.silverlabs:dragon_gravestone.name=Dragon Gravestone +item.silverlabs:dragon_toy.name=Spark Ball +entity.silverlabs:dragon_toy.name=Spark Ball +entity.silverlabs:whistle_signal.name=Whistle Signal diff --git a/addon/spark_pet_RP/textures/blocks/dragon_basket.png b/addon/spark_pet_RP/textures/blocks/dragon_basket.png new file mode 100644 index 0000000..9e9d68c Binary files /dev/null and b/addon/spark_pet_RP/textures/blocks/dragon_basket.png differ diff --git a/addon/spark_pet_RP/textures/entity/dragon_egg.png b/addon/spark_pet_RP/textures/entity/dragon_egg.png new file mode 100644 index 0000000..0ed6d52 Binary files /dev/null and b/addon/spark_pet_RP/textures/entity/dragon_egg.png differ diff --git a/addon/spark_pet_RP/textures/entity/dragon_gravestone.png b/addon/spark_pet_RP/textures/entity/dragon_gravestone.png new file mode 100644 index 0000000..4e57a02 Binary files /dev/null and b/addon/spark_pet_RP/textures/entity/dragon_gravestone.png differ diff --git a/addon/spark_pet_RP/textures/entity/dragon_toy.png b/addon/spark_pet_RP/textures/entity/dragon_toy.png new file mode 100644 index 0000000..ca7c2e7 Binary files /dev/null and b/addon/spark_pet_RP/textures/entity/dragon_toy.png differ diff --git a/addon/spark_pet_RP/textures/entity/spark_dragon.png b/addon/spark_pet_RP/textures/entity/spark_dragon.png new file mode 100644 index 0000000..140d877 Binary files /dev/null and b/addon/spark_pet_RP/textures/entity/spark_dragon.png differ diff --git a/addon/spark_pet_RP/textures/item_texture.json b/addon/spark_pet_RP/textures/item_texture.json new file mode 100644 index 0000000..38b0dc7 --- /dev/null +++ b/addon/spark_pet_RP/textures/item_texture.json @@ -0,0 +1,21 @@ +{ + "resource_pack_name": "spark_pet_RP", + "texture_name": "atlas.items", + "texture_data": { + "dragon_whistle": { + "textures": "textures/items/dragon_whistle" + }, +"dragon_egg": { + "textures": "textures/items/dragon_egg" + }, + "dragon_toy": { + "textures": "textures/items/dragon_toy" + }, + "dragon_bones": { + "textures": "textures/items/dragon_bones" + }, + "dragon_gravestone": { + "textures": "textures/items/dragon_gravestone" + }, + } +} diff --git a/addon/spark_pet_RP/textures/items/dragon_bones.png b/addon/spark_pet_RP/textures/items/dragon_bones.png new file mode 100644 index 0000000..3be0afa Binary files /dev/null and b/addon/spark_pet_RP/textures/items/dragon_bones.png differ diff --git a/addon/spark_pet_RP/textures/items/dragon_egg.png b/addon/spark_pet_RP/textures/items/dragon_egg.png new file mode 100644 index 0000000..d372d04 Binary files /dev/null and b/addon/spark_pet_RP/textures/items/dragon_egg.png differ diff --git a/addon/spark_pet_RP/textures/items/dragon_gravestone.png b/addon/spark_pet_RP/textures/items/dragon_gravestone.png new file mode 100644 index 0000000..00df8cb Binary files /dev/null and b/addon/spark_pet_RP/textures/items/dragon_gravestone.png differ diff --git a/addon/spark_pet_RP/textures/items/dragon_toy.png b/addon/spark_pet_RP/textures/items/dragon_toy.png new file mode 100644 index 0000000..b1ebc92 Binary files /dev/null and b/addon/spark_pet_RP/textures/items/dragon_toy.png differ diff --git a/addon/spark_pet_RP/textures/items/dragon_whistle.png b/addon/spark_pet_RP/textures/items/dragon_whistle.png new file mode 100644 index 0000000..a8380a3 Binary files /dev/null and b/addon/spark_pet_RP/textures/items/dragon_whistle.png differ diff --git a/addon/spark_pet_RP/textures/terrain_texture.json b/addon/spark_pet_RP/textures/terrain_texture.json new file mode 100644 index 0000000..ad69b0b --- /dev/null +++ b/addon/spark_pet_RP/textures/terrain_texture.json @@ -0,0 +1,11 @@ +{ + "resource_pack_name": "spark_pet", + "texture_name": "atlas.terrain", + "padding": 8, + "num_mip_levels": 4, + "texture_data": { + "dragon_basket": { + "textures": "textures/blocks/dragon_basket" + } + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..fbfd489 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,114 @@ +services: + lobby: + image: itzg/minecraft-bedrock-server + container_name: mc-lobby + environment: + EULA: "TRUE" + SERVER_NAME: "SilverLABS Hub" + GAMEMODE: adventure + DIFFICULTY: peaceful + ALLOW_CHEATS: "true" + ONLINE_MODE: "false" + SERVER_PORT: "19132" + LEVEL_NAME: "Hub World" + MAX_PLAYERS: "10" + DEFAULT_PLAYER_PERMISSION_LEVEL: operator + OP_PERMISSION_LEVEL: "4" + ports: + - "${LOBBY_PORT:-19132}:19132/udp" + volumes: + - lobby-data:/data + - ./lobby-addon/lobby_transfer_BP:/data/behavior_packs/lobby_transfer_BP + - ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP + - ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP + restart: unless-stopped + networks: + - mc-network + + jamie: + image: itzg/minecraft-bedrock-server + container_name: mc-jamie + environment: + EULA: "TRUE" + SERVER_NAME: "Jamie's World" + GAMEMODE: survival + DIFFICULTY: normal + ALLOW_CHEATS: "true" + ONLINE_MODE: "false" + SERVER_PORT: "19132" + LEVEL_NAME: "Jamie World" + MAX_PLAYERS: "10" + DEFAULT_PLAYER_PERMISSION_LEVEL: operator + OP_PERMISSION_LEVEL: "4" + ports: + - "${JAMIE_PORT:-19133}:19132/udp" + volumes: + - jamie-data:/data + - ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP + - ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP + - ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP + restart: unless-stopped + networks: + - mc-network + + lyla: + image: itzg/minecraft-bedrock-server + container_name: mc-lyla + environment: + EULA: "TRUE" + SERVER_NAME: "Lyla's World" + GAMEMODE: survival + DIFFICULTY: normal + ALLOW_CHEATS: "true" + ONLINE_MODE: "false" + SERVER_PORT: "19132" + LEVEL_NAME: "Lyla World" + MAX_PLAYERS: "10" + DEFAULT_PLAYER_PERMISSION_LEVEL: operator + OP_PERMISSION_LEVEL: "4" + ports: + - "${LYLA_PORT:-19134}:19132/udp" + volumes: + - lyla-data:/data + - ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP + - ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP + - ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP + restart: unless-stopped + networks: + - mc-network + + mya: + image: itzg/minecraft-bedrock-server + container_name: mc-mya + environment: + EULA: "TRUE" + SERVER_NAME: "Mya's World" + GAMEMODE: survival + DIFFICULTY: normal + ALLOW_CHEATS: "true" + ONLINE_MODE: "false" + SERVER_PORT: "19132" + LEVEL_NAME: "Mya World" + MAX_PLAYERS: "10" + DEFAULT_PLAYER_PERMISSION_LEVEL: operator + OP_PERMISSION_LEVEL: "4" + ports: + - "${MYA_PORT:-19135}:19132/udp" + volumes: + - mya-data:/data + - ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP + - ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP + - ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP + restart: unless-stopped + networks: + - mc-network + +volumes: + lobby-data: + jamie-data: + lyla-data: + mya-data: + +networks: + mc-network: + driver: bridge diff --git a/hub-return-addon/hub_return_transfer_BP/manifest.json b/hub-return-addon/hub_return_transfer_BP/manifest.json new file mode 100644 index 0000000..ae05199 --- /dev/null +++ b/hub-return-addon/hub_return_transfer_BP/manifest.json @@ -0,0 +1,25 @@ +{ + "format_version": 2, + "header": { + "name": "Hub Return Transfer", + "description": "Transfers players back to lobby when they step on the return portal", + "uuid": "b2c3d4e5-1111-2222-3333-fedcba654321", + "version": [1, 0, 1], + "min_engine_version": [1, 21, 0] + }, + "modules": [ + { + "type": "script", + "language": "javascript", + "uuid": "b2c3d4e5-4444-5555-6666-fedcba987654", + "version": [1, 0, 1], + "entry": "scripts/main.js" + } + ], + "dependencies": [ + { + "module_name": "@minecraft/server", + "version": "2.0.0" + } + ] +} diff --git a/hub-return-addon/hub_return_transfer_BP/scripts/main.js b/hub-return-addon/hub_return_transfer_BP/scripts/main.js new file mode 100644 index 0000000..888cf72 --- /dev/null +++ b/hub-return-addon/hub_return_transfer_BP/scripts/main.js @@ -0,0 +1,224 @@ +import { world, system, ItemStack } from "@minecraft/server"; + +const LOBBY_HOST = "10.0.0.247"; +const LOBBY_PORT = 19132; +const COMPASS_ID = "minecraft:recovery_compass"; +const PORTAL_PROP = "hub_portal_location"; +const PORTAL_RADIUS = 3; +const TRANSFER_COOLDOWN = 5000; // 5 seconds + +// Track recently transferred players +const recentTransfers = new Map(); + +function doTransfer(player) { + const now = Date.now(); + if (recentTransfers.has(player.name) && now - recentTransfers.get(player.name) < TRANSFER_COOLDOWN) { + player.sendMessage("§c[Hub] §fPlease wait a moment before transferring again."); + return; + } + + recentTransfers.set(player.name, now); + world.sendMessage(`§a${player.name} is returning to the Hub...`); + + try { + player.runCommand(`transfer "${player.name}" ${LOBBY_HOST} ${LOBBY_PORT}`); + } catch (e) { + world.sendMessage(`§cTransfer failed: ${e.message}`); + } +} + +// ─── A. Compass Distribution ──────────────────────────────────── + +function giveCompassIfMissing(player) { + const inventory = player.getComponent("minecraft:inventory"); + if (!inventory) return; + + const container = inventory.container; + for (let i = 0; i < container.size; i++) { + const item = container.getItem(i); + if (item && item.typeId === COMPASS_ID) return; // already has one + } + + container.addItem(new ItemStack(COMPASS_ID, 1)); + player.sendMessage("§b[Hub] §fYou received a §dHub Compass§f — use it to return to the lobby!"); +} + +world.afterEvents.playerSpawn.subscribe((event) => { + const player = event.player; + // Small delay to let inventory load + system.runTimeout(() => { + try { + giveCompassIfMissing(player); + } catch (e) { + // Silently ignore — player may have disconnected + } + }, 20); +}); + +// ─── B. Compass Use Transfer ──────────────────────────────────── + +world.afterEvents.itemUse.subscribe((event) => { + const player = event.source; + const item = event.itemStack; + + if (item.typeId !== COMPASS_ID) return; + doTransfer(player); +}); + +// ─── C. Portal Zone Detection ─────────────────────────────────── + +system.runInterval(() => { + const portalJson = world.getDynamicProperty(PORTAL_PROP); + if (!portalJson) return; + + let portal; + try { + portal = JSON.parse(portalJson); + } catch { + return; + } + + const now = Date.now(); + const players = world.getAllPlayers(); + + for (const player of players) { + if (recentTransfers.has(player.name) && now - recentTransfers.get(player.name) < TRANSFER_COOLDOWN) { + continue; + } + + const pos = player.location; + const dx = Math.abs(pos.x - portal.x); + const dy = Math.abs(pos.y - portal.y); + const dz = Math.abs(pos.z - portal.z); + + if (dx <= PORTAL_RADIUS && dy <= 3 && dz <= PORTAL_RADIUS) { + doTransfer(player); + } + } +}, 20); + +// ─── D. Chat Commands ─────────────────────────────────────────── + +function handleChatCommand(player, msg) { + if (msg === "!compass") { + try { + giveCompassIfMissing(player); + player.sendMessage("§b[Hub] §fCompass check complete."); + } catch (e) { + player.sendMessage(`§c[Hub] §fCouldn't give compass: ${e.message}`); + } + return true; + } + + if (msg === "!setportal") { + const pos = player.location; + const loc = { + x: Math.floor(pos.x), + y: Math.floor(pos.y), + z: Math.floor(pos.z), + }; + world.setDynamicProperty(PORTAL_PROP, JSON.stringify(loc)); + buildPortal(loc, player.dimension); + player.sendMessage(`§b[Hub] §fReturn portal set at §d${loc.x}, ${loc.y}, ${loc.z}§f!`); + return true; + } + + if (msg === "!hub" || msg === "!lobby") { + doTransfer(player); + return true; + } + + return false; +} + +// Try beforeEvents.chatSend (pre-release in some BDS versions) +try { + world.beforeEvents.chatSend.subscribe((event) => { + const msg = event.message.trim().toLowerCase(); + if (msg.startsWith("!")) { + event.cancel = true; + const player = event.sender; + system.run(() => handleChatCommand(player, msg)); + } + }); +} catch { + // chatSend not available — fall back to polling player chat via scriptEvent +} + +// Fallback: listen for scriptevent commands (players run: /scriptevent hub:cmd ) +system.afterEvents.scriptEventReceive.subscribe((event) => { + if (event.id !== "hub:cmd") return; + const player = event.sourceEntity; + if (!player) return; + const msg = (event.message || "").trim().toLowerCase(); + handleChatCommand(player, `!${msg}`); +}); + +// ─── E. Portal Auto-Build on First Load ───────────────────────── + +function buildPortal(loc, dimension) { + const x = loc.x; + const y = loc.y; + const z = loc.z; + + const commands = []; + + // Clear space for portal (3 wide, 5 tall, 1 deep) + commands.push(`fill ${x - 1} ${y} ${z} ${x + 1} ${y + 4} ${z} air`); + + // Base row: 3 obsidian + commands.push(`setblock ${x - 1} ${y} ${z} obsidian`); + commands.push(`setblock ${x} ${y} ${z} obsidian`); + commands.push(`setblock ${x + 1} ${y} ${z} obsidian`); + + // Left column: 3 crying obsidian + commands.push(`setblock ${x - 1} ${y + 1} ${z} crying_obsidian`); + commands.push(`setblock ${x - 1} ${y + 2} ${z} crying_obsidian`); + commands.push(`setblock ${x - 1} ${y + 3} ${z} crying_obsidian`); + + // Right column: 3 crying obsidian + commands.push(`setblock ${x + 1} ${y + 1} ${z} crying_obsidian`); + commands.push(`setblock ${x + 1} ${y + 2} ${z} crying_obsidian`); + commands.push(`setblock ${x + 1} ${y + 3} ${z} crying_obsidian`); + + // Center: 3 purple stained glass + commands.push(`setblock ${x} ${y + 1} ${z} stained_glass ["color":"purple"]`); + commands.push(`setblock ${x} ${y + 2} ${z} stained_glass ["color":"purple"]`); + commands.push(`setblock ${x} ${y + 3} ${z} stained_glass ["color":"purple"]`); + + // Top: 1 obsidian cap + commands.push(`setblock ${x} ${y + 4} ${z} obsidian`); + + for (const cmd of commands) { + try { + dimension.runCommand(cmd); + } catch (e) { + // Block placement may fail if chunks not loaded — non-fatal + } + } +} + +system.runTimeout(() => { + const existing = world.getDynamicProperty(PORTAL_PROP); + if (existing) return; // Portal location already set + + // Get spawn point and offset by 5 blocks on X + const spawn = world.getDefaultSpawnLocation(); + const loc = { + x: spawn.x + 5, + y: spawn.y, + z: spawn.z, + }; + + world.setDynamicProperty(PORTAL_PROP, JSON.stringify(loc)); + + // Need a dimension reference — use overworld + const overworld = world.getDimension("overworld"); + buildPortal(loc, overworld); + + world.sendMessage("§b[Hub] §fReturn portal auto-built near spawn! Use §d!setportal§f to relocate it."); +}, 100); + +system.run(() => { + world.sendMessage("§b[World] §fHub return system loaded! Use compass, step on portal, or type §d!hub§f to return."); +}); diff --git a/lobby-addon/lobby_transfer_BP/manifest.json b/lobby-addon/lobby_transfer_BP/manifest.json new file mode 100644 index 0000000..47becce --- /dev/null +++ b/lobby-addon/lobby_transfer_BP/manifest.json @@ -0,0 +1,25 @@ +{ + "format_version": 2, + "header": { + "name": "Lobby Portal Transfer", + "description": "Auto-transfers players when they step into portal areas", + "uuid": "a1b2c3d4-1111-2222-3333-abcdef123456", + "version": [1, 0, 1], + "min_engine_version": [1, 21, 0] + }, + "modules": [ + { + "type": "script", + "language": "javascript", + "uuid": "a1b2c3d4-4444-5555-6666-abcdef789012", + "version": [1, 0, 1], + "entry": "scripts/main.js" + } + ], + "dependencies": [ + { + "module_name": "@minecraft/server", + "version": "2.0.0" + } + ] +} diff --git a/lobby-addon/lobby_transfer_BP/scripts/main.js b/lobby-addon/lobby_transfer_BP/scripts/main.js new file mode 100644 index 0000000..56494cc --- /dev/null +++ b/lobby-addon/lobby_transfer_BP/scripts/main.js @@ -0,0 +1,53 @@ +import { world, system } from "@minecraft/server"; + +// Portal definitions: name, center position, and direct transfer target +const portals = [ + { name: "Jamie's World", x: -15, y: 65, z: -24, host: "10.0.0.247", port: 19133 }, + { name: "Lyla's World", x: 0, y: 65, z: -24, host: "10.0.0.247", port: 19134 }, + { name: "Mya's World", x: 15, y: 65, z: -24, host: "10.0.0.247", port: 19135 }, +]; + +const PORTAL_RADIUS_X = 2.5; +const PORTAL_RADIUS_Z = 2.0; +const PORTAL_RADIUS_Y = 2.0; +const COOLDOWN_TICKS = 100; // 5 seconds cooldown + +// Track cooldowns per player +const cooldowns = new Map(); + +system.runInterval(() => { + for (const player of world.getAllPlayers()) { + const pos = player.location; + const playerId = player.id; + + // Check cooldown + const lastTransfer = cooldowns.get(playerId) || 0; + if (system.currentTick - lastTransfer < COOLDOWN_TICKS) continue; + + for (const portal of portals) { + const dx = Math.abs(pos.x - portal.x); + const dy = Math.abs(pos.y - portal.y); + const dz = Math.abs(pos.z - portal.z); + + if (dx < PORTAL_RADIUS_X && dy < PORTAL_RADIUS_Y && dz < PORTAL_RADIUS_Z) { + cooldowns.set(playerId, system.currentTick); + player.sendMessage(`§6Transferring to ${portal.name}...`); + try { + player.runCommand(`transfer "${player.name}" ${portal.host} ${portal.port}`); + } catch (e) { + player.sendMessage(`§cTransfer failed: ${e.message}`); + } + break; + } + } + } +}, 10); // Check every half second + +// Clean up cooldowns when players leave +world.afterEvents.playerLeave.subscribe((event) => { + cooldowns.delete(event.playerId); +}); + +system.run(() => { + world.sendMessage("§6[Hub] §7Portal transfer system loaded!"); +});