Files
RustNotMC/crates/horizon-mod-sdk/examples/beacons/src/lib.rs
T
SashegDev 874b6f20c2 Клиент: начальный импорт кодовой базы
Основа — Horizon (MIT). История апстрима не переносится: этот репозиторий ведёт свою.
2026-10-29 22:04:28 +03:00

104 lines
3.2 KiB
Rust

//! Example Horizon server mod (`docs/mods.md`, "Server mods") with
//! capability `world` and typed commands: `/beacon [height]` lights a
//! pillar of glowstone two blocks east of the player, `/ground [pos]` reads
//! the block under their feet (or at `pos`) and its biome.
use horizon_mod_sdk::server::{
Args, Argument, BlockChange, Player, Registration, ServerMod, players, world,
};
/// How tall `/beacon` builds when no height is given.
const HEIGHT: i32 = 4;
struct Beacons;
/// The block the player stands in: their feet, floored.
fn feet(player: &Player) -> (i32, i32, i32) {
(
player.x.floor() as i32,
player.y.floor() as i32,
player.z.floor() as i32,
)
}
/// The pillar beside `player`: `height` blocks of glowstone, from their feet up.
fn pillar(player: &Player, height: i32) -> Vec<BlockChange> {
let (x, y, z) = feet(player);
(0..height)
.map(|dy| BlockChange {
x: x + 2,
y: y + dy,
z,
state: "minecraft:glowstone".into(),
})
.collect()
}
impl ServerMod for Beacons {
fn init() -> Result<(Self, Registration), String> {
Ok((
Beacons,
Registration::new()
.command_with(
"beacon",
[Argument::integer("height", Some(1), Some(64)).optional()],
)
.command_with("ground", [Argument::block_pos("pos").optional()]),
))
}
fn command(
&mut self,
player: &Player,
name: &str,
args: &Args,
) -> Result<Option<String>, String> {
let (x, y, z) = feet(player);
if name == "beacon" {
let height = args.integer("height").unwrap_or(HEIGHT);
world::set_blocks(&player.dimension, &pillar(player, height))?;
players::broadcast(&format!(
"{} lit a beacon at {} {y} {z}",
player.name,
x + 2
));
return Ok(None);
}
let (bx, by, bz) = match args.block_pos("pos") {
Some(p) => (p.x, p.y, p.z),
None => (x, y - 1, z),
};
let block =
world::get_block(&player.dimension, bx, by, bz).ok_or("That block isn't loaded")?;
let biome = world::get_biome(&player.dimension, bx, by, bz).unwrap_or_default();
if args.block_pos("pos").is_some() {
return Ok(Some(format!("{bx} {by} {bz} is {block} in {biome}")));
}
Ok(Some(format!("You are standing on {block} in {biome}")))
}
}
horizon_mod_sdk::export_server_mod!(Beacons);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_pillar_stands_two_blocks_east() {
let p = Player {
id: String::new(),
name: "Alex".into(),
x: -0.5,
y: 64.0,
z: 3.2,
dimension: "minecraft:overworld".into(),
game_mode: horizon_mod_sdk::server::GameMode::Survival,
health: 20.0,
};
let blocks = pillar(&p, HEIGHT);
assert_eq!(blocks.len(), HEIGHT as usize);
assert_eq!((blocks[0].x, blocks[0].y, blocks[0].z), (1, 64, 3));
assert_eq!(blocks[3].y, 67);
}
}