Skip to main content

yog_event/block/
properties.rs

1//! A block's properties one by one, on top of its whole state.
2
3use yog_core::{BlockPos, join_state, split_state};
4use yog_ids::sep::{PROPERTY_IS, PROPERTY_SEP};
5
6use super::{set_state, state};
7use crate::Arg;
8
9/// Property `name` of the block at `pos` (`"energized"` → `"true"`).
10pub fn property(dim: impl Arg<String>, pos: impl Arg<BlockPos>, name: &str) -> Option<String> {
11    let state = state(dim, pos)?;
12    split_state(&state)
13        .1
14        .into_iter()
15        .find(|(k, _)| *k == name)
16        .map(|(_, v)| v.to_owned())
17}
18
19/// Sets some properties of the block at `pos` (`"energized=true,powered=false"`),
20/// keeping the rest; `false` if there's no block or the state doesn't take.
21pub fn set_properties(dim: impl Arg<String>, pos: impl Arg<BlockPos>, properties: &str) -> bool {
22    let (dim, pos) = (dim.arg(), pos.arg());
23    let Some(state) = state(dim.as_str(), pos) else {
24        return false;
25    };
26    let (id, mut props) = split_state(&state);
27    for pair in properties.split(PROPERTY_SEP).filter(|p| !p.is_empty()) {
28        let Some((k, v)) = pair.split_once(PROPERTY_IS) else {
29            return false;
30        };
31        match props.iter_mut().find(|(n, _)| *n == k) {
32            Some(p) => p.1 = v,
33            None => props.push((k, v)),
34        }
35    }
36    set_state(dim, pos, join_state(id, &props))
37}