#[cfg(test)]
#[path = "../tests/entities/dissolve.rs"]
mod tests;
use crate::entities::Entity;
use crate::entities::fields::FieldError;
use crate::entities::movement::EntityFlags;
use crate::entities::spawn::{EntitySpawn, SpawnError};
use crate::inputs::{InputError, InputValue};
use crate::interfaces::ServerTools;
use std::ffi::CString;
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum DissolveError {
#[error("the entity is dissolving already")]
AlreadyDissolving,
#[error(transparent)]
Field(#[from] FieldError),
#[error(transparent)]
Input(#[from] InputError),
#[error("the entity is not a CBaseAnimating, so has no model to dissolve")]
NotAnimating,
#[error(transparent)]
Spawn(#[from] SpawnError),
}
#[doc(alias("dissolvetype"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum DissolveType {
#[doc(alias("ENTITY_DISSOLVE_NORMAL"))]
#[default]
Normal,
#[doc(alias("ENTITY_DISSOLVE_ELECTRICAL"))]
Electrical,
#[doc(alias("ENTITY_DISSOLVE_ELECTRICAL_LIGHT"))]
ElectricalLight,
#[doc(alias("ENTITY_DISSOLVE_CORE"))]
Core,
}
impl DissolveType {
pub const fn to_raw(self) -> u8 {
match self {
Self::Normal => 0,
Self::Electrical => 1,
Self::ElectricalLight => 2,
Self::Core => 3,
}
}
}
impl<'s> ServerTools<'s> {
#[doc(alias("env_entity_dissolver", "Dissolve"))]
pub fn dissolve(
self,
target: Entity<'_>,
kind: DissolveType,
magnitude: u8,
) -> Result<(), DissolveError> {
if !target.is_a(c"CBaseAnimating") {
return Err(DissolveError::NotAnimating);
}
if target.flags()?.contains(EntityFlags::DISSOLVING) {
return Err(DissolveError::AlreadyDissolving);
}
let spawn = EntitySpawn::new(c"env_entity_dissolver")
.key(c"dissolvetype", &cstring(kind.to_raw()))
.key(c"magnitude", &cstring(magnitude))
.activate(false);
let dissolver = unsafe { spawn.spawn(self) }?;
let dissolved = self.accept_input(
dissolver,
c"Dissolve",
InputValue::String(c"!activator"),
target,
target,
);
let _ = self.remove(dissolver);
dissolved.map_err(DissolveError::from)
}
}
fn cstring(value: u8) -> CString {
CString::new(value.to_string()).expect("numbers have no NUL")
}