#[cfg(test)]
#[path = "../../tests/tf2/objectives/control_points.rs"]
mod tests;
use super::{Objective, ObjectiveError};
use crate::Server;
use crate::entities::Entity;
use crate::inputs::InputValue;
use crate::tf2::scoreboard::ScoringTeam;
use sdk_raw::players::TEAM_UNASSIGNED;
use std::ffi::{CStr, CString, c_int};
const NEITHER_WINS_BY_CAPTURE: c_int = 1;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CaptureWins {
Either,
Neither,
Except(ScoringTeam),
}
impl CaptureWins {
pub const fn from_raw(raw: c_int) -> Option<Self> {
match raw {
TEAM_UNASSIGNED => Some(Self::Either),
NEITHER_WINS_BY_CAPTURE => Some(Self::Neither),
_ => match ScoringTeam::from_raw(raw) {
Some(team) => Some(Self::Except(team)),
None => None,
},
}
}
fn to_key_value(self) -> CString {
CString::new(self.to_raw().to_string()).expect("integers format without NUL bytes")
}
pub const fn to_raw(self) -> c_int {
match self {
Self::Either => TEAM_UNASSIGNED,
Self::Neither => NEITHER_WINS_BY_CAPTURE,
Self::Except(team) => team.to_raw(),
}
}
}
#[doc(alias("team_control_point", "CTeamControlPoint"))]
#[derive(Debug, Clone, Copy)]
pub struct ControlPoint<'s>(Objective<'s>);
impl<'s> ControlPoint<'s> {
pub fn new(server: Server<'s>, entity: Entity<'s>) -> Result<Self, ObjectiveError> {
Objective::new(server, entity, c"CTeamControlPoint", "team_control_point").map(Self)
}
#[doc(alias("SetOwner"))]
pub fn capture(self, owner: ScoringTeam, capper: Entity<'_>) -> Result<(), ObjectiveError> {
self.0
.input_from(c"SetOwner", InputValue::Int(owner.to_raw()), capper, capper)
}
#[doc(alias("m_iDefaultOwner", "point_default_owner"))]
pub fn default_owner(self) -> Result<Option<ScoringTeam>, ObjectiveError> {
Ok(ScoringTeam::from_raw(
self.0.int_field(c"CTeamControlPoint", c"m_iDefaultOwner")?,
))
}
pub fn entity(self) -> Entity<'s> {
self.0.entity()
}
#[doc(alias("m_iCPGroup", "point_group"))]
pub fn group(self) -> Result<c_int, ObjectiveError> {
self.0.int_field(c"CTeamControlPoint", c"m_iCPGroup")
}
#[doc(alias("HideModel"))]
pub fn hide_model(self) -> Result<(), ObjectiveError> {
self.0.input(c"HideModel", InputValue::Void)
}
#[doc(alias("m_iPointIndex", "point_index", "GetPointIndex"))]
pub fn index(self) -> Result<c_int, ObjectiveError> {
self.0.int_field(c"CTeamControlPoint", c"m_iPointIndex")
}
#[doc(alias("m_bLocked", "point_start_locked"))]
pub fn is_locked(self) -> Result<bool, ObjectiveError> {
self.0.bool_field(c"CTeamControlPoint", c"m_bLocked")
}
#[doc(alias("m_iTeamNum", "GetOwner"))]
pub fn owner(self) -> Result<Option<ScoringTeam>, ObjectiveError> {
Ok(ScoringTeam::from_raw(
self.0.int_field(c"CBaseEntity", c"m_iTeamNum")?,
))
}
#[doc(alias("m_iszPrintName", "point_printname"))]
pub fn print_name(self) -> Result<CString, ObjectiveError> {
self.0.string_key(c"CTeamControlPoint", c"point_printname")
}
#[doc(alias("SetLocked"))]
pub fn set_locked(self, locked: bool) -> Result<(), ObjectiveError> {
self.0
.input(c"SetLocked", InputValue::Int(c_int::from(locked)))
}
#[doc(alias("SetOwner"))]
pub fn set_owner(self, owner: Option<ScoringTeam>) -> Result<(), ObjectiveError> {
self.0
.input(c"SetOwner", InputValue::Int(team_number(owner)))
}
#[doc(alias("SetUnlockTime"))]
pub fn set_unlock_time(self, seconds: c_int) -> Result<(), ObjectiveError> {
self.0.input(c"SetUnlockTime", InputValue::Int(seconds))
}
#[doc(alias("ShowModel"))]
pub fn show_model(self) -> Result<(), ObjectiveError> {
self.0.input(c"ShowModel", InputValue::Void)
}
}
#[doc(alias("team_control_point_master", "CTeamControlPointMaster"))]
#[derive(Debug, Clone, Copy)]
pub struct ControlPointMaster<'s>(Objective<'s>);
impl<'s> ControlPointMaster<'s> {
pub fn new(server: Server<'s>, entity: Entity<'s>) -> Result<Self, ObjectiveError> {
Objective::new(
server,
entity,
c"CTeamControlPointMaster",
"team_control_point_master",
)
.map(Self)
}
pub fn find(server: Server<'s>) -> Result<Option<Self>, ObjectiveError> {
super::find_by_class(server, c"team_control_point_master", Self::new)
}
#[doc(alias("m_iszCapLayoutInHUD", "caplayout"))]
pub fn cap_layout(self) -> Result<CString, ObjectiveError> {
self.0.string_key(c"CTeamControlPointMaster", c"caplayout")
}
#[doc(alias("m_iInvalidCapWinner", "cpm_restrict_team_cap_win"))]
pub fn capture_wins(self) -> Result<CaptureWins, ObjectiveError> {
let raw = self
.0
.int_field(c"CTeamControlPointMaster", c"m_iInvalidCapWinner")?;
CaptureWins::from_raw(raw).ok_or(ObjectiveError::UnknownValue {
name: c"m_iInvalidCapWinner",
value: raw,
})
}
#[doc(alias("Disable"))]
pub fn disable(self) -> Result<(), ObjectiveError> {
self.0.input(c"Disable", InputValue::Void)
}
#[doc(alias("Enable"))]
pub fn enable(self) -> Result<(), ObjectiveError> {
self.0.input(c"Enable", InputValue::Void)
}
pub fn entity(self) -> Entity<'s> {
self.0.entity()
}
#[doc(alias("m_bDisabled", "StartDisabled"))]
pub fn is_disabled(self) -> Result<bool, ObjectiveError> {
self.0
.bool_field(c"CTeamControlPointMaster", c"m_bDisabled")
}
#[doc(alias("SetCapLayout"))]
pub fn set_cap_layout(self, layout: &CStr) -> Result<(), ObjectiveError> {
self.0.input(c"SetCapLayout", InputValue::String(layout))
}
#[doc(alias("SetCapLayoutCustomPositionX", "SetCapLayoutCustomPositionY"))]
pub fn set_cap_layout_position(self, x: f32, y: f32) -> Result<(), ObjectiveError> {
self.0
.input(c"SetCapLayoutCustomPositionX", InputValue::Float(x))?;
self.0
.input(c"SetCapLayoutCustomPositionY", InputValue::Float(y))
}
#[doc(alias("cpm_restrict_team_cap_win"))]
pub fn set_capture_wins(self, wins: CaptureWins) -> Result<(), ObjectiveError> {
self.0
.set_key_value(c"cpm_restrict_team_cap_win", &wins.to_key_value())
}
#[doc(alias("switch_teams"))]
pub fn set_switches_teams(self, switches: bool) -> Result<(), ObjectiveError> {
self.0
.set_key_value(c"switch_teams", if switches { c"1" } else { c"0" })
}
#[doc(alias("SetWinner"))]
pub fn set_winner(self, winner: Option<ScoringTeam>) -> Result<(), ObjectiveError> {
self.0.check_round_end()?;
self.0
.input(c"SetWinner", InputValue::Int(team_number(winner)))
}
#[doc(alias("SetWinnerAndForceCaps"))]
pub fn set_winner_and_force_caps(
self,
winner: Option<ScoringTeam>,
) -> Result<(), ObjectiveError> {
self.0.check_round_end()?;
self.0.input(
c"SetWinnerAndForceCaps",
InputValue::Int(team_number(winner)),
)
}
#[doc(alias("m_bSwitchTeamsOnWin", "switch_teams"))]
pub fn switches_teams(self) -> Result<bool, ObjectiveError> {
self.0
.bool_field(c"CTeamControlPointMaster", c"m_bSwitchTeamsOnWin")
}
}
#[doc(alias("team_control_point_round", "CTeamControlPointRound"))]
#[derive(Debug, Clone, Copy)]
pub struct ControlPointRound<'s>(Objective<'s>);
impl<'s> ControlPointRound<'s> {
pub fn new(server: Server<'s>, entity: Entity<'s>) -> Result<Self, ObjectiveError> {
Objective::new(
server,
entity,
c"CTeamControlPointRound",
"team_control_point_round",
)
.map(Self)
}
#[doc(alias("m_iInvalidCapWinner", "cpr_restrict_team_cap_win"))]
pub fn capture_wins(self) -> Result<CaptureWins, ObjectiveError> {
let raw = self
.0
.int_field(c"CTeamControlPointRound", c"m_iInvalidCapWinner")?;
CaptureWins::from_raw(raw).ok_or(ObjectiveError::UnknownValue {
name: c"m_iInvalidCapWinner",
value: raw,
})
}
#[doc(alias("Disable"))]
pub fn disable(self) -> Result<(), ObjectiveError> {
self.0.input(c"Disable", InputValue::Void)
}
#[doc(alias("Enable"))]
pub fn enable(self) -> Result<(), ObjectiveError> {
self.0.input(c"Enable", InputValue::Void)
}
pub fn entity(self) -> Entity<'s> {
self.0.entity()
}
#[doc(alias("m_bDisabled", "StartDisabled"))]
pub fn is_disabled(self) -> Result<bool, ObjectiveError> {
self.0.bool_field(c"CTeamControlPointRound", c"m_bDisabled")
}
#[doc(alias("m_iszCPNames", "cpr_cp_names"))]
pub fn point_names(self) -> Result<CString, ObjectiveError> {
self.0
.string_key(c"CTeamControlPointRound", c"cpr_cp_names")
}
#[doc(alias("m_iszPrintName", "cpr_printname"))]
pub fn print_name(self) -> Result<CString, ObjectiveError> {
self.0
.string_key(c"CTeamControlPointRound", c"cpr_printname")
}
#[doc(alias("m_nPriority", "cpr_priority"))]
pub fn priority(self) -> Result<c_int, ObjectiveError> {
self.0.int_field(c"CTeamControlPointRound", c"m_nPriority")
}
#[doc(alias("cpr_restrict_team_cap_win"))]
pub fn set_capture_wins(self, wins: CaptureWins) -> Result<(), ObjectiveError> {
self.0
.set_key_value(c"cpr_restrict_team_cap_win", &wins.to_key_value())
}
}
fn team_number(team: Option<ScoringTeam>) -> c_int {
team.map_or(TEAM_UNASSIGNED, ScoringTeam::to_raw)
}