#[cfg(test)]
#[path = "../tests/tf2/game_mode.rs"]
mod tests;
use crate::interfaces::ValveEngine;
use crate::tf2::game_rules::{GameRules, GameRulesError};
use sdk_raw::tf2::game_mode::{
HALLOWEEN_SCENARIO_DOOMSDAY, HALLOWEEN_SCENARIO_HIGHTOWER, HALLOWEEN_SCENARIO_LAKESIDE,
HALLOWEEN_SCENARIO_MANN_MANOR, HALLOWEEN_SCENARIO_NONE, HALLOWEEN_SCENARIO_VIADUCT,
HOLIDAY_APRIL_FOOLS, HOLIDAY_CHRISTMAS, HOLIDAY_COMMUNITY_UPDATE, HOLIDAY_EOTL,
HOLIDAY_FULL_MOON, HOLIDAY_HALLOWEEN, HOLIDAY_HALLOWEEN_OR_FULL_MOON,
HOLIDAY_HALLOWEEN_OR_FULL_MOON_OR_VALENTINES, HOLIDAY_MEET_THE_PYRO, HOLIDAY_NONE,
HOLIDAY_SOLDIER, HOLIDAY_SUMMER, HOLIDAY_TF_BIRTHDAY, HOLIDAY_VALENTINES, TF_GAMETYPE_ARENA,
TF_GAMETYPE_CP, TF_GAMETYPE_CTF, TF_GAMETYPE_ESCORT, TF_GAMETYPE_MVM, TF_GAMETYPE_PASSTIME,
TF_GAMETYPE_PD, TF_GAMETYPE_RD, TF_GAMETYPE_UNDEFINED, TF_HUDTYPE_ARENA, TF_HUDTYPE_CP,
TF_HUDTYPE_CTF, TF_HUDTYPE_ESCORT, TF_HUDTYPE_TRAINING, TF_HUDTYPE_UNDEFINED,
};
use sdk_raw::tf2::game_rules::is_holiday_active;
use std::ffi::{CStr, c_int};
const GAME_TYPE: &CStr = c"m_nGameType";
const HALLOWEEN_SCENARIO: &CStr = c"m_halloweenScenario";
const HUD_TYPE: &CStr = c"m_nHudType";
const MAP_HOLIDAY: &CStr = c"m_nMapHolidayType";
const USES_SPELLS: &CStr = c"m_bIsUsingSpells";
const ESCORT_PUSH: &CStr = c"m_nForceEscortPushLogic";
const PLAYERS_IN_HELL: &CStr = c"m_bHelltowerPlayersInHell";
const UPGRADES: &CStr = c"m_nForceUpgrades";
#[doc(alias("ETFGameType"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum GameType {
#[doc(alias("TF_GAMETYPE_UNDEFINED"))]
Undefined = TF_GAMETYPE_UNDEFINED,
#[doc(alias("TF_GAMETYPE_CTF"))]
CaptureTheFlag = TF_GAMETYPE_CTF,
#[doc(alias("TF_GAMETYPE_CP"))]
ControlPoints = TF_GAMETYPE_CP,
#[doc(alias("TF_GAMETYPE_ESCORT"))]
Payload = TF_GAMETYPE_ESCORT,
#[doc(alias("TF_GAMETYPE_ARENA", "IsInArenaMode"))]
Arena = TF_GAMETYPE_ARENA,
#[doc(alias("TF_GAMETYPE_MVM"))]
MannVsMachine = TF_GAMETYPE_MVM,
#[doc(alias("TF_GAMETYPE_RD"))]
RobotDestruction = TF_GAMETYPE_RD,
#[doc(alias("TF_GAMETYPE_PASSTIME", "IsPasstimeMode"))]
PassTime = TF_GAMETYPE_PASSTIME,
#[doc(alias("TF_GAMETYPE_PD"))]
PlayerDestruction = TF_GAMETYPE_PD,
}
impl GameType {
pub const ALL: [Self; 9] = [
Self::Undefined,
Self::CaptureTheFlag,
Self::ControlPoints,
Self::Payload,
Self::Arena,
Self::MannVsMachine,
Self::RobotDestruction,
Self::PassTime,
Self::PlayerDestruction,
];
pub const fn from_raw(raw: c_int) -> Option<Self> {
match raw {
TF_GAMETYPE_UNDEFINED => Some(Self::Undefined),
TF_GAMETYPE_CTF => Some(Self::CaptureTheFlag),
TF_GAMETYPE_CP => Some(Self::ControlPoints),
TF_GAMETYPE_ESCORT => Some(Self::Payload),
TF_GAMETYPE_ARENA => Some(Self::Arena),
TF_GAMETYPE_MVM => Some(Self::MannVsMachine),
TF_GAMETYPE_RD => Some(Self::RobotDestruction),
TF_GAMETYPE_PASSTIME => Some(Self::PassTime),
TF_GAMETYPE_PD => Some(Self::PlayerDestruction),
_ => None,
}
}
pub const fn to_raw(self) -> c_int {
self as c_int
}
}
#[doc(alias("HalloweenScenarioType"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum HalloweenScenario {
#[doc(alias("HALLOWEEN_SCENARIO_MANN_MANOR"))]
MannManor = HALLOWEEN_SCENARIO_MANN_MANOR,
#[doc(alias("HALLOWEEN_SCENARIO_VIADUCT"))]
Eyeaduct = HALLOWEEN_SCENARIO_VIADUCT,
#[doc(alias("HALLOWEEN_SCENARIO_LAKESIDE"))]
GhostFort = HALLOWEEN_SCENARIO_LAKESIDE,
#[doc(alias("HALLOWEEN_SCENARIO_HIGHTOWER"))]
Helltower = HALLOWEEN_SCENARIO_HIGHTOWER,
#[doc(alias("HALLOWEEN_SCENARIO_DOOMSDAY"))]
CarnivalOfCarnage = HALLOWEEN_SCENARIO_DOOMSDAY,
}
impl HalloweenScenario {
pub const ALL: [Self; 5] = [
Self::MannManor,
Self::Eyeaduct,
Self::GhostFort,
Self::Helltower,
Self::CarnivalOfCarnage,
];
pub const fn from_raw(raw: c_int) -> Option<Self> {
match raw {
HALLOWEEN_SCENARIO_MANN_MANOR => Some(Self::MannManor),
HALLOWEEN_SCENARIO_VIADUCT => Some(Self::Eyeaduct),
HALLOWEEN_SCENARIO_LAKESIDE => Some(Self::GhostFort),
HALLOWEEN_SCENARIO_HIGHTOWER => Some(Self::Helltower),
HALLOWEEN_SCENARIO_DOOMSDAY => Some(Self::CarnivalOfCarnage),
_ => None,
}
}
pub const fn to_raw(self) -> c_int {
self as c_int
}
}
#[doc(alias("EHoliday"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum Holiday {
#[doc(alias("kHoliday_TFBirthday"))]
Birthday = HOLIDAY_TF_BIRTHDAY,
#[doc(alias("kHoliday_Halloween"))]
Halloween = HOLIDAY_HALLOWEEN,
#[doc(alias("kHoliday_Christmas"))]
Christmas = HOLIDAY_CHRISTMAS,
#[doc(alias("kHoliday_CommunityUpdate"))]
CommunityUpdate = HOLIDAY_COMMUNITY_UPDATE,
#[doc(alias("kHoliday_EOTL"))]
EndOfTheLine = HOLIDAY_EOTL,
#[doc(alias("kHoliday_Valentines"))]
Valentines = HOLIDAY_VALENTINES,
#[doc(alias("kHoliday_MeetThePyro"))]
MeetThePyro = HOLIDAY_MEET_THE_PYRO,
#[doc(alias("kHoliday_FullMoon"))]
FullMoon = HOLIDAY_FULL_MOON,
#[doc(alias("kHoliday_HalloweenOrFullMoon"))]
HalloweenOrFullMoon = HOLIDAY_HALLOWEEN_OR_FULL_MOON,
#[doc(alias("kHoliday_HalloweenOrFullMoonOrValentines"))]
HalloweenOrFullMoonOrValentines = HOLIDAY_HALLOWEEN_OR_FULL_MOON_OR_VALENTINES,
#[doc(alias("kHoliday_AprilFools"))]
AprilFools = HOLIDAY_APRIL_FOOLS,
#[doc(alias("kHoliday_Soldier"))]
Soldier = HOLIDAY_SOLDIER,
#[doc(alias("kHoliday_Summer"))]
Summer = HOLIDAY_SUMMER,
}
impl Holiday {
pub const ALL: [Self; 13] = [
Self::Birthday,
Self::Halloween,
Self::Christmas,
Self::CommunityUpdate,
Self::EndOfTheLine,
Self::Valentines,
Self::MeetThePyro,
Self::FullMoon,
Self::HalloweenOrFullMoon,
Self::HalloweenOrFullMoonOrValentines,
Self::AprilFools,
Self::Soldier,
Self::Summer,
];
pub const fn from_raw(raw: c_int) -> Option<Self> {
match raw {
HOLIDAY_TF_BIRTHDAY => Some(Self::Birthday),
HOLIDAY_HALLOWEEN => Some(Self::Halloween),
HOLIDAY_CHRISTMAS => Some(Self::Christmas),
HOLIDAY_COMMUNITY_UPDATE => Some(Self::CommunityUpdate),
HOLIDAY_EOTL => Some(Self::EndOfTheLine),
HOLIDAY_VALENTINES => Some(Self::Valentines),
HOLIDAY_MEET_THE_PYRO => Some(Self::MeetThePyro),
HOLIDAY_FULL_MOON => Some(Self::FullMoon),
HOLIDAY_HALLOWEEN_OR_FULL_MOON => Some(Self::HalloweenOrFullMoon),
HOLIDAY_HALLOWEEN_OR_FULL_MOON_OR_VALENTINES => {
Some(Self::HalloweenOrFullMoonOrValentines)
}
HOLIDAY_APRIL_FOOLS => Some(Self::AprilFools),
HOLIDAY_SOLDIER => Some(Self::Soldier),
HOLIDAY_SUMMER => Some(Self::Summer),
_ => None,
}
}
pub const fn to_raw(self) -> c_int {
self as c_int
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum HudType {
#[doc(alias("TF_HUDTYPE_UNDEFINED"))]
Undefined = TF_HUDTYPE_UNDEFINED,
#[doc(alias("TF_HUDTYPE_CTF"))]
CaptureTheFlag = TF_HUDTYPE_CTF,
#[doc(alias("TF_HUDTYPE_CP"))]
ControlPoints = TF_HUDTYPE_CP,
#[doc(alias("TF_HUDTYPE_ESCORT"))]
Payload = TF_HUDTYPE_ESCORT,
#[doc(alias("TF_HUDTYPE_ARENA"))]
Arena = TF_HUDTYPE_ARENA,
#[doc(alias("TF_HUDTYPE_TRAINING"))]
Training = TF_HUDTYPE_TRAINING,
}
impl HudType {
pub const ALL: [Self; 6] = [
Self::Undefined,
Self::CaptureTheFlag,
Self::ControlPoints,
Self::Payload,
Self::Arena,
Self::Training,
];
pub const fn from_raw(raw: c_int) -> Option<Self> {
match raw {
TF_HUDTYPE_UNDEFINED => Some(Self::Undefined),
TF_HUDTYPE_CTF => Some(Self::CaptureTheFlag),
TF_HUDTYPE_CP => Some(Self::ControlPoints),
TF_HUDTYPE_ESCORT => Some(Self::Payload),
TF_HUDTYPE_ARENA => Some(Self::Arena),
TF_HUDTYPE_TRAINING => Some(Self::Training),
_ => None,
}
}
pub const fn to_raw(self) -> c_int {
self as c_int
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum RuleOverride {
#[default]
Default = 0,
Off = 1,
On = 2,
}
impl RuleOverride {
pub const ALL: [Self; 3] = [Self::Default, Self::Off, Self::On];
pub const fn from_raw(raw: c_int) -> Option<Self> {
match raw {
0 => Some(Self::Default),
1 => Some(Self::Off),
2 => Some(Self::On),
_ => None,
}
}
pub const fn to_raw(self) -> c_int {
self as c_int
}
}
impl GameRules<'_> {
#[doc(alias("m_nForceEscortPushLogic", "GameModeUsesEscortPushLogic"))]
pub fn escort_push_override(self) -> Result<RuleOverride, GameRulesError> {
self.rule_override(ESCORT_PUSH)
}
fn rule_override(self, variable: &'static CStr) -> Result<RuleOverride, GameRulesError> {
let raw = self.read::<c_int>(variable)?;
RuleOverride::from_raw(raw).ok_or(GameRulesError::UnknownValue {
variable,
value: raw,
})
}
#[doc(alias("ForceEscortPushLogic"))]
pub fn set_escort_push_override(
self,
engine: ValveEngine<'_>,
value: RuleOverride,
) -> Result<(), GameRulesError> {
unsafe { self.set(engine, ESCORT_PUSH, value.to_raw()) }
}
#[doc(alias("SetPlayersInHell"))]
pub fn set_players_in_hell(
self,
engine: ValveEngine<'_>,
in_hell: bool,
) -> Result<(), GameRulesError> {
unsafe { self.set(engine, PLAYERS_IN_HELL, in_hell) }
}
#[doc(alias("m_nForceUpgrades", "GameModeUsesUpgrades"))]
pub fn upgrades_override(self) -> Result<RuleOverride, GameRulesError> {
self.rule_override(UPGRADES)
}
#[doc(alias("ForceEnableUpgrades"))]
pub fn set_upgrades_override(
self,
engine: ValveEngine<'_>,
value: RuleOverride,
) -> Result<(), GameRulesError> {
unsafe { self.set(engine, UPGRADES, value.to_raw()) }
}
}
impl GameRules<'_> {
#[doc(alias("m_bHelltowerPlayersInHell", "ArePlayersInHell"))]
pub fn are_players_in_hell(self) -> Result<bool, GameRulesError> {
self.read(PLAYERS_IN_HELL)
}
#[doc(alias("m_nGameType", "GetGameType"))]
pub fn game_type(self) -> Result<GameType, GameRulesError> {
let raw = self.read::<c_int>(GAME_TYPE)?;
GameType::from_raw(raw).ok_or(GameRulesError::UnknownValue {
variable: GAME_TYPE,
value: raw,
})
}
#[doc(alias("m_halloweenScenario", "GetHalloweenScenario"))]
pub fn halloween_scenario(self) -> Result<Option<HalloweenScenario>, GameRulesError> {
let raw = self.read::<c_int>(HALLOWEEN_SCENARIO)?;
match HalloweenScenario::from_raw(raw) {
None if raw != HALLOWEEN_SCENARIO_NONE => Err(GameRulesError::UnknownValue {
variable: HALLOWEEN_SCENARIO,
value: raw,
}),
scenario => Ok(scenario),
}
}
#[doc(alias("IsHolidayActive", "TF_IsHolidayActive"))]
pub fn is_holiday_active(self, holiday: Holiday) -> bool {
unsafe { is_holiday_active(self.as_non_null(), holiday.to_raw()) }
}
#[doc(alias("m_bCompetitiveMode", "IsCompetitiveMode"))]
pub fn is_competitive(self) -> Result<bool, GameRulesError> {
self.read(c"m_bCompetitiveMode")
}
#[doc(alias("m_bPlayingHybrid_CTF_CP", "IsPlayingHybrid_CTF_CP"))]
pub fn is_hybrid_ctf_cp(self) -> Result<bool, GameRulesError> {
self.read(c"m_bPlayingHybrid_CTF_CP")
}
#[doc(alias("m_bPlayingKoth", "IsInKothMode"))]
pub fn is_king_of_the_hill(self) -> Result<bool, GameRulesError> {
self.read(c"m_bPlayingKoth")
}
#[doc(alias("m_bPlayingMannVsMachine", "IsMannVsMachineMode"))]
pub fn is_mann_vs_machine(self) -> Result<bool, GameRulesError> {
self.read(c"m_bPlayingMannVsMachine")
}
#[doc(alias("m_bPowerupMode", "IsPowerupMode"))]
pub fn is_mannpower(self) -> Result<bool, GameRulesError> {
self.read(c"m_bPowerupMode")
}
#[doc(alias("m_bPlayingMedieval", "IsInMedievalMode"))]
pub fn is_medieval(self) -> Result<bool, GameRulesError> {
self.read(c"m_bPlayingMedieval")
}
#[doc(alias("m_bPlayingRobotDestructionMode", "IsPlayingRobotDestructionMode"))]
pub fn is_robot_destruction(self) -> Result<bool, GameRulesError> {
self.read(c"m_bPlayingRobotDestructionMode")
}
#[doc(alias("m_bPlayingSpecialDeliveryMode", "IsPlayingSpecialDeliveryMode"))]
pub fn is_special_delivery(self) -> Result<bool, GameRulesError> {
self.read(c"m_bPlayingSpecialDeliveryMode")
}
#[doc(alias("m_bTruceActive", "IsTruceActive"))]
pub fn is_truce_active(self) -> Result<bool, GameRulesError> {
self.read(c"m_bTruceActive")
}
#[doc(alias("m_nHudType", "GetHUDType"))]
pub fn hud_type(self) -> Result<HudType, GameRulesError> {
let raw = self.read::<c_int>(HUD_TYPE)?;
HudType::from_raw(raw).ok_or(GameRulesError::UnknownValue {
variable: HUD_TYPE,
value: raw,
})
}
#[doc(alias("m_nMapHolidayType", "IsHolidayMap"))]
pub fn map_holiday(self) -> Result<Option<Holiday>, GameRulesError> {
let raw = self.read::<c_int>(MAP_HOLIDAY)?;
match Holiday::from_raw(raw) {
None if raw != HOLIDAY_NONE => Err(GameRulesError::UnknownValue {
variable: MAP_HOLIDAY,
value: raw,
}),
holiday => Ok(holiday),
}
}
#[doc(alias("m_bIsUsingSpells"))]
pub fn uses_spells(self) -> Result<bool, GameRulesError> {
self.read(USES_SPELLS)
}
#[doc(alias("SetUsingSpells", "HalloweenSetUsingSpells"))]
pub fn set_uses_spells(
self,
engine: ValveEngine<'_>,
using: bool,
) -> Result<(), GameRulesError> {
unsafe { self.set(engine, USES_SPELLS, using) }
}
}