use sdk_raw::util::cstr::copy_cstr;
use sdk_raw::vcall;
use std::ffi::{CStr, CString, c_int};
const ERROR_MODEL: &[u8] = b"error.mdl";
interface! {
#[doc(alias("IVModelInfo"))]
pub struct ModelInfo(sys::IVModelInfo) = Engine sdk_raw::interfaces::model_info::VERSION;
}
impl<'s> ModelInfo<'s> {
pub fn is_error_model(self, index: c_int) -> bool {
self.studio_name(index)
.is_some_and(|name| name.to_bytes().eq_ignore_ascii_case(ERROR_MODEL))
}
#[doc(alias("GetModelIndex"))]
pub fn model_index(self, name: &CStr) -> Option<c_int> {
let index = unsafe { vcall!(self.as_ptr() => IVModelInfo_GetModelIndex(name.as_ptr())) };
(index >= 0).then_some(index)
}
#[doc(alias("GetModelName"))]
pub fn model_name(self, index: c_int) -> Option<CString> {
let model = unsafe { vcall!(self.as_ptr() => IVModelInfo_GetModel(index)) };
if model.is_null() {
return None;
}
unsafe { copy_cstr(vcall!(self.as_ptr() => IVModelInfo_GetModelName(model))) }
}
#[doc(alias("GetStudiomodel"))]
pub fn studio_name(self, index: c_int) -> Option<CString> {
let model = unsafe { vcall!(self.as_ptr() => IVModelInfo_GetModel(index)) };
if model.is_null() {
return None;
}
let studio = unsafe { vcall!(self.as_ptr() => IVModelInfo_GetStudiomodel(model)) };
if studio.is_null() {
return None;
}
let name = unsafe { (&raw const (*studio).name).read() };
let bytes = name.map(|byte| byte as u8);
let len = bytes
.iter()
.position(|&byte| byte == 0)
.unwrap_or(bytes.len());
CString::new(&bytes[..len]).ok()
}
#[doc(alias("GetVCollide", "solidCount"))]
pub fn vcollide_solid_count(self, index: c_int) -> Option<c_int> {
let model = unsafe { vcall!(self.as_ptr() => IVModelInfo_GetModel(index)) };
if model.is_null() {
return None;
}
let collide = unsafe { vcall!(self.as_ptr() => IVModelInfo_GetVCollide(model)) };
if collide.is_null() {
return None;
}
Some(c_int::from(unsafe {
sys::vcollide_t::solidCount_raw(collide)
}))
}
}