diff --git a/controller/src/enhancements/player.rs b/controller/src/enhancements/player.rs index 587586bb..27bd55e9 100644 --- a/controller/src/enhancements/player.rs +++ b/controller/src/enhancements/player.rs @@ -1,4 +1,3 @@ -use anyhow::Context; use cs2::{ BoneFlags, CEntityIdentityEx, @@ -9,13 +8,7 @@ use cs2::{ PlayerPawnInfo, PlayerPawnState, }; -use cs2_schema_generated::{ - cs2::client::{ - CCSPlayerController, - C_CSPlayerPawn, - }, - EntityHandle, -}; +use cs2_schema_generated::cs2::client::C_CSPlayerPawn; use imgui::ImColor32; use obfstr::obfstr; @@ -40,7 +33,6 @@ pub struct PlayerESP { toggle: KeyToggle, players: Vec, local_team_id: u8, - local_pos: Option>, } impl PlayerESP { @@ -49,7 +41,6 @@ impl PlayerESP { toggle: KeyToggle::new(), players: Default::default(), local_team_id: 0, - local_pos: Default::default(), } } @@ -180,32 +171,22 @@ impl Enhancement for PlayerESP { self.players.reserve(16); + let local_player_controller = entities.get_local_player_controller()?; + if local_player_controller.is_null()? { + return Ok(()); + } + + let local_player_controller = local_player_controller.reference_schema()?; + self.local_team_id = local_player_controller.m_iPendingTeamNum()?; + let view_target = ctx.states.resolve::(())?; - let target_controller_id = match &view_target.target_controller_entity_id { + let target_entity_id = match &view_target.target_entity_id { Some(value) => *value, None => return Ok(()), }; - let local_player_controller = entities - .get_by_handle::(&EntityHandle::from_index(target_controller_id))? - .context("missing current player controller")? - .entity()? - .reference_schema()?; - - let local_player_pawn_entity_index = - local_player_controller.m_hPlayerPawn()?.get_entity_index(); - self.local_team_id = local_player_controller.m_iPendingTeamNum()?; - for entity_identity in entities.all_identities() { - if entity_identity.handle::<()>()?.get_entity_index() == local_player_pawn_entity_index - { - /* current pawn we control/observe */ - let local_pawn = entity_identity - .entity_ptr::()? - .read_schema()?; - let local_pos = - nalgebra::Vector3::::from_column_slice(&local_pawn.m_vOldOrigin()?); - self.local_pos = Some(local_pos); + if entity_identity.handle::<()>()?.get_entity_index() == target_entity_id { continue; } @@ -246,13 +227,14 @@ impl Enhancement for PlayerESP { let draw = ui.get_window_draw_list(); const UNITS_TO_METERS: f32 = 0.01905; + + let view_world_position = match view.get_camera_world_position() { + Some(view_world_position) => view_world_position, + _ => return Ok(()), + }; + for entry in self.players.iter() { - let distance = if let Some(local_pos) = self.local_pos { - let distance = (entry.position - local_pos).norm() * UNITS_TO_METERS; - distance - } else { - 0.0 - }; + let distance = (entry.position - view_world_position).norm() * UNITS_TO_METERS; let esp_settings = match self.resolve_esp_player_config(&settings, entry) { Some(settings) => settings, None => continue, diff --git a/controller/src/enhancements/spectators_list.rs b/controller/src/enhancements/spectators_list.rs index 6cf5457a..7766ea27 100644 --- a/controller/src/enhancements/spectators_list.rs +++ b/controller/src/enhancements/spectators_list.rs @@ -25,11 +25,11 @@ impl Enhancement for SpectatorsListIndicator { } let view_target = states.resolve::(())?; - let target_controller_id = match &view_target.target_controller_entity_id { + let target_entity_id = match &view_target.target_entity_id { Some(value) => *value, None => return Ok(()), }; - let spectators = states.resolve::(target_controller_id)?; + let spectators = states.resolve::(target_entity_id)?; let group = ui.begin_group(); diff --git a/controller/src/view/world.rs b/controller/src/view/world.rs index a77adfec..12608e9d 100644 --- a/controller/src/view/world.rs +++ b/controller/src/view/world.rs @@ -44,6 +44,31 @@ impl ViewController { self.screen_bounds = bounds; } + pub fn get_camera_world_position(&self) -> Option> { + let view_matrix = self.view_matrix; + let a = view_matrix.m22 * view_matrix.m33 - view_matrix.m32 * view_matrix.m23; + let b = view_matrix.m32 * view_matrix.m13 - view_matrix.m12 * view_matrix.m33; + let c = view_matrix.m12 * view_matrix.m23 - view_matrix.m22 * view_matrix.m13; + let z = view_matrix.m11 * a + view_matrix.m21 * b + view_matrix.m31 * c; + + if z.abs() < 0.0001 { + return None; + } + + let d = view_matrix.m31 * view_matrix.m23 - view_matrix.m21 * view_matrix.m33; + let e = view_matrix.m11 * view_matrix.m33 - view_matrix.m31 * view_matrix.m13; + let f = view_matrix.m21 * view_matrix.m13 - view_matrix.m11 * view_matrix.m23; + let g = view_matrix.m21 * view_matrix.m32 - view_matrix.m31 * view_matrix.m22; + let h = view_matrix.m31 * view_matrix.m12 - view_matrix.m11 * view_matrix.m32; + let k = view_matrix.m11 * view_matrix.m22 - view_matrix.m21 * view_matrix.m12; + + let x = (a * view_matrix.m41 + d * view_matrix.m42 + g * view_matrix.m43) / z; + let y = (b * view_matrix.m41 + e * view_matrix.m42 + h * view_matrix.m43) / z; + let z = (c * view_matrix.m41 + f * view_matrix.m42 + k * view_matrix.m43) / z; + + Some(nalgebra::Vector3::new(-x, -y, -z)) + } + /// Returning an mint::Vector2 as the result should be used via ImGui. pub fn world_to_screen( &self, diff --git a/cs2/src/state/observer.rs b/cs2/src/state/observer.rs index 0e57a3a6..0da335e9 100644 --- a/cs2/src/state/observer.rs +++ b/cs2/src/state/observer.rs @@ -1,10 +1,7 @@ use std::ffi::CStr; use anyhow::Context; -use cs2_schema_generated::cs2::client::{ - C_CSObserverPawn, - C_CSPlayerPawnBase, -}; +use cs2_schema_generated::cs2::client::C_CSObserverPawn; use obfstr::obfstr; use utils_state::{ State, @@ -23,17 +20,14 @@ pub struct SpectatorInfo { } pub struct SpectatorList { - pub target_entity_index: u32, + pub target_entity_id: u32, pub spectators: Vec, } impl State for SpectatorList { type Parameter = u32; - fn create( - states: &StateRegistry, - target_entity_index: Self::Parameter, - ) -> anyhow::Result { + fn create(states: &StateRegistry, target_entity_id: Self::Parameter) -> anyhow::Result { let entities = states.resolve::(())?; let class_name_cache = states.resolve::(())?; @@ -52,8 +46,8 @@ impl State for SpectatorList { .read_schema()?; let observer_target_handle = { - let observer_services_ptr = observer_pawn.m_pObserverServices(); - let observer_services = observer_services_ptr? + let observer_services = observer_pawn + .m_pObserverServices()? .try_reference_schema() .with_context(|| obfstr!("failed to read observer services").to_string())?; @@ -65,32 +59,7 @@ impl State for SpectatorList { } }; - let current_observer_target = entities.get_by_handle(&observer_target_handle)?; - let observer_target_pawn = if let Some(identity) = ¤t_observer_target { - identity - .entity()? - .cast::() - .try_reference_schema() - .with_context(|| obfstr!("failed to observer target pawn").to_string())? - } else { - continue; - }; - - let observer_target_pawn = match observer_target_pawn { - Some(pawn) => pawn, - None => { - continue; - } - }; - - let target_controller_handle = match observer_target_pawn.m_hController() { - Ok(controller) => controller, - Err(_e) => { - continue; - } - }; - - if target_controller_handle.get_entity_index() != target_entity_index { + if observer_target_handle.get_entity_index() != target_entity_id { continue; } @@ -113,7 +82,7 @@ impl State for SpectatorList { Ok(Self { spectators, - target_entity_index, + target_entity_id, }) } @@ -122,10 +91,10 @@ impl State for SpectatorList { } } -/// Get the controller id which we're currently following +/// Get the entity id which we're currently following pub struct LocalCameraControllerTarget { pub is_local_entity: bool, - pub target_controller_entity_id: Option, + pub target_entity_id: Option, } impl State for LocalCameraControllerTarget { @@ -144,7 +113,7 @@ impl State for LocalCameraControllerTarget { None => { /* We're currently not connected */ return Ok(Self { - target_controller_entity_id: None, + target_entity_id: None, is_local_entity: false, }); } @@ -153,13 +122,11 @@ impl State for LocalCameraControllerTarget { if player_controller.m_bPawnIsAlive()? { /* * Our player pawn is alive. - * This most certenly means we're currently following our pawn. + * This most certainly means we're currently following our pawn. */ - let entity_index = player_controller - .m_hOriginalControllerOfCurrentPawn()? - .get_entity_index(); + Ok(Self { - target_controller_entity_id: Some(entity_index), + target_entity_id: Some(player_controller.m_hPawn()?.get_entity_index()), is_local_entity: true, }) } else { @@ -169,7 +136,7 @@ impl State for LocalCameraControllerTarget { None => { /* this is odd... */ return Ok(Self { - target_controller_entity_id: None, + target_entity_id: None, is_local_entity: false, }); } @@ -180,26 +147,17 @@ impl State for LocalCameraControllerTarget { .reference_schema()? .m_hObserverTarget()?; - let local_observed_controller = entities - .get_by_handle(&observer_target_handle)? - .map(|identity| { - identity - .entity()? - .cast::() - .try_reference_schema() - .with_context(|| { - obfstr!("failed to read local observer target pawn").to_string() - }) - }) - .transpose()? - .flatten() - .map(|player_pawn| player_pawn.m_hController()) - .transpose()?; + if !observer_target_handle.is_valid() { + return Ok(Self { + target_entity_id: None, + is_local_entity: false, + }); + } + let target_entity_id = observer_target_handle.get_entity_index(); Ok(Self { is_local_entity: false, - target_controller_entity_id: local_observed_controller - .map(|identity| identity.get_entity_index()), + target_entity_id: Some(target_entity_id), }) } }