exolvl 0.12.0

A library for reading and writing Exoracer level files.
Documentation
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
use super::{color::Color, vec2::Vec2};
use crate::{Read, Write, error::Error};
use ordered_float::OrderedFloat;

#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum ObjectProperty {
    Color(Color),
    Resolution(i32),
    FillMode(i32),
    SecondaryColor(Color),
    Thickness(OrderedFloat<f32>),
    TotalAngle(i32),
    Corners(i32),
    Blending(i32),
    GridOffset(Vec2),
    CornerRadius(OrderedFloat<f32>),
    Width(OrderedFloat<f32>),
    Height(OrderedFloat<f32>),
    BorderColor(Color),
    BorderThickness(OrderedFloat<f32>),
    PhysicsType(i32),
    Friction(OrderedFloat<f32>),
    TerrainCorners(Vec<Vec<Vec2>>),
    Direction(i32),
    Impulse(i32),
    Killer(bool),
    RoundReflexAngles(bool),
    RoundCollider(bool),
    Radius(OrderedFloat<f32>),
    Size(OrderedFloat<f32>),
    ReverseDirection(bool),
    CollisionDetector(bool),
    Pattern(i32),
    PatternTiling(Vec2),
    PatternOffset(Vec2),
    Bounce(bool),
    RestoreVelocity(bool),
    Sprite(String),
    Trigger(bool),
    Health(OrderedFloat<f32>),
    DamageFromJump(bool),
    DamageFromDash(bool),
    ReverseDirOnDamage(bool),
    Floating(bool),
    LinkedObjects(Vec<i32>),
    FlipX(bool),
    FlipY(bool),
    Text(String),
    FontSize(OrderedFloat<f32>),
    EditorColor(Color),
    Color2(Color),
    Color3(Color),
    Color4(Color),
    ParticleTexture(String),
    Duration(OrderedFloat<f32>),
    Delay(OrderedFloat<f32>),
    Loop(bool),
    AutoPlay(bool),
    LifetimeMin(OrderedFloat<f32>),
    LifetimeMax(OrderedFloat<f32>),
    SimulationSpace(i32),
    Rate(OrderedFloat<f32>),
    Burst(i32),
    EmitterShape(i32),
    EmitterWidth(OrderedFloat<f32>),
    EmitterHeight(OrderedFloat<f32>),
    EmitterTotalAngle(OrderedFloat<f32>),
    SizeMin(OrderedFloat<f32>),
    SizeMax(OrderedFloat<f32>),
    SizeOverLifetime(bool),
    StartSizeMultiplier(OrderedFloat<f32>),
    EndSizeMultiplier(OrderedFloat<f32>),
    SpeedMin(OrderedFloat<f32>),
    SpeedMax(OrderedFloat<f32>),
    SpeeLimit(OrderedFloat<f32>),
    SpeedDampen(OrderedFloat<f32>),
    RotationMin(OrderedFloat<f32>),
    RotationMax(OrderedFloat<f32>),
    Rotationspeed(OrderedFloat<f32>),
    ColorOverLifetime(bool),
    StartColorMultiplier(Color),
    EndColorMultiplier(Color),
    GravityMultiplier(OrderedFloat<f32>),
    AnchorPos(Vec2),
    MoonInnerRadius(OrderedFloat<f32>),
    MoonOffset(OrderedFloat<f32>),
}

