1use std::collections::HashMap;
18
19use serde::{Deserialize, Serialize};
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
30#[serde(default)]
31pub struct YogDimensionTypeDef {
32 pub min_y: i32,
33 pub height: i32,
34 pub logical_height: i32,
35 pub has_sky_light: bool,
36 pub sky_light_updates: bool,
37 pub ambient_light: f32,
38 pub coordinate_scale: f32,
39 pub ultrawarm: bool,
40 pub beds_explode: bool,
41 pub respawn_anchors_explode: bool,
42 pub piglin_safe: bool,
43 pub natural: bool,
44 pub has_ceiling: bool,
45 pub effects: String,
46 pub has_sky: bool,
47 pub has_clouds: bool,
48 pub cloud_height: f64,
49 pub has_fog: bool,
50 pub fog_color: Option<i32>,
51 pub sky_color: Option<i32>,
52 pub water_color: Option<i32>,
53 pub water_fog_color: Option<i32>,
54}
55
56impl Default for YogDimensionTypeDef {
57 fn default() -> Self {
58 Self {
59 min_y: -64,
60 height: 384,
61 logical_height: 384,
62 has_sky_light: true,
63 sky_light_updates: true,
64 ambient_light: 0.0,
65 coordinate_scale: 1.0,
66 ultrawarm: false,
67 beds_explode: false,
68 respawn_anchors_explode: false,
69 piglin_safe: false,
70 natural: true,
71 has_ceiling: false,
72 effects: "overworld".to_owned(),
73 has_sky: true,
74 has_clouds: true,
75 cloud_height: 192.0,
76 has_fog: false,
77 fog_color: None,
78 sky_color: None,
79 water_color: None,
80 water_fog_color: None,
81 }
82 }
83}
84
85impl YogDimensionTypeDef {
86 pub fn min_y(mut self, v: i32) -> Self {
90 self.min_y = v;
91 self
92 }
93 pub fn height(mut self, v: i32) -> Self {
94 self.height = v;
95 self.logical_height = v;
96 self
97 }
98 pub fn logical_height(mut self, v: i32) -> Self {
99 self.logical_height = v;
100 self
101 }
102 pub fn has_sky_light(mut self, v: bool) -> Self {
103 self.has_sky_light = v;
104 self
105 }
106 pub fn sky_light_updates(mut self, v: bool) -> Self {
107 self.sky_light_updates = v;
108 self
109 }
110 pub fn ambient_light(mut self, v: f32) -> Self {
111 self.ambient_light = v;
112 self
113 }
114 pub fn coordinate_scale(mut self, v: f32) -> Self {
115 self.coordinate_scale = v;
116 self
117 }
118 pub fn ultrawarm(mut self, v: bool) -> Self {
119 self.ultrawarm = v;
120 self
121 }
122 pub fn beds_explode(mut self, v: bool) -> Self {
123 self.beds_explode = v;
124 self
125 }
126 pub fn respawn_anchors_explode(mut self, v: bool) -> Self {
127 self.respawn_anchors_explode = v;
128 self
129 }
130 pub fn piglin_safe(mut self, v: bool) -> Self {
131 self.piglin_safe = v;
132 self
133 }
134 pub fn natural(mut self, v: bool) -> Self {
135 self.natural = v;
136 self
137 }
138 pub fn has_ceiling(mut self, v: bool) -> Self {
139 self.has_ceiling = v;
140 self
141 }
142 pub fn effects(mut self, v: impl Into<String>) -> Self {
143 self.effects = v.into();
144 self
145 }
146 pub fn has_sky(mut self, v: bool) -> Self {
147 self.has_sky = v;
148 self
149 }
150 pub fn has_clouds(mut self, v: bool) -> Self {
151 self.has_clouds = v;
152 self
153 }
154 pub fn cloud_height(mut self, v: f64) -> Self {
155 self.cloud_height = v;
156 self
157 }
158 pub fn has_fog(mut self, v: bool) -> Self {
159 self.has_fog = v;
160 self
161 }
162 pub fn fog_color(mut self, v: i32) -> Self {
163 self.fog_color = Some(v);
164 self
165 }
166 pub fn sky_color(mut self, v: i32) -> Self {
167 self.sky_color = Some(v);
168 self
169 }
170 pub fn water_color(mut self, v: i32) -> Self {
171 self.water_color = Some(v);
172 self
173 }
174 pub fn water_fog_color(mut self, v: i32) -> Self {
175 self.water_fog_color = Some(v);
176 self
177 }
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
190#[serde(default)]
191pub struct YogDimensionDef {
192 pub id: String,
193 pub dimension_type: YogDimensionTypeDef,
194 pub extra: HashMap<String, String>,
197}
198
199impl Default for YogDimensionDef {
200 fn default() -> Self {
201 Self {
202 id: String::new(),
203 dimension_type: YogDimensionTypeDef::default(),
204 extra: HashMap::new(),
205 }
206 }
207}
208
209impl YogDimensionDef {
210 pub fn new(id: impl Into<String>) -> Self {
212 Self {
213 id: id.into(),
214 ..Self::default()
215 }
216 }
217
218 pub fn dimension_type(mut self, dimension_type: YogDimensionTypeDef) -> Self {
220 self.dimension_type = dimension_type;
221 self
222 }
223
224 pub fn with_extra(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
226 self.extra.insert(key.into(), value.into());
227 self
228 }
229
230 pub fn to_json(&self) -> String {
232 serde_json::to_string(self).expect("YogDimensionDef serializes infallibly")
233 }
234}
235
236pub struct ChunkWriter(*const yog_abi::YogChunkWriterApi);
242
243impl ChunkWriter {
244 #[doc(hidden)]
245 pub unsafe fn from_raw(raw: *const yog_abi::YogChunkWriterApi) -> Self {
246 Self(raw)
247 }
248
249 #[inline]
250 fn api(&self) -> &yog_abi::YogChunkWriterApi {
251 unsafe { &*self.0 }
252 }
253
254 pub fn chunk_x(&self) -> i32 {
256 self.api().chunk_x
257 }
258
259 pub fn chunk_z(&self) -> i32 {
261 self.api().chunk_z
262 }
263
264 pub fn min_y(&self) -> i32 {
266 self.api().min_y
267 }
268
269 pub fn height(&self) -> i32 {
271 self.api().height
272 }
273
274 pub fn set_block(&self, x: i32, y: i32, z: i32, block_id: &str) -> bool {
278 let api = self.api();
279 unsafe { (api.set_block)(api.ctx, x, y, z, yog_abi::YogStr::from_str(block_id)) }
280 }
281}
282
283#[cfg(test)]
284mod tests {
285 use super::*;
286
287 #[test]
288 fn dimension_def_to_json_roundtrips_through_serde() {
289 let def = YogDimensionDef::new("mymod:my_dim")
290 .dimension_type(
291 YogDimensionTypeDef::default()
292 .ultrawarm(true)
293 .effects("nether"),
294 )
295 .with_extra("note", "test");
296
297 let json = def.to_json();
298 let back: YogDimensionDef = serde_json::from_str(&json).expect("valid json");
299 assert_eq!(back.id, "mymod:my_dim");
300 assert!(back.dimension_type.ultrawarm);
301 assert_eq!(back.dimension_type.effects, "nether");
302 assert_eq!(back.extra.get("note").map(String::as_str), Some("test"));
303 }
304}