From ab193d1160b90c446fb35d48e6c636d8f867c473 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Tue, 4 Aug 2026 20:26:20 +0200 Subject: [PATCH] feat: status effects --- v0.1/player.wit | 104 +++++++++++++++++++++++++++++++++++++++++ v0.1/plugin.wit | 9 ++++ v0.1/status-effect.wit | 54 +++++++++++++++++++++ v0.1/world.wit | 48 +++++++++++++++++++ 4 files changed, 215 insertions(+) create mode 100644 v0.1/status-effect.wit diff --git a/v0.1/player.wit b/v0.1/player.wit index 2f110a2..9a906a1 100644 --- a/v0.1/player.wit +++ b/v0.1/player.wit @@ -11,6 +11,26 @@ interface player { use java-packets.{clientbound-packet as java-packet}; use bedrock-packets.{clientbound-packet as bedrock-packet}; use uuid.{uuid}; + use status-effect.{status-effect-type, status-effect-instance}; + + /// Represents per-player weather condition overrides. + enum player-weather { + clear, + downfall, + } + + /// Types of projectiles that can be launched by a player. + enum projectile-type { + arrow, + snowball, + egg, + ender-pearl, + splash-potion, + fireball, + small-fireball, + trident, + wind-charge, + } /// Various abilities a player can have. record player-abilities { @@ -637,6 +657,50 @@ interface player { /// Transfers the player to another server. transfer: func (host: string, port: u16); + // Status Effects + + /// Gives a status effect to the player. + add-effect: func(effect: status-effect-instance); + /// Removes a status effect from the player. + remove-effect: func(effect: status-effect-type); + /// Clears all active status effects from the player. + clear-effects: func(); + /// Checks if a status effect is currently applied to the player. + has-effect: func(effect: status-effect-type) -> bool; + /// Returns the status effect instance applied to the player, if any. + get-effect: func(effect: status-effect-type) -> option; + /// Returns all status effects currently applied to the player. + get-active-effects: func() -> list; + + // Health & Damage + + /// Heals the player by a specified amount. + heal: func(amount: f32); + /// Deals damage to the player by a specified amount. + damage: func(amount: f32); + /// Kills the player instantly. + kill: func(); + + // Cooldowns + + /// Starts an item cooldown for a specific item group name. + start-cooldown: func(group: string, duration-ticks: s32); + /// Returns the cooldown progress (0.0 to 1.0) for a specific item group. + get-cooldown: func(group: string) -> f32; + /// Checks if a specific item group is currently on cooldown. + is-on-cooldown: func(group: string) -> bool; + + // Abilities & Flight + + /// Sets whether the player is allowed to fly. + set-allow-flight: func(allowed: bool); + /// Sets the player's flying speed. + set-fly-speed: func(speed: f32); + /// Sets the player's walking speed. + set-walk-speed: func(speed: f32); + /// Sets whether the player is invulnerable to damage. + set-invulnerable: func(invulnerable: bool); + // Inventory /// Returns the index of the currently selected hotbar slot (0-8). @@ -720,6 +784,46 @@ interface player { /// Sets which skin parts are visible. set-skin-parts: func(parts: skin-parts); + // Per-Player Environment & Overrides + + /// Overrides the time of day shown to this player. + set-player-time: func(time: u64, relative: bool); + /// Resets the player's time to sync with the server world time. + reset-player-time: func(); + /// Returns the custom time set for this player, if any. + get-player-time: func() -> option; + /// Checks if the custom player time is relative to the world time. + is-player-time-relative: func() -> bool; + + /// Overrides the weather condition shown to this player. + set-player-weather: func(weather: player-weather); + /// Resets the player's weather to match the server world weather. + reset-player-weather: func(); + /// Returns the custom weather set for this player, if any. + get-player-weather: func() -> option; + + /// Sets the position where the player's compass points. + set-compass-target: func(pos: position); + /// Returns the position where the player's compass currently points. + get-compass-target: func() -> position; + + /// Sets the player's custom respawn / bed location. + set-respawn-location: func(pos: position); + /// Returns the player's custom respawn / bed location, if set. + get-respawn-location: func() -> option; + + /// Hides another player from this player's view (vanish). + hide-player: func(other: player); + /// Shows a previously hidden player to this player. + show-player: func(other: player); + /// Checks if this player can see another specified player. + can-see: func(other: player) -> bool; + + /// Raycasts from the player's eyes to find the block being targeted. + get-target-block: func(max-distance: u32) -> option; + /// Launches a projectile from the player's eyes in their line of sight. + launch-projectile: func(%type: projectile-type) -> option; + /// Returns a Java-specific player handle, if the player is connected via Java Edition. /// /// This allows access to Java-exclusive features like sending specific packets diff --git a/v0.1/plugin.wit b/v0.1/plugin.wit index f6f3749..e344188 100644 --- a/v0.1/plugin.wit +++ b/v0.1/plugin.wit @@ -8,6 +8,7 @@ world plugin { use event.{event}; use server.{server as server-instance}; use command.{command-sender, consumed-args, command-error}; + use %world.{entity}; // --- Host-provided imports --- @@ -39,6 +40,8 @@ world plugin { import forms; /// Provides Java Edition dialogs. import java-dialogs; + /// Provides status effect types and instances. + import status-effect; // --- Plugin-provided exports --- @@ -65,4 +68,10 @@ world plugin { /// Dispatches a scheduled task execution to the plugin. export handle-task: func(handler-id: u32, server: server-instance); + + export handle-ai-goal-can-start: func(goal-id: u32, server: server-instance, entity: entity) -> bool; + export handle-ai-goal-should-continue: func(goal-id: u32, server: server-instance, entity: entity) -> bool; + export handle-ai-goal-start: func(goal-id: u32, server: server-instance, entity: entity); + export handle-ai-goal-tick: func(goal-id: u32, server: server-instance, entity: entity); + export handle-ai-goal-stop: func(goal-id: u32, server: server-instance, entity: entity); } diff --git a/v0.1/status-effect.wit b/v0.1/status-effect.wit new file mode 100644 index 0000000..b2cdb4c --- /dev/null +++ b/v0.1/status-effect.wit @@ -0,0 +1,54 @@ +package pumpkin:plugin@0.1.0; + +interface status-effect { + enum status-effect-type { + speed, + slowness, + haste, + mining-fatigue, + strength, + instant-health, + instant-damage, + jump-boost, + nausea, + regeneration, + resistance, + fire-resistance, + water-breathing, + invisibility, + blindness, + night-vision, + hunger, + weakness, + poison, + wither, + health-boost, + absorption, + saturation, + glowing, + levitation, + luck, + unluck, + slow-falling, + conduit-power, + dolphins-grace, + bad-omen, + hero-of-the-village, + darkness, + trial-omen, + raid-omen, + wind-charged, + weaving, + oozing, + infested, + } + + record status-effect-instance { + effect-type: status-effect-type, + duration: u32, + amplifier: u8, + ambient: bool, + show-particles: bool, + show-icon: bool, + } +} diff --git a/v0.1/world.wit b/v0.1/world.wit index fbcea2a..b097be9 100644 --- a/v0.1/world.wit +++ b/v0.1/world.wit @@ -24,6 +24,22 @@ interface %world { push-only } + /// Predefined AI goals that can be added to mob entities. + variant builtin-ai-goal { + swim, + wander-around(f32), + melee-attack(f32), + look-at-player(f32), + look-around, + escape-danger(f32), + avoid-entity(f32), + blaze-attack, + creeper-ignite, + eat-grass, + zombie-attack(f32), + + } + /// Categories for sounds to control their volume independently. enum sound-category { master, @@ -230,6 +246,11 @@ interface %world { is-fall-flying: func() -> bool; set-fall-flying: func(fall-flying: bool); + is-silent: func() -> bool; + set-silent: func(silent: bool); + has-gravity: func() -> bool; + set-has-gravity: func(gravity: bool); + get-width: func() -> f32; get-height: func() -> f32; @@ -269,6 +290,27 @@ 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; } @@ -457,6 +499,12 @@ interface %world { /// Returns a list of all entities in this world. get-entities: func() -> list; + /// Spawns a lightning bolt at the specified position. + strike-lightning: func(pos: position, effect-only: bool); + + /// Performs a raycast from start position to end position to hit blocks. + ray-trace-blocks: func(start: position, end: position) -> option; + /// Returns the block entity at the specified position, if any. get-block-entity: func(pos: block-pos) -> option; }