impl Read for ObjectProperty {
    fn read(input: &mut impl std::io::Read) -> Result<Self, Error> {
        let property_type = Read::read(input)?;

        Ok(match property_type {
            0 => Self::Color(Read::read(input)?),
            1 => Self::Resolution(Read::read(input)?),
            2 => Self::FillMode(Read::read(input)?),
            3 => Self::SecondaryColor(Read::read(input)?),
            4 => Self::Thickness(Read::read(input)?),
            5 => Self::TotalAngle(Read::read(input)?),
            6 => Self::Corners(Read::read(input)?),
            7 => Self::Blending(Read::read(input)?),
            8 => Self::GridOffset(Read::read(input)?),
            9 => Self::CornerRadius(Read::read(input)?),
            10 => Self::Width(Read::read(input)?),
            11 => Self::Height(Read::read(input)?),
            12 => Self::BorderColor(Read::read(input)?),
            13 => Self::BorderThickness(Read::read(input)?),
            14 => Self::PhysicsType(Read::read(input)?),
            15 => Self::Friction(Read::read(input)?),
            16 => Self::TerrainCorners(Read::read(input)?),
            17 => Self::Direction(Read::read(input)?),
            18 => Self::Impulse(Read::read(input)?),
            19 => Self::Killer(Read::read(input)?),
            20 => Self::RoundReflexAngles(Read::read(input)?),
            21 => Self::RoundCollider(Read::read(input)?),
            22 => Self::Radius(Read::read(input)?),
            23 => Self::Size(Read::read(input)?),
            24 => Self::ReverseDirection(Read::read(input)?),
            25 => Self::CollisionDetector(Read::read(input)?),
            26 => Self::Pattern(Read::read(input)?),
            27 => Self::PatternTiling(Read::read(input)?),
            28 => Self::PatternOffset(Read::read(input)?),
            32 => Self::Bounce(Read::read(input)?),
            34 => Self::RestoreVelocity(Read::read(input)?),
            35 => Self::Sprite(Read::read(input)?),
            36 => Self::Trigger(Read::read(input)?),
            37 => Self::Health(Read::read(input)?),
            38 => Self::DamageFromJump(Read::read(input)?),
            39 => Self::DamageFromDash(Read::read(input)?),
            40 => Self::ReverseDirOnDamage(Read::read(input)?),
            41 => Self::Floating(Read::read(input)?),
            42 => Self::LinkedObjects(Read::read(input)?),
            43 => Self::FlipX(Read::read(input)?),
            44 => Self::FlipY(Read::read(input)?),
            45 => Self::Text(Read::read(input)?),
            46 => Self::FontSize(Read::read(input)?),
            47 => Self::EditorColor(Read::read(input)?),
            48 => Self::Color2(Read::read(input)?),
            49 => Self::Color3(Read::read(input)?),
            50 => Self::Color4(Read::read(input)?),
            51 => Self::ParticleTexture(Read::read(input)?),
            52 => Self::Duration(Read::read(input)?),
            53 => Self::Delay(Read::read(input)?),
            54 => Self::Loop(Read::read(input)?),
            55 => Self::AutoPlay(Read::read(input)?),
            56 => Self::LifetimeMin(Read::read(input)?),
            57 => Self::LifetimeMax(Read::read(input)?),
            58 => Self::SimulationSpace(Read::read(input)?),
            59 => Self::Rate(Read::read(input)?),
            60 => Self::Burst(Read::read(input)?),
            61 => Self::EmitterShape(Read::read(input)?),
            62 => Self::EmitterWidth(Read::read(input)?),
            63 => Self::EmitterHeight(Read::read(input)?),
            64 => Self::EmitterTotalAngle(Read::read(input)?),
            65 => Self::SizeMin(Read::read(input)?),
            66 => Self::SizeMax(Read::read(input)?),
            67 => Self::SizeOverLifetime(Read::read(input)?),
            68 => Self::StartSizeMultiplier(Read::read(input)?),
            69 => Self::EndSizeMultiplier(Read::read(input)?),
            71 => Self::SpeedMin(Read::read(input)?),
            72 => Self::SpeedMax(Read::read(input)?),
            73 => Self::SpeeLimit(Read::read(input)?),
            74 => Self::SpeedDampen(Read::read(input)?),
            75 => Self::RotationMin(Read::read(input)?),
            76 => Self::RotationMax(Read::read(input)?),
            77 => Self::Rotationspeed(Read::read(input)?),
            78 => Self::ColorOverLifetime(Read::read(input)?),
            79 => Self::StartColorMultiplier(Read::read(input)?),
            80 => Self::EndColorMultiplier(Read::read(input)?),
            81 => Self::GravityMultiplier(Read::read(input)?),
            82 => Self::AnchorPos(Read::read(input)?),
            83 => Self::MoonInnerRadius(Read::read(input)?),
            84 => Self::MoonOffset(Read::read(input)?),
            n => return Err(Error::InvalidObjectPropertyType(n)),
        })
    }
}

