mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
Mod API entries and dispatch calls for #6624's hooks
Main requires a mod_api entry for every pending fragment since #6253; cargo run -p xtask -- mod-api filled the dispatch calls. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
2bc228cfd0
commit
91acd76265
6 files changed
+255
-8
No files matched your search
@@ -2671,7 +2671,15 @@ impl Game<'_> {
|
||||
slot: &str,
|
||||
cancel: &mut bool,
|
||||
) {
|
||||
let _ = (player, name, stand_id, slot, cancel);
|
||||
mod_api::dispatch_armor_stand_manipulate(
|
||||
self,
|
||||
mod_api::mods(),
|
||||
player,
|
||||
name,
|
||||
stand_id,
|
||||
slot,
|
||||
cancel,
|
||||
);
|
||||
}
|
||||
/// A boat or minecart (`kind`, `minecraft:oak_boat`) moved since the last
|
||||
/// tick (`VehicleMoveEvent`): `from` and `to` are its positions, heard
|
||||
@@ -2692,7 +2700,7 @@ impl Game<'_> {
|
||||
from: [f64; 3],
|
||||
to: [f64; 3],
|
||||
) {
|
||||
let _ = (player, kind, from, to);
|
||||
mod_api::dispatch_vehicle_moved(self, mod_api::mods(), player, kind, from, to);
|
||||
}
|
||||
/// A player opens one of the game's own menus (`ServerPlayer.openMenu`; the
|
||||
/// job of NeoForge's `PlayerContainerEvent.Open`, which comes after the
|
||||
@@ -2718,7 +2726,7 @@ impl Game<'_> {
|
||||
pos: Option<[i32; 3]>,
|
||||
cancel: &mut bool,
|
||||
) {
|
||||
let _ = (player, name, kind, pos, cancel);
|
||||
mod_api::dispatch_container_opened(self, mod_api::mods(), player, name, kind, pos, cancel);
|
||||
}
|
||||
/// A creative-mode player sets a slot of their inventory from the
|
||||
/// creative screen (`ServerGamePacketListenerImpl.handleSetCreativeModeSlot`):
|
||||
@@ -2743,7 +2751,16 @@ impl Game<'_> {
|
||||
count: i32,
|
||||
cancel: &mut bool,
|
||||
) {
|
||||
let _ = (player, name, slot, item, count, cancel);
|
||||
mod_api::dispatch_creative_slot(
|
||||
self,
|
||||
mod_api::mods(),
|
||||
player,
|
||||
name,
|
||||
slot,
|
||||
item,
|
||||
count,
|
||||
cancel,
|
||||
);
|
||||
}
|
||||
/// A server player's game mode is about to change (NeoForge's
|
||||
/// `PlayerChangeGameModeEvent`): from `from` to `to` (0 survival, 1
|
||||
|
||||
+215
@@ -2570,6 +2570,74 @@ pub trait Hooks: Send + Sync {
|
||||
let _ = host;
|
||||
let _ = event;
|
||||
}
|
||||
/// A player takes an item from an armor stand or puts one on it
|
||||
/// (`ArmorStand.interactAt`, after the stand's disabled-slot checks and
|
||||
/// `swapItem`'s take/put locks, before anything moves): `stand_id` is the
|
||||
/// stand's `Entity.getId` and `slot` the one the click reached
|
||||
/// (`mainhand`, `offhand`, `feet`, `legs`, `chest` or `head`). Set
|
||||
/// `cancel` and nothing changes: neither the stand nor the player's hand,
|
||||
/// and the click is spent. The player's state is swapped in for the call;
|
||||
/// `player` is the UUID the helpers take. Not told of a click that changes
|
||||
/// nothing (an empty hand on an empty slot). Not covered, other ways a
|
||||
/// stand's equipment moves: breaking or blasting the stand (its items
|
||||
/// drop), a dispenser putting armour on one, a mod's own changes.
|
||||
/// Server-side, for every player of the world.
|
||||
/// @API:native_armor_stand_manipulate@.
|
||||
///
|
||||
/// Return `Flow::Cancel` to take it: this sets `cancel`, and later mods are skipped.
|
||||
fn armor_stand_manipulate(
|
||||
&self,
|
||||
host: &mut dyn Host,
|
||||
event: &mut ArmorStandManipulateEvent<'_>,
|
||||
) -> Flow {
|
||||
let _ = host;
|
||||
let _ = event;
|
||||
Flow::Continue
|
||||
}
|
||||
/// A player opens one of the game's own menus (`ServerPlayer.openMenu`; the
|
||||
/// job of NeoForge's `PlayerContainerEvent.Open`, which comes after the
|
||||
/// menu is open and cannot stop it): `kind` is the menu type
|
||||
/// (`minecraft:generic_9x3`, `minecraft:furnace`, `minecraft:crafting`,
|
||||
/// `minecraft:merchant`, `minecraft:anvil`, `minecraft:lectern`...; a
|
||||
/// horse's inventory is `minecraft:horse_inventory`) and `pos` the block
|
||||
/// it belongs to, none for a villager, a mount or a vehicle's chest.
|
||||
/// Heard after the checks that refuse the menu (a locked container, a
|
||||
/// spectator) and before the menu that was open closes. Set `cancel` and
|
||||
/// nothing opens: the open menu stays as it was and the click is spent.
|
||||
/// The player's state is swapped in for the call, as for
|
||||
/// `native_perform_command`, so `native_acting_player`, `native_tell` and
|
||||
/// the item helpers reach them. Not heard: a menu a mod opens
|
||||
/// (`native_open_menu`), the inventory screen, and the editors (sign,
|
||||
/// book, command block). Server-side, for every player of the world.
|
||||
/// @API:native_container_opened@.
|
||||
///
|
||||
/// Return `Flow::Cancel` to take it: this sets `cancel`, and later mods are skipped.
|
||||
fn container_opened(&self, host: &mut dyn Host, event: &mut ContainerOpenedEvent<'_>) -> Flow {
|
||||
let _ = host;
|
||||
let _ = event;
|
||||
Flow::Continue
|
||||
}
|
||||
/// A creative-mode player sets a slot of their inventory from the
|
||||
/// creative screen (`ServerGamePacketListenerImpl.handleSetCreativeModeSlot`):
|
||||
/// `slot` is the inventory menu's slot (5 to 8 armour, 9 to 35 the
|
||||
/// inventory, 36 to 44 the hotbar, 45 the off hand; below 0 is a stack
|
||||
/// thrown out of the screen, which is dropped) and `item` (`minecraft:air`
|
||||
/// for an emptied slot) and `count` what is put there. Heard once the
|
||||
/// packet passed vanilla's checks (a creative player, a real slot, a valid
|
||||
/// stack) and before the slot changes or the stack drops. Set `cancel`
|
||||
/// and the packet is ignored. The player's state is swapped in for the
|
||||
/// call, as for `native_perform_command`, so `native_acting_player`,
|
||||
/// `native_tell` and the item helpers reach them. Not heard: stacks a
|
||||
/// creative player gets other ways (middle-click pick block, `/give`).
|
||||
/// Server-side, for every player of the world.
|
||||
/// @API:native_creative_slot@.
|
||||
///
|
||||
/// Return `Flow::Cancel` to take it: this sets `cancel`, and later mods are skipped.
|
||||
fn creative_slot(&self, host: &mut dyn Host, event: &mut CreativeSlotEvent<'_>) -> Flow {
|
||||
let _ = host;
|
||||
let _ = event;
|
||||
Flow::Continue
|
||||
}
|
||||
/// The food level of the server player `player` (`name`) is about to change
|
||||
/// from `from` to `to` (Bukkit's `FoodLevelChangeEvent`):
|
||||
/// eating, hunger and saturation effects, the exhaustion that costs a
|
||||
@@ -2777,6 +2845,22 @@ pub trait Hooks: Send + Sync {
|
||||
let _ = host;
|
||||
let _ = event;
|
||||
}
|
||||
/// A boat or minecart (`kind`, `minecraft:oak_boat`) moved since the last
|
||||
/// tick (`VehicleMoveEvent`): `from` and `to` are its positions, heard
|
||||
/// after the tick moved it. Once a tick for each vehicle that carries a
|
||||
/// server player, whose state is then swapped in (as for
|
||||
/// `native_perform_command`: `native_acting_player`, `native_tell` and
|
||||
/// the item helpers reach them; `player` is their UUID), and for one a
|
||||
/// server player rode and left, until it has stood still for ten
|
||||
/// seconds (`player` is none, nobody is swapped in). It only hears.
|
||||
/// Cheap when nothing moves: one position compare a tick for each watched
|
||||
/// vehicle. Not heard: a vehicle moved before anyone rode it, a mount
|
||||
/// (horse, pig...) or a vehicle carrying only a mob. Server-side, in the
|
||||
/// level the vehicle is in. @API:native_vehicle_moved@.
|
||||
fn vehicle_moved(&self, host: &mut dyn Host, event: &mut VehicleMovedEvent<'_>) {
|
||||
let _ = host;
|
||||
let _ = event;
|
||||
}
|
||||
}
|
||||
/// What [`Hooks::frame`] is told. Fields may be added: the struct is `#[non_exhaustive]`.
|
||||
#[non_exhaustive]
|
||||
@@ -7323,6 +7407,111 @@ pub fn dispatch_item_crafted(
|
||||
mod_hook.item_crafted(host, &mut event);
|
||||
}
|
||||
}
|
||||
/// What [`Hooks::armor_stand_manipulate`] is told. Fields may be added: the struct is `#[non_exhaustive]`.
|
||||
#[non_exhaustive]
|
||||
pub struct ArmorStandManipulateEvent<'a> {
|
||||
pub player: u128,
|
||||
pub name: &'a str,
|
||||
pub stand_id: i32,
|
||||
pub slot: &'a str,
|
||||
}
|
||||
pub fn dispatch_armor_stand_manipulate(
|
||||
host: &mut dyn Host,
|
||||
mods: &[Box<dyn Hooks>],
|
||||
player: u128,
|
||||
name: &str,
|
||||
stand_id: i32,
|
||||
slot: &str,
|
||||
cancel: &mut bool,
|
||||
) {
|
||||
if *cancel {
|
||||
return;
|
||||
}
|
||||
let mut event = ArmorStandManipulateEvent {
|
||||
player,
|
||||
name,
|
||||
stand_id,
|
||||
slot,
|
||||
};
|
||||
for mod_hook in mods {
|
||||
if matches!(
|
||||
mod_hook.armor_stand_manipulate(host, &mut event),
|
||||
Flow::Cancel
|
||||
) {
|
||||
*cancel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// What [`Hooks::container_opened`] is told. Fields may be added: the struct is `#[non_exhaustive]`.
|
||||
#[non_exhaustive]
|
||||
pub struct ContainerOpenedEvent<'a> {
|
||||
pub player: u128,
|
||||
pub name: &'a str,
|
||||
pub kind: &'a str,
|
||||
pub pos: Option<[i32; 3]>,
|
||||
}
|
||||
pub fn dispatch_container_opened(
|
||||
host: &mut dyn Host,
|
||||
mods: &[Box<dyn Hooks>],
|
||||
player: u128,
|
||||
name: &str,
|
||||
kind: &str,
|
||||
pos: Option<[i32; 3]>,
|
||||
cancel: &mut bool,
|
||||
) {
|
||||
if *cancel {
|
||||
return;
|
||||
}
|
||||
let mut event = ContainerOpenedEvent {
|
||||
player,
|
||||
name,
|
||||
kind,
|
||||
pos,
|
||||
};
|
||||
for mod_hook in mods {
|
||||
if matches!(mod_hook.container_opened(host, &mut event), Flow::Cancel) {
|
||||
*cancel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// What [`Hooks::creative_slot`] is told. Fields may be added: the struct is `#[non_exhaustive]`.
|
||||
#[non_exhaustive]
|
||||
pub struct CreativeSlotEvent<'a> {
|
||||
pub player: u128,
|
||||
pub name: &'a str,
|
||||
pub slot: i32,
|
||||
pub item: &'a str,
|
||||
pub count: i32,
|
||||
}
|
||||
pub fn dispatch_creative_slot(
|
||||
host: &mut dyn Host,
|
||||
mods: &[Box<dyn Hooks>],
|
||||
player: u128,
|
||||
name: &str,
|
||||
slot: i32,
|
||||
item: &str,
|
||||
count: i32,
|
||||
cancel: &mut bool,
|
||||
) {
|
||||
if *cancel {
|
||||
return;
|
||||
}
|
||||
let mut event = CreativeSlotEvent {
|
||||
player,
|
||||
name,
|
||||
slot,
|
||||
item,
|
||||
count,
|
||||
};
|
||||
for mod_hook in mods {
|
||||
if matches!(mod_hook.creative_slot(host, &mut event), Flow::Cancel) {
|
||||
*cancel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// What [`Hooks::food_level_changed`] is told. Fields may be added: the struct is `#[non_exhaustive]`.
|
||||
#[non_exhaustive]
|
||||
pub struct FoodLevelChangedEvent<'a> {
|
||||
@@ -7635,3 +7824,29 @@ pub fn dispatch_resource_pack_status(
|
||||
mod_hook.resource_pack_status(host, &mut event);
|
||||
}
|
||||
}
|
||||
/// What [`Hooks::vehicle_moved`] is told. Fields may be added: the struct is `#[non_exhaustive]`.
|
||||
#[non_exhaustive]
|
||||
pub struct VehicleMovedEvent<'a> {
|
||||
pub player: Option<u128>,
|
||||
pub kind: &'a str,
|
||||
pub from: [f64; 3],
|
||||
pub to: [f64; 3],
|
||||
}
|
||||
pub fn dispatch_vehicle_moved(
|
||||
host: &mut dyn Host,
|
||||
mods: &[Box<dyn Hooks>],
|
||||
player: Option<u128>,
|
||||
kind: &str,
|
||||
from: [f64; 3],
|
||||
to: [f64; 3],
|
||||
) {
|
||||
let mut event = VehicleMovedEvent {
|
||||
player,
|
||||
kind,
|
||||
from,
|
||||
to,
|
||||
};
|
||||
for mod_hook in mods {
|
||||
mod_hook.vehicle_moved(host, &mut event);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,11 @@
|
||||
"target": "horizon_client::game::native_hooks::Game<'_>::native_armor_stand_manipulate",
|
||||
"neoforge": "none (Bukkit's PlayerArmorStandManipulateEvent)",
|
||||
"side": "server",
|
||||
"cancellable": true
|
||||
"cancellable": true,
|
||||
"mod_api": {
|
||||
"contract": "cancel",
|
||||
"out": "cancel"
|
||||
}
|
||||
}
|
||||
],
|
||||
"rust_summary": "a player taking an item from or putting one on an armor stand, cancellable (`native_armor_stand_manipulate`).",
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
"target": "horizon_client::game::native_hooks::Game<'_>::native_container_opened",
|
||||
"neoforge": "none (NeoForge's PlayerContainerEvent.Open fires after the menu is open and is not cancellable)",
|
||||
"side": "server",
|
||||
"cancellable": true
|
||||
"cancellable": true,
|
||||
"mod_api": {
|
||||
"contract": "cancel",
|
||||
"out": "cancel"
|
||||
}
|
||||
}
|
||||
],
|
||||
"rust_summary": "a player opening one of the game's menus, cancellable (`native_container_opened`).",
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
"name": "creative_slot",
|
||||
"target": "horizon_client::game::native_hooks::Game<'_>::native_creative_slot",
|
||||
"side": "server",
|
||||
"cancellable": true
|
||||
"cancellable": true,
|
||||
"mod_api": {
|
||||
"contract": "cancel",
|
||||
"out": "cancel"
|
||||
}
|
||||
}
|
||||
],
|
||||
"rust_summary": "a creative player setting a slot from the creative screen, cancellable (`native_creative_slot`).",
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
{
|
||||
"name": "vehicle_moved",
|
||||
"target": "horizon_client::game::native_hooks::Game<'_>::native_vehicle_moved",
|
||||
"side": "server"
|
||||
"side": "server",
|
||||
"mod_api": {
|
||||
"contract": "listen"
|
||||
}
|
||||
}
|
||||
],
|
||||
"rust_summary": "a boat or minecart a server player rides having moved (`native_vehicle_moved`).",
|
||||
|
||||
Reference in new issue
Block a user