diff --git a/v0.1/block-entity.wit b/v0.1/block-entity.wit index 583ab3f..363c7d7 100644 --- a/v0.1/block-entity.wit +++ b/v0.1/block-entity.wit @@ -1,6 +1,7 @@ interface block-entity { use common.{block-pos, nbt-tree}; use item-stack.{item-stack}; + use inventory.{inventory}; resource block-entity { resource-location: func() -> string; @@ -21,6 +22,8 @@ interface block-entity { resource container-block-entity { get-block-entity: func() -> block-entity; + /// Returns the generic inventory handle for this container. + get-inventory: func() -> inventory; get-size: func() -> u32; is-empty: func() -> bool; get-stack: func(slot: u32) -> option; diff --git a/v0.1/datapack.wit b/v0.1/datapack.wit new file mode 100644 index 0000000..28345c9 --- /dev/null +++ b/v0.1/datapack.wit @@ -0,0 +1,54 @@ +package pumpkin:plugin@0.1.0; + +interface datapack { + /// Information about a discovered or loaded datapack. + record datapack-info { + id: string, + name: string, + description: string, + pack-format: u32, + is-enabled: bool, + recipe-count: u32, + function-count: u32, + } + + /// Position options for enabling a datapack relative to other packs. + variant enable-position { + first, + last, + before(string), + after(string), + } + + /// Global manager for inspecting and controlling server datapacks. + resource datapack-manager { + /// Returns all known datapacks (both enabled and available/disabled). + list-all-packs: func() -> list; + + /// Returns only currently enabled datapacks. + list-enabled-packs: func() -> list; + + /// Returns available (disabled) datapacks. + list-available-packs: func() -> list; + + /// Retrieves details about a specific datapack by name or ID. + get-pack: func(name: string) -> option; + + /// Checks if a datapack is currently enabled. + is-enabled: func(name: string) -> bool; + + /// Enables a datapack with a specific priority position. + enable-pack: func(name: string, position: enable-position) -> result<_, string>; + + /// Disables an enabled datapack. + disable-pack: func(name: string) -> result<_, string>; + + /// Reloads all enabled datapacks, recipes, and function tags, + /// synchronizes recipes with online players, and triggers `#minecraft:load`. + reload: func() -> result<_, string>; + + /// Executes a datapack function or function tag (e.g. "namespace:fn" or "#namespace:tag"). + /// Returns the number of commands executed. + execute-function: func(name: string) -> result; + } +} diff --git a/v0.1/entity.wit b/v0.1/entity.wit index 1873f84..1c286b7 100644 --- a/v0.1/entity.wit +++ b/v0.1/entity.wit @@ -1 +1 @@ -interface entity { use %world.{entity, raycast-result, ray-trace-block-result, ray-trace-entity-result, block-direction}; } +interface entity { use %world.{entity, living-entity, mob, path-node-type, dye-color, villager-profession, mob-data, sheep-data, wolf-data, cat-data, villager-data, creeper-data, slime-data, enderman-data, iron-golem-data, fox-data, ageable-data, zombie-data, shulker-data, raycast-result, ray-trace-block-result, ray-trace-entity-result, block-direction}; } diff --git a/v0.1/gui.wit b/v0.1/gui.wit index d82a4d7..23aa119 100644 --- a/v0.1/gui.wit +++ b/v0.1/gui.wit @@ -3,9 +3,12 @@ interface gui { use common.{click-type}; use item-stack.{item-stack}; use screens.{screen}; + use inventory.{inventory}; resource gui { constructor(%type: screen, title: text-component); + /// Returns the underlying inventory handle for this GUI. + get-inventory: func() -> inventory; set-item: func(slot: u32, item: item-stack); get-item: func(slot: u32) -> option; diff --git a/v0.1/inventory.wit b/v0.1/inventory.wit new file mode 100644 index 0000000..ad236d8 --- /dev/null +++ b/v0.1/inventory.wit @@ -0,0 +1,78 @@ +package pumpkin:plugin@0.1.0; + +interface inventory { + use item-stack.{item-stack}; + use common.{hand}; + + /// Common inventory resource used across GUIs, player inventories, and containers. + resource inventory { + /// Returns the number of slots in this inventory. + get-size: func() -> u32; + + /// Returns true if all slots in this inventory are empty. + is-empty: func() -> bool; + + /// Returns the item in the specified slot index, or none if empty. + get-item: func(slot: u32) -> option; + + /// Sets the item in the specified slot index. + set-item: func(slot: u32, item: option); + + /// Removes and returns the item in the specified slot index. + remove-item: func(slot: u32) -> option; + + /// Clears all items from this inventory. + clear: func(); + + /// Returns all items in this inventory as a list of slots. + get-all-items: func() -> list>; + + /// Sets all items in this inventory from a list. + set-all-items: func(items: list>); + + /// Counts the total number of items with the given ID in this inventory. + count-item: func(item-id: string) -> u32; + + /// Checks if the inventory contains at least one item with the given ID. + contains-item: func(item-id: string) -> bool; + } + + /// Specialized player inventory handle providing access to main inventory, armor, offhand, and hotbar. + resource player-inventory { + /// Returns the generic 36-slot inventory handle (hotbar + main storage). + as-inventory: func() -> inventory; + + /// Returns the item currently held in the specified hand. + get-item-in-hand: func(hand: hand) -> option; + /// Sets the item in the specified hand. + set-item-in-hand: func(hand: hand, item: option); + + /// Returns the currently selected hotbar slot index (0-8). + get-selected-slot: func() -> u8; + /// Sets the currently selected hotbar slot index (0-8). + set-selected-slot: func(slot: u8); + + /// Armor slot accessors + get-helmet: func() -> option; + set-helmet: func(item: option); + + get-chestplate: func() -> option; + set-chestplate: func(item: option); + + get-leggings: func() -> option; + set-leggings: func(item: option); + + get-boots: func() -> option; + set-boots: func(item: option); + + get-off-hand: func() -> option; + set-off-hand: func(item: option); + + /// Clears all armor slots. + clear-armor: func(); + /// Clears the 36 main inventory slots. + clear-main: func(); + /// Clears all slots (main inventory, armor, offhand). + clear-all: func(); + } +} diff --git a/v0.1/player.wit b/v0.1/player.wit index b44a9bf..2d46f4b 100644 --- a/v0.1/player.wit +++ b/v0.1/player.wit @@ -16,6 +16,7 @@ interface player { use advancement.{advancement-progress}; use damage-types.{damage-type}; use statistics.{statistic-category, custom-statistic}; + use inventory.{inventory, player-inventory}; /// Represents per-player weather condition overrides. enum player-weather { @@ -947,6 +948,11 @@ interface player { // Inventory + /// Returns the player's inventory handle for managing main storage, armor, and equipment. + get-inventory: func () -> player-inventory; + /// Returns the player's ender chest inventory handle. + get-ender-chest: func () -> inventory; + /// Returns the index of the currently selected hotbar slot (0-8). get-selected-slot: func () -> u8; /// Returns the item currently in the specified hand. diff --git a/v0.1/plugin.wit b/v0.1/plugin.wit index 13b7b5b..7cc8a49 100644 --- a/v0.1/plugin.wit +++ b/v0.1/plugin.wit @@ -55,6 +55,10 @@ world plugin { import advancement; /// Provides custom recipe registration and management. import recipe; + /// Provides inventory manipulation and management. + import inventory; + /// Provides datapack inspection and management. + import datapack; /// Provides custom enchantment registration and management. import enchantments; /// Provides damage types. diff --git a/v0.1/server.wit b/v0.1/server.wit index d4f9a7d..a57f0c7 100644 --- a/v0.1/server.wit +++ b/v0.1/server.wit @@ -8,6 +8,7 @@ interface server { use enchantments.{enchantment-manager, custom-enchantment}; use permission.{permission-level}; use advancement.{advancement-info}; + use datapack.{datapack-manager, datapack-info}; /// Represents an operator entry in the ops configuration. record op-entry { @@ -269,5 +270,8 @@ interface server { /// Returns a list of all registered enchantment IDs (custom and vanilla) on the server. get-all-enchantment-ids: func() -> list; + + /// Returns the global datapack manager for inspecting, enabling, disabling, and reloading datapacks. + get-datapack-manager: func() -> datapack-manager; } } diff --git a/v0.1/world.wit b/v0.1/world.wit index 5242bf5..034528e 100644 --- a/v0.1/world.wit +++ b/v0.1/world.wit @@ -53,7 +53,175 @@ interface %world { creeper-ignite, eat-grass, zombie-attack(f32), + } + /// Node and terrain classification types evaluated during mob pathfinding. + enum path-node-type { + blocked, + open, + walkable, + walkable-door, + trapdoor, + powder-snow, + danger-powder-snow, + fence, + lava, + water, + water-border, + rail, + unpassable-rail, + danger-fire, + damage-fire, + danger-other, + damage-other, + door-open, + door-wood-closed, + door-iron-closed, + breach, + leaves, + sticky-honey, + cocoa, + damage-cautious, + danger-trapdoor, + } + + /// Minecraft 16 dye colors. + enum dye-color { + white, + orange, + magenta, + light-blue, + yellow, + lime, + pink, + gray, + light-gray, + cyan, + purple, + blue, + brown, + green, + red, + black, + } + + /// Villager profession identifiers. + enum villager-profession { + none, + armorer, + butcher, + cartographer, + cleric, + farmer, + fisherman, + fletcher, + leatherworker, + librarian, + mason, + nitwit, + shepherd, + toolsmith, + weaponsmith, + } + + /// Specialized data for sheep entities. + record sheep-data { + color: dye-color, + is-sheared: bool, + } + + /// Specialized data for wolf entities. + record wolf-data { + is-tamed: bool, + owner: option, + is-sitting: bool, + collar-color: dye-color, + is-angry: bool, + is-begging: bool, + } + + /// Specialized data for cat entities. + record cat-data { + is-tamed: bool, + owner: option, + is-sitting: bool, + collar-color: dye-color, + } + + /// Specialized data for villager entities. + record villager-data { + profession: villager-profession, + level: u8, + experience: u32, + } + + /// Specialized data for creeper entities. + record creeper-data { + is-powered: bool, + fuse: s32, + is-ignited: bool, + explosion-radius: u8, + } + + /// Specialized data for slime and magma cube entities. + record slime-data { + size: s32, + } + + /// Specialized data for enderman entities. + record enderman-data { + carried-block-state: option, + is-screaming: bool, + is-staring: bool, + } + + /// Specialized data for iron golem entities. + record iron-golem-data { + is-player-created: bool, + } + + /// Specialized data for fox entities. + record fox-data { + is-sitting: bool, + is-sleeping: bool, + is-crouching: bool, + } + + /// Specialized data for ageable animal mobs. + record ageable-data { + is-baby: bool, + age: s32, + in-love-ticks: s32, + } + + /// Specialized data for zombie entities. + record zombie-data { + is-baby: bool, + can-break-doors: bool, + } + + /// Specialized data for shulker entities. + record shulker-data { + attached-face: block-direction, + peek-amount: u8, + color: option, + } + + /// Tagged variant holding specialized data for specific mob types. + variant mob-data { + sheep(sheep-data), + wolf(wolf-data), + cat(cat-data), + villager(villager-data), + creeper(creeper-data), + slime(slime-data), + enderman(enderman-data), + iron-golem(iron-golem-data), + fox(fox-data), + ageable(ageable-data), + zombie(zombie-data), + shulker(shulker-data), + generic, } /// Categories for sounds to control their volume independently. @@ -277,46 +445,6 @@ interface %world { get-fire-ticks: func() -> s32; set-fire-ticks: func(ticks: s32); - get-health: func() -> f32; - set-health: func(health: f32); - get-max-health: func() -> f32; - damage: func(amount: f32, damage-type: damage-type); - is-dead: func() -> bool; - - get-absorption: func() -> f32; - set-absorption: func(amount: f32); - - // Attributes - - /// Returns the computed value of the specified attribute for this entity. - get-attribute-value: func(attr: attribute) -> f64; - /// Returns the base value of the specified attribute for this entity. - get-attribute-base: func(attr: attribute) -> f64; - /// Sets the base value of the specified attribute for this entity. - set-attribute-base: func(attr: attribute, value: f64); - /// Adds or replaces an attribute modifier for the specified attribute. - add-attribute-modifier: func(attr: attribute, modifier: attribute-modifier); - /// Removes an attribute modifier by its identifier. - remove-attribute-modifier: func(attr: attribute, id: string); - /// Returns all attribute modifiers currently attached to the specified attribute. - get-attribute-modifiers: func(attr: attribute) -> list; - /// Resets the specified attribute to its default base value with no modifiers. - reset-attribute: func(attr: attribute); - /// Resets all attributes on this entity to their default base values and removes all modifiers. - reset-all-attributes: func(); - - // Equipment - - /// Gets the item currently equipped in the specified slot, if any. - get-equipment: func(slot: equipment-slot) -> option; - /// Sets the item equipped in the specified slot and broadcasts the change to tracking clients. - set-equipment: func(slot: equipment-slot, stack: option); - /// Clears all equipment on this entity and broadcasts the removal. - clear-equipment: func(); - - get-age: func() -> s32; - set-age: func(age: s32); - get-fall-distance: func() -> f32; set-fall-distance: func(distance: f32); @@ -359,8 +487,6 @@ interface %world { set-remaining-air: func(air: s32); get-max-air: func() -> s32; - send-system-message: func(message: text-component); - get-eye-height: func() -> f32; get-eye-position: func() -> position; @@ -380,27 +506,6 @@ interface %world { remove: func(); - /// Adds a built-in AI goal to this mob entity at the specified priority level. - add-ai-goal: func(priority: u8, goal: builtin-ai-goal); - - /// Adds a custom AI goal to this mob entity at the specified priority level. - add-custom-ai-goal: func(priority: u8, goal-id: u32); - - /// Removes all AI goals from this mob entity. - clear-ai-goals: func(); - - /// Sets whether AI execution is disabled for this entity. - set-ai-disabled: func(disabled: bool); - - /// Checks if AI execution is disabled for this entity. - is-ai-disabled: func() -> bool; - - /// Sets the target entity for this mob. - set-target: func(target: option); - - /// Gets the current target entity of this mob, if any. - get-target: func() -> option; - /// Performs a raycast from the entity's eye position in its looking direction. raycast: func(max-distance: f64, fluid-handling: bool) -> option; @@ -421,6 +526,98 @@ interface %world { remove-custom-data: func(namespace: string, key: string); /// Returns whether this entity has a namespaced custom data value. has-custom-data: func(namespace: string, key: string) -> bool; + + /// Returns this entity as a living-entity if it has health and attributes, or none otherwise. + as-living: func() -> option; + + /// Returns this entity as a mob if it is an AI-driven mob entity, or none otherwise. + as-mob: func() -> option; + + /// Returns whether this entity is a living entity. + is-living: func() -> bool; + + /// Returns whether this entity is an AI-driven mob. + is-mob: func() -> bool; + } + + /// Represents a living entity with health, combat stats, attributes, and equipment (mobs, players, armor stands). + resource living-entity { + /// Converts back to the base entity handle. + as-entity: func() -> entity; + + /// Returns this living entity as a mob if it has AI/navigation, or none otherwise. + as-mob: func() -> option; + + /// Returns whether this living entity is an AI-driven mob. + is-mob: func() -> bool; + + // Health & Combat + get-health: func() -> f32; + set-health: func(health: f32); + get-max-health: func() -> f32; + set-max-health: func(max-health: f32); + damage: func(amount: f32, damage-type: damage-type); + is-dead: func() -> bool; + + get-absorption: func() -> f32; + set-absorption: func(amount: f32); + + // Attributes + get-attribute-value: func(attr: attribute) -> f64; + get-attribute-base: func(attr: attribute) -> f64; + set-attribute-base: func(attr: attribute, value: f64); + add-attribute-modifier: func(attr: attribute, modifier: attribute-modifier); + remove-attribute-modifier: func(attr: attribute, id: string); + get-attribute-modifiers: func(attr: attribute) -> list; + reset-attribute: func(attr: attribute); + reset-all-attributes: func(); + + // Equipment + get-equipment: func(slot: equipment-slot) -> option; + set-equipment: func(slot: equipment-slot, stack: option); + clear-equipment: func(); + + get-age: func() -> s32; + set-age: func(age: s32); + send-system-message: func(message: text-component); + } + + /// Represents an AI-driven mob entity with goals, targeting, and pathfinding navigation (e.g. zombies, villagers). + resource mob { + /// Converts back to the base entity handle. + as-entity: func() -> entity; + + /// Converts to the living-entity handle. + as-living: func() -> living-entity; + + // Goals & Targeting + add-ai-goal: func(priority: u8, goal: builtin-ai-goal); + add-custom-ai-goal: func(priority: u8, goal-id: u32); + clear-ai-goals: func(); + set-ai-disabled: func(disabled: bool); + is-ai-disabled: func() -> bool; + set-target: func(target: option); + get-target: func() -> option; + + // Pathfinding & Navigation + navigate-to-pos: func(pos: position, speed: f64) -> bool; + navigate-to-entity: func(target: entity, speed: f64) -> bool; + stop-navigation: func(); + is-navigating: func() -> bool; + has-reached-destination: func() -> bool; + set-navigation-speed: func(speed: f64); + can-reach: func(pos: position, max-distance: f32) -> bool; + set-pathfinding-malus: func(node-type: path-node-type, malus: f32); + get-pathfinding-malus: func(node-type: path-node-type) -> f32; + look-at: func(pos: position); + look-at-entity: func(target: entity); + + /// Returns the specialized mob-specific data for this mob. + get-mob-data: func() -> mob-data; + + /// Sets the specialized mob-specific data for this mob. + /// Returns false if the provided data variant is incompatible with this mob. + set-mob-data: func(data: mob-data) -> bool; } /// Result of a raycast operation.