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
//     dis-rust - A rust implementation of the DIS simulation protocol.
//     Copyright (C) 2022 Thomas Mann
// 
//     This software is dual-licensed. It is available under the conditions of
//     the GNU Affero General Public License (see the LICENSE file included) 
//     or under a commercial license (email contact@coffeebreakdevs.com for
//     details).

use bytes::{BytesMut, BufMut};
use num_derive::FromPrimitive; 

#[derive(Copy, Clone, Debug,)]
/// General Appearance Record as defined in IEEE 1278.1 standard. Used to communicate the general appearance of an entity during the simulation.
pub struct GeneralAppearanceRecord {
    pub entity_paint_scheme_field: EntityPaintScheme,
    pub entity_mobility_kill_field: EntityMobilityKill,
    pub entity_fire_power_field: EntityFirePower,
    pub entity_damage_field: EntityDamage,
    pub entity_smoke_field: EntitySmoke,
    pub entity_trailing_effect_field: EntityTrailingEffect,
    pub entity_hatch_state_field: EntityHatchState,
    pub entity_lights_field: EntityLights,
    pub entity_flaming_effect_field: EntityFlamingEffect,
}

impl GeneralAppearanceRecord {
    /// Provides a function to create a new GeneralAppearanceRecord.
    pub fn new(entity_paint_scheme_field: EntityPaintScheme,
        entity_mobility_kill_field: EntityMobilityKill,
        entity_fire_power_field: EntityFirePower,
        entity_damage_field: EntityDamage,
        entity_smoke_field: EntitySmoke,
        entity_trailing_effect_field: EntityTrailingEffect,
        entity_hatch_state_field: EntityHatchState,
        entity_lights_field: EntityLights,
        entity_flaming_effect_field: EntityFlamingEffect,) -> Self {
        GeneralAppearanceRecord {
            entity_paint_scheme_field,
            entity_mobility_kill_field,
            entity_fire_power_field,
            entity_damage_field,
            entity_smoke_field,
            entity_trailing_effect_field,
            entity_hatch_state_field,
            entity_lights_field,
            entity_flaming_effect_field,
        }
    }

    /// Provides a function to default a new GeneralAppearanceRecord.
    /// The default record shows an entity in uniform with no damage or effects.
    pub fn default() -> Self {
        GeneralAppearanceRecord {
            entity_paint_scheme_field: EntityPaintScheme::UniformColor,
            entity_mobility_kill_field: EntityMobilityKill::NoMobilityKill,
            entity_fire_power_field: EntityFirePower::NoFirePowerKill,
            entity_damage_field: EntityDamage::NoDamage,
            entity_smoke_field: EntitySmoke::NotSmoking,
            entity_trailing_effect_field: EntityTrailingEffect::None,
            entity_hatch_state_field: EntityHatchState::NotApplicable,
            entity_lights_field: EntityLights::None,
            entity_flaming_effect_field: EntityFlamingEffect::None,
        }
    }

    /// Fills a BytesMut struct with a GeneralAppearanceRecord serialised into binary. This buffer is then ready to be sent via
    /// UDP to the simluation network.
    pub fn serialize(&self, buf: &mut BytesMut) {
        let entity_paint_scheme : u16 = self.entity_paint_scheme_field as u16;
        let entity_paint_scheme = entity_paint_scheme << 15;
        let entity_mobility_kill : u16 = self.entity_mobility_kill_field as u16;
        let entity_mobility_kill = entity_mobility_kill << 14;
        let entity_fire_power : u16 = self.entity_fire_power_field as u16;
        let entity_fire_power = entity_fire_power << 13;
        let entity_damage : u16 = self.entity_damage_field as u16;
        let entity_damage = entity_damage << 11;
        let entity_smoke : u16 = self.entity_smoke_field as u16;
        let entity_smoke = entity_smoke << 9;
        let entity_trailing_effect : u16 = self.entity_trailing_effect_field as u16;
        let entity_trailing_effect = entity_trailing_effect << 7;
        let entity_hatch_state : u16 = self.entity_hatch_state_field as u16;
        let entity_hatch_state = entity_hatch_state << 4;
        let entity_lights : u16 = self.entity_lights_field as u16;
        let entity_lights = entity_lights << 1;
        let entity_flaming_effect : u16 = self.entity_flaming_effect_field as u16;

        let general_appearance : u16 = 0u16 | entity_paint_scheme | entity_mobility_kill
            | entity_fire_power | entity_damage | entity_smoke | entity_trailing_effect
            | entity_hatch_state | entity_lights | entity_flaming_effect;
        buf.put_u16(general_appearance);
    }
}

#[derive(Debug, FromPrimitive, PartialEq, Clone, Copy)]
/// Enum to represent an entity's paint scheme.
pub enum EntityPaintScheme {
    UniformColor = 0,
    Camouflage = 1,
}

#[derive(Debug, FromPrimitive, PartialEq, Clone, Copy)]
/// Enum to represent an entity's mobility kill status.
pub enum EntityMobilityKill {
    NoMobilityKill = 0,
    MobilityKill = 1,
}

#[derive(Debug, FromPrimitive, PartialEq, Clone, Copy)]
/// Enum to represent an entity's firepower kill status.
pub enum EntityFirePower {
    NoFirePowerKill = 0,
    FirePowerKill = 1,
}

#[derive(Debug, FromPrimitive, PartialEq, Clone, Copy)]
/// Enum to represent an entity's damage.
pub enum EntityDamage {
    NoDamage = 0,
    SlightDamage = 1,
    ModerateDamage = 2,
    Destoryed = 3,
}

#[derive(Debug, FromPrimitive, PartialEq, Clone, Copy)]
/// Enum to represent an entity's smoke effect.
pub enum EntitySmoke {
    NotSmoking = 0,
    SmokePlumeRising = 1,
    EngineSmoke = 2,
    EngineSmokeAndSmokePlumeRising = 3,
}

#[derive(Debug, FromPrimitive, PartialEq, Clone, Copy)]
/// Enum to represent an entity's trailing effect.
pub enum EntityTrailingEffect {
    None = 0,
    Small = 1,
    Medium = 2,
    Large = 3,
}

#[derive(Debug, FromPrimitive, PartialEq, Clone, Copy)]
pub enum EntityHatchState {
    NotApplicable = 0,
    PrimaryHatchClosed = 1,
    PrimaryHatchPopped = 2,
    PrimaryHatchPoppedAndPersonVisibleUnderHatch = 3,
    PrimaryHatchOpen = 4,
    PrimaryHatchOpenAndPersonVisible = 5,
}

#[derive(Debug, FromPrimitive, PartialEq, Clone, Copy)]
pub enum EntityLights {
    None = 0,
    RunningLightsOn = 1,
    NavigationLightsOn = 2,
    FormationLightsOn = 3,
}

#[derive(Debug, FromPrimitive, PartialEq, Clone, Copy)]
pub enum EntityFlamingEffect {
    None = 0,
    FlamesPresent = 1,
}