1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! The note block device and its associated types
//!
//! [OC2 Docs](https://fnuecke.github.io/oc2/manual/en_us/device/note_block.html)
use std::convert::Infallible;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use uuid::Uuid;
use crate::client::{DeviceBase, HlapiClient, HlapiClientError};
/// A note block's instrument
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum Instrument {
/// A harp (piano)
Harp,
/// A bass drum
#[serde(rename = "basedrum")]
BassDrum,
/// A snare drum
Snare,
/// A hi-hat
Hat,
/// A bass
Bass,
/// A flute
Flute,
/// A bell (Glockenspiel)
Bell,
/// A guitar
Guitar,
/// A chime
Chime,
/// A xylophone
Xylophone,
/// An iron xylophone
IronXylophone,
/// A cowbell
CowBell,
/// A didgeridoo
Didgeridoo,
/// A synthesizer
Bit,
/// A banjo
Banjo,
/// An electric piano
Pling,
/// A zombie
Zombie,
/// A skeleton
Skeleton,
/// A creeper
Creeper,
/// An ender dragon
Dragon,
/// A wither skeleton
WitherSkeleton,
/// A piglin
Piglin,
/// A custom head
CustomHead,
}
/// The possible errors for device functions
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum NoteBlockError {
#[error("HLAPI client error: {0}")]
/// HLAPI client error
HlapiClientError(#[from] HlapiClientError),
#[error("Note out of range")]
/// Note out of range
NoteOutOfRange,
}
#[derive(Debug, Clone)]
/// A note block device
pub struct NoteBlock {
client: HlapiClient,
uuid: Uuid,
}
impl NoteBlock {
/// Gets the note block's current instrument
pub fn get_instrument(&self) -> Result<Instrument, NoteBlockError> {
Ok(self.call("getInstrument", &[], &[])?.0)
}
/// Sets the note block's current instrument. This is temporary, and will get reset if a note
/// block detects a change to the block above or below it.
pub fn set_instrument(&self, instrument: Instrument) -> Result<(), NoteBlockError> {
self.call::<()>("setInstrument", &[&instrument as _], &[])?;
Ok(())
}
/// Gets the note block's current note
///
/// Note numbers are as shown on the [MC Wiki](https://minecraft.wiki/w/Note_Block)
pub fn get_note(&self) -> Result<u8, NoteBlockError> {
Ok(self.call("getNote", &[], &[])?.0)
}
/// Sets the note block's current note
///
/// Note numbers are as shown on the [MC Wiki](https://minecraft.wiki/w/Note_Block)
pub fn set_note(&self, note: u8) -> Result<(), NoteBlockError> {
if note > 24 {
return Err(NoteBlockError::NoteOutOfRange);
}
self.call::<()>("setNote", &[¬e as _], &[])?;
Ok(())
}
}
impl DeviceBase for NoteBlock {
const TYPE: &'static str = "note_block";
type Event = Infallible;
fn new(client: HlapiClient, uuid: Uuid) -> Result<Self, HlapiClientError> {
Ok(Self { client, uuid })
}
fn uuid_base(&self) -> Uuid {
self.uuid
}
fn client(&self) -> &HlapiClient {
&self.client
}
}