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
use std::error::Error;

use crate::{
    ai_interface::{
        callback::game_mod::{
            combat::{GameModCombat, GameModCombatAll},
            construction_decay::{GameModConstructionDecay, GameModConstructionDecayAll},
            info::{GameModInfo, GameModInfoAll},
            mip::{GameModMipLevel, GameModMipLevelAll},
            reclaim::{GameModReclaim, GameModReclaimAll},
            transport::{GameModTransport, GameModTransportAll},
        },
        AIInterface,
    },
    get_callback,
};

pub mod combat;
pub mod construction_decay;
pub mod info;
pub mod mip;
pub mod reclaim;
pub mod transport;

#[derive(Debug, Copy, Clone)]
pub struct GameMod {
    pub ai_id: i32,
}

#[derive(Debug, Clone)]
pub struct GameModAll {
    info: GameModInfoAll,
    // allow_team_colors: bool,
    construction_decay: GameModConstructionDecayAll,
    reclaim: GameModReclaimAll,
    capture_energy_cost_factor: f32,
    transport: GameModTransportAll,
    combat: GameModCombatAll,
    mip_level: GameModMipLevelAll,
    require_sonar_underwater: bool,
}

const MAX_TEAM: usize = 32;

impl AIInterface {
    pub fn game_mod(&self) -> GameMod {
        GameMod { ai_id: self.ai_id }
    }
}

impl GameMod {
    pub fn info(&self) -> GameModInfo {
        GameModInfo { ai_id: self.ai_id }
    }

    // TODO: Was removed by BAR
    // pub fn allow_team_colors(&self) -> Result<bool, Box<dyn Error>> {
    //     let get_allow_team_colors = get_callback!(self.ai_id, Mod_getAllowTeamColors)?;
    //
    //     Ok(unsafe { get_allow_team_colors(self.ai_id) })
    // }

    pub fn construction_decay(&self) -> GameModConstructionDecay {
        GameModConstructionDecay { ai_id: self.ai_id }
    }

    pub fn reclaim(&self) -> GameModReclaim {
        GameModReclaim { ai_id: self.ai_id }
    }

    pub fn capture_energy_cost_factor(&self) -> Result<f32, Box<dyn Error>> {
        let get_capture_energy_cost_factor =
            get_callback!(self.ai_id, Mod_getCaptureEnergyCostFactor)?;

        Ok(unsafe { get_capture_energy_cost_factor(self.ai_id) })
    }

    pub fn transport(&self) -> GameModTransport {
        GameModTransport { ai_id: self.ai_id }
    }

    pub fn combat(&self) -> GameModCombat {
        GameModCombat { ai_id: self.ai_id }
    }

    pub fn mip_level(&self) -> GameModMipLevel {
        GameModMipLevel { ai_id: self.ai_id }
    }

    pub fn require_sonar_underwater(&self) -> Result<bool, Box<dyn Error>> {
        let get_require_sonar_underwater =
            get_callback!(self.ai_id, Mod_getRequireSonarUnderWater)?;

        Ok(unsafe { get_require_sonar_underwater(self.ai_id) })
    }

    pub fn all(&self) -> Result<GameModAll, Box<dyn Error>> {
        Ok(GameModAll {
            info: self.info().all()?,
            // allow_team_colors: self.allow_team_colors()?,
            construction_decay: self.construction_decay().all()?,
            reclaim: self.reclaim().all()?,
            capture_energy_cost_factor: self.capture_energy_cost_factor()?,
            transport: self.transport().all()?,
            combat: self.combat().all()?,
            mip_level: self.mip_level().all()?,
            require_sonar_underwater: self.require_sonar_underwater()?,
        })
    }
}