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
//! Representation of a unit build command.

use crate::data::commands::BuildSquad as BuildSquadData;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// Representation of a unit build/construction command in a Company of Heroes 3 replay. Note that
/// this command logically represents the enqueuing of a build command within the game engine and
/// does not necessarily guarantee that the unit in question was actually built. If a command to
/// cancel construction is issued before the unit is fielded, the unit cost will be refunded.
/// Therefore, to calculate build orders, one must be aware of all unit build times for the
/// corresponding patch version and track unit cancellation as well.
///
/// Commands are collected during tick parsing and then associated with the `Player` instance that
/// sent them. To access, see `Player::commands`.

#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
    feature = "magnus",
    magnus::wrap(class = "VaultCoh::Commands::BuildSquad")
)]
pub struct BuildSquad {
    tick: u32,
    pbgid: u32,
}

impl BuildSquad {
    /// This value is the tick at which the command was found while parsing the replay, which
    /// represents the time in the replay at which it was executed. Because CoH3's engine runs at 8
    /// ticks per second, you can divide this value by 8 to get the number of seconds since the
    /// replay began, which will tell you when this command was executed.
    pub fn tick(&self) -> u32 {
        self.tick
    }
    /// Internal ID that uniquely identifies the unit being built. This value can be matched to
    /// CoH3 attribute files in order to determine the unit being built. Note that, while rare, it
    /// is possible that this value may change between patches for the same unit.
    pub fn pbgid(&self) -> u32 {
        self.pbgid
    }
}

pub fn from_data(data: &BuildSquadData, tick: i32) -> BuildSquad {
    BuildSquad {
        tick: tick as u32,
        pbgid: data.pgbid,
    }
}

// this is safe as BuildSquad does not contain any Ruby types
#[cfg(feature = "magnus")]
unsafe impl magnus::IntoValueFromNative for BuildSquad {}