Skip to main content

yog_api/
body.rs

1//! Bodies, camera and movement (`yog-body`, see its docs): pose and dress
2//! entities, disguise and morph them, move the camera, replace the local
3//! player's travel step. Register handlers with [`Registry::on_body`],
4//! [`Registry::on_camera`] and [`Registry::on_travel`]; say which entities
5//! to ask about with [`track`] and [`track_type`].
6//!
7//! [`Registry::on_body`]: crate::Registry::on_body
8//! [`Registry::on_camera`]: crate::Registry::on_camera
9//! [`Registry::on_travel`]: crate::Registry::on_travel
10
11pub use yog_body::*;
12use yog_abi::YogStr;
13
14use crate::registry::global_api;
15
16/// Asks the body handlers about entity `uuid` each frame (`on`), or stops.
17pub fn track(uuid: &str, on: bool) {
18    let api = global_api();
19    if api.is_null() {
20        return;
21    }
22    unsafe { ((*api).client_body_track)((*api).ctx, YogStr::from_str(uuid), on) }
23}
24
25/// What this client was told entity `uuid` keeps under `key`
26/// ([`yog_core::Server::set_entity_data`]); body frames carry it too
27/// ([`Frame::data`]).
28pub fn entity_data(uuid: &str, key: &str) -> Option<Vec<u8>> {
29    let api = global_api();
30    if api.is_null() {
31        return None;
32    }
33    let mut out = Vec::new();
34    let found = unsafe {
35        ((*api).client_entity_data)((*api).ctx, YogStr::from_str(uuid), YogStr::from_str(key), &mut out as *mut Vec<u8> as *mut std::os::raw::c_void, collect)
36    };
37    found.then_some(out)
38}
39
40/// A [`yog_abi::YogBytesSink`] into a `Vec<u8>`.
41pub(crate) unsafe extern "C" fn collect(sink: *mut std::os::raw::c_void, data: *const u8, len: usize) {
42    // SAFETY: `sink` is the `Vec<u8>` the caller passed; `data` is valid for the call.
43    unsafe { (*(sink as *mut Vec<u8>)).extend_from_slice(std::slice::from_raw_parts(data, len)) }
44}
45
46/// This client's side of [`yog_core::Server::entity_set_dimensions`]: the
47/// entity's own hitbox (`Some((width, height, eye height))`, blocks) or
48/// vanilla's again. The mod sends who has which (its own packet); the local
49/// player moves and collides with it.
50pub fn set_dimensions(uuid: &str, size: Option<(f32, f32, f32)>) {
51    let api = global_api();
52    if api.is_null() {
53        return;
54    }
55    let (w, h, e) = size.unwrap_or((-1.0, 0.0, 0.0));
56    unsafe { ((*api).client_set_dimensions)((*api).ctx, YogStr::from_str(uuid), w, h, e) }
57}
58
59/// Asks the body handlers about every entity of `entity_type` (`on`), or stops.
60pub fn track_type(entity_type: &str, on: bool) {
61    let api = global_api();
62    if api.is_null() {
63        return;
64    }
65    unsafe { ((*api).client_body_track_type)((*api).ctx, YogStr::from_str(entity_type), on) }
66}