impl Write for ObjectProperty {
    #[allow(clippy::too_many_lines)]
    fn write(&self, output: &mut impl std::io::Write) -> Result<(), Error> {
        match self {
            Self::Color(value) => {
                0.write(output)?;
                value.write(output)
            }
            Self::Resolution(value) => {
                1.write(output)?;
                value.write(output)
            }
            Self::FillMode(value) => {
                2.write(output)?;
                value.write(output)
            }
            Self::SecondaryColor(value) => {
                3.write(output)?;
                value.write(output)
            }
            Self::Thickness(value) => {
                4.write(output)?;
                value.write(output)
            }
            Self::TotalAngle(value) => {
                5.write(output)?;
                value.write(output)
            }
            Self::Corners(value) => {
                6.write(output)?;
                value.write(output)
            }
            Self::Blending(value) => {
                7.write(output)?;
                value.write(output)
            }
            Self::GridOffset(value) => {
                8.write(output)?;
                value.write(output)
            }
            Self::CornerRadius(value) => {
                9.write(output)?;
                value.write(output)
            }
            Self::Width(value) => {
                10.write(output)?;
                value.write(output)
            }
            Self::Height(value) => {
                11.write(output)?;
                value.write(output)
            }
            Self::BorderColor(value) => {
                12.write(output)?;
                value.write(output)
            }
            Self::BorderThickness(value) => {
                13.write(output)?;
                value.write(output)
            }
            Self::PhysicsType(value) => {
                14.write(output)?;
                value.write(output)
            }
            Self::Friction(value) => {
                15.write(output)?;
                value.write(output)
            }
            Self::TerrainCorners(value) => {
                16.write(output)?;
                value.write(output)
            }
            Self::Direction(value) => {
                17.write(output)?;
                value.write(output)
            }
            Self::Impulse(value) => {
                18.write(output)?;
                value.write(output)
            }
            Self::Killer(value) => {
                19.write(output)?;
                value.write(output)
            }
            Self::RoundReflexAngles(value) => {
                20.write(output)?;
                value.write(output)
            }
            Self::RoundCollider(value) => {
                21.write(output)?;
                value.write(output)
            }
            Self::Radius(value) => {
                22.write(output)?;
                value.write(output)
            }
            Self::Size(value) => {
                23.write(output)?;
                value.write(output)
            }
            Self::ReverseDirection(value) => {
                24.write(output)?;
                value.write(output)
            }
            Self::CollisionDetector(value) => {
                25.write(output)?;
                value.write(output)
            }
            Self::Pattern(value) => {
                26.write(output)?;
                value.write(output)
            }
            Self::PatternTiling(value) => {
                27.write(output)?;
                value.write(output)
            }
            Self::PatternOffset(value) => {
                28.write(output)?;
                value.write(output)
            }
            Self::Bounce(value) => {
                32.write(output)?;
                value.write(output)
            }
            Self::RestoreVelocity(value) => {
                34.write(output)?;
                value.write(output)
            }
            Self::Sprite(value) => {
                35.write(output)?;
                value.write(output)
            }
            Self::Trigger(value) => {
                36.write(output)?;
                value.write(output)
            }
            Self::Health(value) => {
                37.write(output)?;
                value.write(output)
            }
            Self::DamageFromJump(value) => {
                38.write(output)?;
                value.write(output)
            }
            Self::DamageFromDash(value) => {
                39.write(output)?;
                value.write(output)
            }
            Self::ReverseDirOnDamage(value) => {
                40.write(output)?;
                value.write(output)
            }
            Self::Floating(value) => {
                41.write(output)?;
                value.write(output)
            }
            Self::LinkedObjects(value) => {
                42.write(output)?;
                value.write(output)
            }
            Self::FlipX(value) => {
                43.write(output)?;
                value.write(output)
            }
            Self::FlipY(value) => {
                44.write(output)?;
                value.write(output)
            }
            Self::Text(value) => {
                45.write(output)?;
                value.write(output)
            }
            Self::FontSize(value) => {
                46.write(output)?;
                value.write(output)
            }
            Self::EditorColor(value) => {
                47.write(output)?;
                value.write(output)
            }
            Self::Color2(value) => {
                48.write(output)?;
                value.write(output)
            }
            Self::Color3(value) => {
                49.write(output)?;
                value.write(output)
            }
            Self::Color4(value) => {
                50.write(output)?;
                value.write(output)
            }
            Self::ParticleTexture(value) => {
                51.write(output)?;
                value.write(output)
            }
            Self::Duration(value) => {
                52.write(output)?;
                value.write(output)
            }
            Self::Delay(value) => {
                53.write(output)?;
                value.write(output)
            }
            Self::Loop(value) => {
                54.write(output)?;
                value.write(output)
            }
            Self::AutoPlay(value) => {
                55.write(output)?;
                value.write(output)
            }
            Self::LifetimeMin(value) => {
                56.write(output)?;
                value.write(output)
            }
            Self::LifetimeMax(value) => {
                57.write(output)?;
                value.write(output)
            }
            Self::SimulationSpace(value) => {
                58.write(output)?;
                value.write(output)
            }
            Self::Rate(value) => {
                59.write(output)?;
                value.write(output)
            }
            Self::Burst(value) => {
                60.write(output)?;
                value.write(output)
            }
            Self::EmitterShape(value) => {
                61.write(output)?;
                value.write(output)
            }
            Self::EmitterWidth(value) => {
                62.write(output)?;
                value.write(output)
            }
            Self::EmitterHeight(value) => {
                63.write(output)?;
                value.write(output)
            }
            Self::EmitterTotalAngle(value) => {
                64.write(output)?;
                value.write(output)
            }
            Self::SizeMin(value) => {
                65.write(output)?;
                value.write(output)
            }
            Self::SizeMax(value) => {
                66.write(output)?;
                value.write(output)
            }
            Self::SizeOverLifetime(value) => {
                67.write(output)?;
                value.write(output)
            }
            Self::StartSizeMultiplier(value) => {
                68.write(output)?;
                value.write(output)
            }
            Self::EndSizeMultiplier(value) => {
                69.write(output)?;
                value.write(output)
            }
            Self::SpeedMin(value) => {
                71.write(output)?;
                value.write(output)
            }
            Self::SpeedMax(value) => {
                72.write(output)?;
                value.write(output)
            }
            Self::SpeeLimit(value) => {
                73.write(output)?;
                value.write(output)
            }
            Self::SpeedDampen(value) => {
                74.write(output)?;
                value.write(output)
            }
            Self::RotationMin(value) => {
                75.write(output)?;
                value.write(output)
            }
            Self::RotationMax(value) => {
                76.write(output)?;
                value.write(output)
            }
            Self::Rotationspeed(value) => {
                77.write(output)?;
                value.write(output)
            }
            Self::ColorOverLifetime(value) => {
                78.write(output)?;
                value.write(output)
            }
            Self::StartColorMultiplier(value) => {
                79.write(output)?;
                value.write(output)
            }
            Self::EndColorMultiplier(value) => {
                80.write(output)?;
                value.write(output)
            }
            Self::GravityMultiplier(value) => {
                81.write(output)?;
                value.write(output)
            }
            Self::AnchorPos(value) => {
                82.write(output)?;
                value.write(output)
            }
            Self::MoonInnerRadius(value) => {
                83.write(output)?;
                value.write(output)
            }
            Self::MoonOffset(value) => {
                84.write(output)?;
                value.write(output)
            }
        }
    }
}