1use crate::serde_helpers::impl_bitfield_serde;
4
5#[cfg(feature = "chumsky")]
6use chumsky::{Parser, prelude::just, text::whitespace};
7
8#[cfg(feature = "chumsky")]
9use crate::utils::f32_parser;
10
11#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
13pub struct Vector {
14 pub x: f32,
16 pub y: f32,
18 pub z: f32,
20}
21
22#[cfg(feature = "chumsky")]
30#[must_use]
31pub fn vector_parser<'src>()
32-> impl Parser<'src, &'src str, Vector, chumsky::extra::Err<chumsky::error::Rich<'src, char>>> {
33 just('<')
34 .then(whitespace().or_not())
35 .ignore_then(f32_parser())
36 .then_ignore(whitespace().or_not())
37 .then_ignore(just(','))
38 .then_ignore(whitespace().or_not())
39 .then(f32_parser())
40 .then_ignore(whitespace().or_not())
41 .then_ignore(just(','))
42 .then_ignore(whitespace().or_not())
43 .then(f32_parser())
44 .then_ignore(whitespace().or_not())
45 .then_ignore(just('>'))
46 .map(|((x, y), z)| Vector { x, y, z })
47}
48
49impl From<crate::map::RegionCoordinates> for Vector {
50 fn from(value: crate::map::RegionCoordinates) -> Self {
51 Self {
52 x: value.x(),
53 y: value.y(),
54 z: value.z(),
55 }
56 }
57}
58
59#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
61pub struct Rotation {
62 pub x: f32,
64 pub y: f32,
66 pub z: f32,
68 pub s: f32,
70}
71
72#[cfg(feature = "chumsky")]
80#[must_use]
81pub fn rotation_parser<'src>()
82-> impl Parser<'src, &'src str, Rotation, chumsky::extra::Err<chumsky::error::Rich<'src, char>>> {
83 just('<')
84 .then(whitespace().or_not())
85 .ignore_then(f32_parser())
86 .then_ignore(whitespace().or_not())
87 .then_ignore(just(','))
88 .then_ignore(whitespace().or_not())
89 .then(f32_parser())
90 .then_ignore(whitespace().or_not())
91 .then_ignore(just(','))
92 .then_ignore(whitespace().or_not())
93 .then(f32_parser())
94 .then_ignore(whitespace().or_not())
95 .then_ignore(just(','))
96 .then_ignore(whitespace().or_not())
97 .then(f32_parser())
98 .then_ignore(whitespace().or_not())
99 .then_ignore(just('>'))
100 .map(|(((x, y), z), s)| Rotation { x, y, z, s })
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
107pub struct ScriptPermissions(pub i32);
108
109impl ScriptPermissions {
110 pub const DEBIT: i32 = 1 << 1;
112 pub const TAKE_CONTROLS: i32 = 1 << 2;
114 pub const TRIGGER_ANIMATION: i32 = 1 << 4;
116 pub const ATTACH: i32 = 1 << 5;
118 pub const CHANGE_LINKS: i32 = 1 << 7;
120 pub const TRACK_CAMERA: i32 = 1 << 10;
122 pub const CONTROL_CAMERA: i32 = 1 << 11;
124 pub const TELEPORT: i32 = 1 << 12;
126 pub const EXPERIENCE: i32 = 1 << 13;
128 pub const SILENT_ESTATE_MANAGEMENT: i32 = 1 << 14;
130 pub const OVERRIDE_ANIMATIONS: i32 = 1 << 15;
132 pub const RETURN_OBJECTS: i32 = 1 << 16;
134
135 #[must_use]
137 pub const fn contains(self, mask: i32) -> bool {
138 self.0 & mask == mask
139 }
140}
141
142impl_bitfield_serde!(
143 ScriptPermissions,
144 i32,
145 "DEBIT" => ScriptPermissions::DEBIT,
146 "TAKE_CONTROLS" => ScriptPermissions::TAKE_CONTROLS,
147 "TRIGGER_ANIMATION" => ScriptPermissions::TRIGGER_ANIMATION,
148 "ATTACH" => ScriptPermissions::ATTACH,
149 "CHANGE_LINKS" => ScriptPermissions::CHANGE_LINKS,
150 "TRACK_CAMERA" => ScriptPermissions::TRACK_CAMERA,
151 "CONTROL_CAMERA" => ScriptPermissions::CONTROL_CAMERA,
152 "TELEPORT" => ScriptPermissions::TELEPORT,
153 "EXPERIENCE" => ScriptPermissions::EXPERIENCE,
154 "SILENT_ESTATE_MANAGEMENT" => ScriptPermissions::SILENT_ESTATE_MANAGEMENT,
155 "OVERRIDE_ANIMATIONS" => ScriptPermissions::OVERRIDE_ANIMATIONS,
156 "RETURN_OBJECTS" => ScriptPermissions::RETURN_OBJECTS,
157);