1pub(crate) mod op;
14pub mod player;
15pub mod world;
16
17use yog_abi::YogStr;
18pub use yog_abi::ui_flags;
19
20use crate::registry::global_api;
21
22pub fn open_ui_flags(ui_id: &str, flags: u32) {
24 let api = global_api();
25 if api.is_null() {
26 return;
27 }
28 unsafe { ((*api).ui_open_flags)((*api).ctx, YogStr::from_str(ui_id), flags) }
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
33pub struct SoundHandle(pub u32);
34
35pub fn play_sound(sound_id: &str, volume: f32, pitch: f32, looping: bool) -> SoundHandle {
39 let api = global_api();
40 if api.is_null() {
41 return SoundHandle(0);
42 }
43 SoundHandle(unsafe {
44 ((*api).client_play_sound)(
45 (*api).ctx,
46 YogStr::from_str(sound_id),
47 volume,
48 pitch,
49 looping,
50 )
51 })
52}
53
54pub fn stop_sound(handle: SoundHandle) {
56 let api = global_api();
57 if api.is_null() || handle.0 == 0 {
58 return;
59 }
60 unsafe { ((*api).client_stop_sound)((*api).ctx, handle.0) }
61}
62
63pub fn held_item(off_hand: bool) -> Option<String> {
66 let api = global_api();
67 if api.is_null() {
68 return None;
69 }
70 let owned = unsafe { ((*api).client_held_item)((*api).ctx, off_hand) };
71 crate::registry::take_owned(unsafe { (*api).free_str }, owned)
72}
73
74pub fn attribute_value(attribute_id: &str) -> Option<f64> {
78 let api = global_api();
79 if api.is_null() {
80 return None;
81 }
82 let v = unsafe { ((*api).client_attribute_value)((*api).ctx, YogStr::from_str(attribute_id)) };
83 (!v.is_nan()).then_some(v)
84}
85
86pub fn advancement_done(id: &str) -> bool {
88 let api = global_api();
89 !api.is_null() && unsafe { ((*api).client_advancement_done)((*api).ctx, YogStr::from_str(id)) }
90}
91
92pub fn set_block_tint(dimension: &str, pos: yog_core::BlockPos, color: Option<u32>) {
97 let api = global_api();
98 if api.is_null() {
99 return;
100 }
101 let p = yog_abi::YogBlockPos { x: pos.x, y: pos.y, z: pos.z };
102 let c = color.map_or(-1, |c| (c & 0xFF_FFFF) as i64);
103 unsafe { ((*api).client_set_block_tint)((*api).ctx, YogStr::from_str(dimension), p, c) }
104}
105
106pub mod keys {
108 pub const UNBOUND: i32 = -1;
110 pub const A: i32 = 65;
112 pub const B: i32 = 66;
113 pub const C: i32 = 67;
114 pub const D: i32 = 68;
115 pub const E: i32 = 69;
116 pub const F: i32 = 70;
117 pub const G: i32 = 71;
118 pub const H: i32 = 72;
119 pub const I: i32 = 73;
120 pub const J: i32 = 74;
121 pub const K: i32 = 75;
122 pub const L: i32 = 76;
123 pub const M: i32 = 77;
124 pub const N: i32 = 78;
125 pub const O: i32 = 79;
126 pub const P: i32 = 80;
127 pub const Q: i32 = 81;
128 pub const R: i32 = 82;
129 pub const S: i32 = 83;
130 pub const T: i32 = 84;
131 pub const U: i32 = 85;
132 pub const V: i32 = 86;
133 pub const W: i32 = 87;
134 pub const X: i32 = 88;
135 pub const Y: i32 = 89;
136 pub const Z: i32 = 90;
137 pub const HOME: i32 = 268;
138 pub const LEFT_SHIFT: i32 = 340;
139 pub const LEFT_CONTROL: i32 = 341;
140 pub const LEFT_ALT: i32 = 342;
141 pub const RIGHT_SHIFT: i32 = 344;
142 pub const RIGHT_CONTROL: i32 = 345;
143 pub const RIGHT_ALT: i32 = 346;
144}
145
146pub fn key_down(key: i32) -> bool {
148 let api = global_api();
149 if api.is_null() {
150 return false;
151 }
152 unsafe { ((*api).client_key_down)((*api).ctx, key) }
153}
154
155pub fn control_down() -> bool {
158 key_down(keys::LEFT_CONTROL) || key_down(keys::RIGHT_CONTROL)
159}