pub mod events;
pub mod functions;
pub use functions::load_functions;
use crate::{
actors::Actor,
classes::PlayerClass,
dialogs::{self, DialogStyle},
models,
objects::{self, Object, ObjectAttachmentSlotData, PlayerObject},
runtime::queue_api_call,
textdraws::{self, PlayerTextDraw},
types::{
animationdata::AnimationData,
colour::Colour,
staticarray::StaticArray,
vector::{Vector2, Vector3, Vector4},
},
vehicles::Vehicle,
};
use std::{mem::transmute, os::raw::c_void};
use super::{
checkpoints::{self, PlayerCheckPointData, PlayerRaceCheckPointData, RaceCheckpointType},
menus::Menu,
textlabels::{self, PlayerTextLabel},
};
#[derive(Clone, Copy)]
pub struct Player {
handle: *const c_void,
}
impl Player {
pub fn new(handle: *const c_void) -> Self {
Self { handle }
}
pub fn get_handle(&self) -> *const c_void {
self.handle
}
pub fn send_client_message(&self, colour: Colour, message: &str) -> bool {
functions::Player_SendClientMessage(self, colour.rgba(), message)
}
pub fn get_name(&self) -> String {
let mut name = String::new();
functions::Player_GetName(self, &mut name, 24);
name
}
pub fn set_camera_pos(&self, pos: Vector3) -> bool {
functions::Player_SetCameraPos(self, pos.x, pos.y, pos.z)
}
pub fn set_drunk_level(&self, level: i32) -> bool {
functions::Player_SetDrunkLevel(self, level)
}
pub fn set_interior(&self, interiorid: i32) {
self.defer_api_call(Box::new(move |player| {
functions::Player_SetInterior(&player, interiorid);
}));
}
pub fn set_wanted_level(&self, level: i32) -> bool {
functions::Player_SetWantedLevel(self, level)
}
pub fn set_weather(&self, weatherid: i32) -> bool {
functions::Player_SetWeather(self, weatherid)
}
pub fn get_weather(&self) -> i32 {
functions::Player_GetWeather(self)
}
pub fn set_skin(&self, skinid: i32) -> bool {
functions::Player_SetSkin(self, skinid)
}
pub fn set_shop_name(&self, shopname: &str) -> bool {
functions::Player_SetShopName(self, shopname)
}
pub fn give_money(&self, amount: i32) -> bool {
functions::Player_GiveMoney(self, amount)
}
pub fn set_camera_look_at(&self, pos: Vector3, cut: PlayerCameraCutType) -> bool {
functions::Player_SetCameraLookAt(self, pos.x, pos.y, pos.z, cut as i32)
}
pub fn set_camera_behind_player(&self) -> bool {
functions::Player_SetCameraBehind(self)
}
pub fn create_explosion(&self, pos: Vector3, explosion_type: i32, radius: f32) -> bool {
functions::Player_CreateExplosion(self, pos.x, pos.y, pos.z, explosion_type, radius)
}
pub fn play_audio_stream(&self, url: &str, pos: Vector3, distance: f32, use_pos: bool) -> bool {
functions::Player_PlayAudioStream(self, url, pos.x, pos.y, pos.z, distance, use_pos)
}
pub fn stop_audio_stream(&self) -> bool {
functions::Player_StopAudioStream(self)
}
pub fn send_death_message(
&self,
killer: &Player,
killee: &Player,
weapon: PlayerWeapon,
) -> bool {
functions::Player_SendDeathMessage(self, killer, killee, weapon as i32)
}
pub fn toggle_widescreen(&self, enable: bool) -> bool {
functions::Player_ToggleWidescreen(self, enable)
}
pub fn is_widescreen_toggled(&self) -> bool {
functions::Player_IsWidescreenToggled(self)
}
pub fn set_health(&self, health: f32) {
self.defer_api_call(Box::new(move |player| {
functions::Player_SetHealth(&player, health);
}));
}
pub fn get_health(&self) -> f32 {
functions::Player_GetHealth(self)
}
pub fn set_armour(&self, armour: f32) -> bool {
functions::Player_SetArmor(self, armour)
}
pub fn get_armour(&self) -> f32 {
functions::Player_GetArmor(self)
}
pub fn set_team(&self, teamid: i32) -> bool {
functions::Player_SetTeam(self, teamid)
}
pub fn get_team(&self) -> i32 {
functions::Player_GetTeam(self)
}
pub fn set_score(&self, score: i32) -> bool {
functions::Player_SetScore(self, score)
}
pub fn get_score(&self) -> i32 {
functions::Player_GetScore(self)
}
pub fn get_skin(&self) -> i32 {
functions::Player_GetSkin(self)
}
pub fn set_color(&self, colour: Colour) -> bool {
functions::Player_SetColor(self, colour.rgba())
}
pub fn get_color(&self) -> Colour {
Colour::from_rgba(functions::Player_GetColor(self))
}
pub fn get_default_colour(&self) -> Colour {
Colour::from_rgba(functions::Player_GetDefaultColor(self))
}
pub fn get_drunk_level(&self) -> i32 {
functions::Player_GetDrunkLevel(self)
}
pub fn give_weapon(&self, data: WeaponSlotData) -> bool {
functions::Player_GiveWeapon(self, data.id as i32, data.ammo as i32)
}
pub fn remove_weapon(&self, weaponid: u8) -> bool {
functions::Player_RemoveWeapon(self, weaponid as i32)
}
pub fn get_money(&self) -> i32 {
functions::Player_GetMoney(self)
}
pub fn reset_money(&self) -> bool {
functions::Player_ResetMoney(self)
}
pub fn set_name(&self, name: &str) -> PlayerNameStatus {
PlayerNameStatus::from(functions::Player_SetName(self, name))
}
pub fn get_state(&self) -> PlayerState {
PlayerState::from(functions::Player_GetState(self))
}
pub fn get_ping(&self) -> i32 {
functions::Player_GetPing(self)
}
pub fn get_weapon(&self) -> PlayerWeapon {
unsafe { transmute(functions::Player_GetWeapon(self) as u8) }
}
pub fn set_time(&self, hour: i32, minute: i32) -> bool {
functions::Player_SetTime(self, hour, minute)
}
pub fn get_time(&self) -> (i32, i32) {
let mut hour = 0;
let mut minute = 0;
functions::Player_GetTime(self, &mut hour, &mut minute);
(hour, minute)
}
pub fn toggle_clock(&self, enable: bool) -> bool {
functions::Player_ToggleClock(self, enable)
}
pub fn has_clock_enabled(&self) -> bool {
functions::Player_HasClock(self)
}
pub fn force_class_selection(&self) {
self.defer_api_call(Box::new(move |player| {
functions::Player_ForceClassSelection(&player);
}));
}
pub fn get_wanted_level(&self) -> i32 {
functions::Player_GetWantedLevel(self)
}
pub fn set_fighting_style(&self, style: PlayerFightingStyle) -> bool {
functions::Player_SetFightingStyle(self, style as i32)
}
pub fn get_fighting_style(&self) -> PlayerFightingStyle {
unsafe { transmute(functions::Player_GetFightingStyle(self)) }
}
pub fn set_velocity(&self, pos: Vector3) {
self.defer_api_call(Box::new(move |player| {
functions::Player_SetVelocity(&player, pos.x, pos.y, pos.z);
}));
}
pub fn get_velocity(&self) -> Vector3 {
let mut pos = Vector3 {
x: 0.0,
y: 0.0,
z: 0.0,
};
functions::Player_GetVelocity(self, &mut pos.x, &mut pos.y, &mut pos.z);
pos
}
pub fn get_camera_pos(&self) -> Vector3 {
let mut pos = Vector3 {
x: 0.0,
y: 0.0,
z: 0.0,
};
functions::Player_GetCameraPos(self, &mut pos.x, &mut pos.y, &mut pos.z);
pos
}
pub fn get_distance_from_point(&self, pos: Vector3) -> f32 {
functions::Player_GetDistanceFromPoint(self, pos.x, pos.y, pos.z)
}
pub fn get_interior(&self) -> i32 {
functions::Player_GetInterior(self)
}
pub fn set_pos(&self, pos: Vector3) {
self.defer_api_call(Box::new(move |player| {
functions::Player_SetPos(&player, pos.x, pos.y, pos.z);
}));
}
pub fn get_pos(&self) -> Vector3 {
let mut pos = Vector3 {
x: 0.0,
y: 0.0,
z: 0.0,
};
functions::Player_GetPos(self, &mut pos.x, &mut pos.y, &mut pos.z);
pos
}
pub fn get_virtual_world(&self) -> i32 {
functions::Player_GetVirtualWorld(self)
}
pub fn is_npc(&self) -> bool {
functions::Player_IsNPC(self)
}
pub fn is_streamed_in(&self, other: &Player) -> bool {
functions::Player_IsStreamedIn(self, other)
}
pub fn play_sound(&self, sound: usize, pos: Vector3) -> bool {
functions::Player_PlayGameSound(self, sound as i32, pos.x, pos.y, pos.z)
}
pub fn spectate_player(&self, target: &Player, mode: PlayerSpectateMode) {
let target_id = target.get_id();
self.defer_api_call(Box::new(move |player| {
let target = match Player::from_id(target_id) {
Some(target) => target,
None => {
log::error!("target player with id={target_id} not found");
return;
}
};
functions::Player_SpectatePlayer(&player, &target, mode as i32);
}));
}
pub fn spectate_vehicle(&self, vehicle: &Vehicle, mode: PlayerSpectateMode) {
let vehicle_id = vehicle.get_id();
self.defer_api_call(Box::new(move |player| {
let vehicle = match Vehicle::get_from_id(vehicle_id) {
Some(vehicle) => vehicle,
None => {
log::error!("vehicle with id={vehicle_id} not found");
return;
}
};
functions::Player_SpectateVehicle(&player, &vehicle, mode as i32);
}));
}
pub fn set_virtual_world(&self, vw: i32) -> bool {
functions::Player_SetVirtualWorld(self, vw)
}
pub fn set_world_bounds(&self, coords: Vector4) -> bool {
functions::Player_SetWorldBounds(self, coords.x, coords.y, coords.z, coords.w)
}
pub fn clear_world_bounds(&self) -> bool {
functions::Player_ClearWorldBounds(self)
}
pub fn get_world_bounds(&self) -> Vector4 {
let mut pos = Vector4 {
x: 0.0,
y: 0.0,
z: 0.0,
w: 0.0,
};
functions::Player_GetWorldBounds(self, &mut pos.x, &mut pos.y, &mut pos.z, &mut pos.w);
pos
}
pub fn clear_animations(&self, sync_type: PlayerAnimationSyncType) {
self.defer_api_call(Box::new(move |player| {
functions::Player_ClearAnimations(&player, sync_type as i32);
}));
}
pub fn get_last_shot_vectors(&self) -> PlayerBulletData {
let mut data = PlayerBulletData::default();
functions::Player_GetLastShotVectors(
self,
&mut data.origin.x,
&mut data.origin.y,
&mut data.origin.z,
&mut data.hitPos.x,
&mut data.hitPos.y,
&mut data.hitPos.z,
);
data
}
pub fn get_camera_target_player(&self) -> Option<Player> {
functions::Player_GetCameraTargetPlayer(self)
}
pub fn get_camera_target_actor(&self) -> Option<Actor> {
functions::Player_GetCameraTargetActor(self)
}
pub fn get_camera_target_object(&self) -> Option<Object> {
functions::Player_GetCameraTargetObject(self)
}
pub fn get_camera_target_vehicle(&self) -> Option<Vehicle> {
functions::Player_GetCameraTargetVehicle(self)
}
pub fn put_in_vehicle(&self, vehicle: &Vehicle, seat_id: i32) {
let vehicle_id = vehicle.get_id();
self.defer_api_call(Box::new(move |player| {
let vehicle = match Vehicle::get_from_id(vehicle_id) {
Some(vehicle) => vehicle,
None => {
log::error!("vehicle with id={vehicle_id} not found");
return;
}
};
functions::Player_PutInVehicle(&player, &vehicle, seat_id);
}));
}
pub fn remove_building(&self, model: i32, pos: Vector3, radius: f32) -> bool {
functions::Player_RemoveBuilding(self, model, pos.x, pos.y, pos.z, radius)
}
pub fn get_buildings_removed(&self) -> i32 {
functions::Player_GetBuildingsRemoved(self)
}
pub fn remove_from_vehicle(&self, force: bool) {
self.defer_api_call(Box::new(move |player| {
functions::Player_RemoveFromVehicle(&player, force);
}));
}
pub fn remove_map_icon(&self, icon_id: i32) -> bool {
functions::Player_RemoveMapIcon(self, icon_id)
}
pub fn set_map_icon(
&self,
icon_id: i32,
pos: Vector3,
icon_type: i32,
colour: Colour,
style: MapIconStyle,
) -> bool {
functions::Player_SetMapIcon(
self,
icon_id,
pos.x,
pos.y,
pos.z,
icon_type,
colour.rgba(),
style as i32,
)
}
pub fn reset_weapons(&self) -> bool {
functions::Player_ResetWeapons(self)
}
pub fn set_ammo(&self, data: WeaponSlotData) -> bool {
functions::Player_SetAmmo(self, data.id as u8, data.ammo)
}
pub fn set_armed_weapon(&self, weapon: PlayerWeapon) -> bool {
functions::Player_SetArmedWeapon(self, weapon as u8)
}
pub fn set_chat_bubble(
&self,
text: &str,
colour: Colour,
drawdistance: f32,
expiretime: i32,
) -> bool {
functions::Player_SetChatBubble(self, text, colour.rgba(), drawdistance, expiretime)
}
pub fn set_pos_find_z(&self, pos: Vector3) {
self.defer_api_call(Box::new(move |player| {
functions::Player_SetPosFindZ(&player, pos.x, pos.y, pos.z);
}));
}
pub fn set_skill_level(&self, weapon: PlayerWeaponSkill, level: i32) -> bool {
functions::Player_SetSkillLevel(self, weapon as u8, level)
}
pub fn set_special_action(&self, action: PlayerSpecialAction) -> bool {
functions::Player_SetSpecialAction(self, action as u32)
}
pub fn show_name_tag(&self, other: &Player, enable: bool) -> bool {
functions::Player_ShowNameTagForPlayer(self, other, enable)
}
pub fn toggle_controllable(&self, enable: bool) -> bool {
functions::Player_ToggleControllable(self, enable)
}
pub fn toggle_spectating(&self, enable: bool) {
self.defer_api_call(Box::new(move |player| {
functions::Player_ToggleSpectating(&player, enable);
}));
}
pub fn apply_animation(
&self,
animation_data: AnimationData,
sync: PlayerAnimationSyncType,
) -> bool {
functions::Player_ApplyAnimation(
self,
&animation_data.get_animation_library(),
&animation_data.get_name(),
animation_data.delta,
animation_data.looping,
animation_data.lockX,
animation_data.lockY,
animation_data.freeze,
animation_data.time as u32,
sync as i32,
)
}
pub fn edit_attached_object(&self, index: i32) -> bool {
functions::Player_EditAttachedObject(self, index)
}
pub fn enable_camera_target(&self, enable: bool) -> bool {
functions::Player_EnableCameraTarget(self, enable)
}
pub fn enable_stunt_bonus(&self, enable: bool) -> bool {
functions::Player_EnableStuntBonus(self, enable)
}
pub fn get_ammo(&self) -> i32 {
functions::Player_GetPlayerAmmo(self)
}
pub fn get_animation_index(&self) -> i32 {
functions::Player_GetAnimationIndex(self)
}
pub fn get_facing_angle(&self) -> f32 {
functions::Player_GetFacingAngle(self)
}
pub fn get_ip(&self) -> String {
let mut ip = String::new();
functions::Player_GetIp(self, &mut ip, 15);
ip
}
pub fn get_special_action(&self) -> PlayerSpecialAction {
unsafe { transmute(functions::Player_GetSpecialAction(self)) }
}
pub fn get_vehicle_id(&self) -> i32 {
functions::Player_GetVehicleID(self)
}
pub fn get_vehicle_seat(&self) -> i32 {
functions::Player_GetVehicleSeat(self)
}
pub fn get_weapon_data(&self, slot: i32) -> WeaponSlotData {
let mut ammo: i32 = 0;
let mut id: i32 = 0;
functions::Player_GetWeaponData(self, slot, &mut id, &mut ammo);
WeaponSlotData {
ammo: ammo as _,
id: unsafe { transmute(id as u8) },
}
}
pub fn get_weapon_state(&self) -> i32 {
functions::Player_GetWeaponState(self)
}
pub fn interpolate_camera_pos(
&self,
from: Vector3,
to: Vector3,
time: i32,
cut: PlayerCameraCutType,
) -> bool {
functions::Player_InterpolateCameraPos(
self, from.x, from.y, from.z, to.x, to.y, to.z, time, cut as i32,
)
}
pub fn interpolate_camera_look_at(
&self,
from: Vector3,
to: Vector3,
time: i32,
cut: PlayerCameraCutType,
) -> bool {
functions::Player_InterpolateCameraLookAt(
self, from.x, from.y, from.z, to.x, to.y, to.z, time, cut as i32,
)
}
pub fn is_attached_object_slot_used(&self, index: i32) -> bool {
functions::Player_IsPlayerAttachedObjectSlotUsed(self, index)
}
pub fn attach_camera_to_object(&self, object: &Object) -> bool {
functions::Player_AttachCameraToObject(self, object)
}
pub fn attach_camera_to_player_object(&self, object: &PlayerObject) -> bool {
functions::Player_AttachCameraToPlayerObject(self, object)
}
pub fn get_keys(&self) -> PlayerKeyData {
let mut keys = 0;
let mut updown = 0;
let mut leftright = 0;
functions::Player_GetKeys(self, &mut keys, &mut updown, &mut leftright);
PlayerKeyData {
keys: keys as _,
leftRight: leftright as _,
upDown: updown as _,
}
}
pub fn get_surfing_object(&self) -> Option<Object> {
functions::Player_GetSurfingObject(self)
}
pub fn get_surfing_vehicle(&self) -> Option<Vehicle> {
functions::Player_GetSurfingVehicle(self)
}
pub fn get_target_player(&self) -> Option<Player> {
functions::Player_GetCameraTargetPlayer(self)
}
pub fn get_target_actor(&self) -> Option<Actor> {
functions::Player_GetCameraTargetActor(self)
}
pub fn is_in_vehicle(&self, target_vehicle: &Vehicle) -> bool {
functions::Player_IsInVehicle(self, target_vehicle)
}
pub fn is_in_any_vehicle(&self) -> bool {
functions::Player_IsInAnyVehicle(self)
}
pub fn is_in_range_of_point(&self, range: f32, coord: Vector3) -> bool {
functions::Player_IsInRangeOfPoint(self, range, coord.x, coord.y, coord.z)
}
pub fn play_crime_report(&self, suspect: &Player, crime: i32) -> bool {
functions::Player_PlayCrimeReport(self, suspect, crime)
}
pub fn remove_attached_object(&self, index: i32) -> bool {
functions::Player_RemoveAttachedObject(self, index)
}
pub fn set_facing_angle(&self, angle: f32) -> bool {
functions::Player_SetFacingAngle(self, angle)
}
pub fn set_marker_for_player(&self, other: &Player, colour: Colour) -> bool {
functions::Player_SetMarkerForPlayer(self, other, colour.rgba())
}
pub fn get_marker_for_player(&self, other: &Player) -> u32 {
functions::Player_GetMarkerForPlayer(self, other)
}
pub fn allow_teleport(&self, allow: bool) -> bool {
functions::Player_AllowTeleport(self, allow)
}
pub fn is_teleport_allowed(&self) -> bool {
functions::Player_IsTeleportAllowed(self)
}
pub fn set_remote_vehicle_collisions(&self, collide: bool) -> bool {
functions::Player_DisableRemoteVehicleCollisions(self, !collide)
}
pub fn select_text_draw(&self, hover_colour: Colour) -> bool {
functions::Player_SelectTextDraw(self, hover_colour.rgba())
}
pub fn cancel_select_text_draw(&self) -> bool {
functions::Player_CancelSelectTextDraw(self)
}
pub fn send_client_check(
&self,
action_type: i32,
address: i32,
offset: i32,
count: i32,
) -> bool {
functions::Player_SendClientCheck(self, action_type, address, offset, count)
}
pub fn spawn(&self) {
self.defer_api_call(Box::new(move |player| {
functions::Player_Spawn(&player);
}));
}
pub fn gpci(&self) -> String {
let mut output = String::new();
functions::Player_GPCI(self, &mut output, 41);
output
}
pub fn is_admin(&self) -> bool {
functions::Player_IsAdmin(self)
}
pub fn kick(&self) {
self.defer_api_call(Box::new(move |player| {
functions::Player_Kick(&player);
}));
}
pub fn show_game_text(&self, msg: &str, time: i32, style: i32) -> bool {
functions::Player_ShowGameText(self, msg, time, style)
}
pub fn hide_game_text(&self, style: i32) -> bool {
functions::Player_HideGameText(self, style)
}
pub fn has_game_text(&self, style: i32) -> bool {
functions::Player_HasGameText(self, style)
}
pub fn get_game_text(
&self,
style: i32,
message: &mut String,
time: &mut i32,
remaining: &mut i32,
) -> bool {
functions::Player_GetGameText(self, style, message, 32, time, remaining)
}
pub fn ban(&self) {
self.defer_api_call(Box::new(move |player| {
functions::Player_Ban(&player);
}));
}
pub fn ban_ex(&self, msg: &str) {
let msg = msg.to_owned();
self.defer_api_call(Box::new(move |player| {
functions::Player_BanEx(&player, &msg);
}));
}
pub fn send_message_to_player(&self, sender: &Player, message: &str) -> bool {
functions::Player_SendMessageToPlayer(self, sender, message)
}
pub fn get_version(&self) -> String {
let mut output = String::new();
functions::Player_GetVersion(self, &mut output, 24);
output
}
pub fn get_skill_level(&self, skill: i32) -> i32 {
functions::Player_GetSkillLevel(self, skill)
}
pub fn get_spectate_id(&self) -> i32 {
functions::Player_GetPlayerSpectateID(self)
}
pub fn get_spectate_data(&self) -> PlayerSpectateData {
let mut spectate_data = PlayerSpectateData {
spectating: false,
spectateID: self.get_spectate_id(),
spectate_type: unsafe { transmute(functions::Player_GetSpectateType(self)) },
};
spectate_data.spectating = spectate_data.spectateID != 0xFFFF;
spectate_data
}
pub fn get_raw_ip(&self) -> u32 {
functions::Player_GetRawIp(self)
}
pub fn set_gravity(&self, gravity: f32) {
self.defer_api_call(Box::new(move |player| {
functions::Player_SetGravity(&player, gravity);
}));
}
pub fn get_gravity(&self) -> f32 {
functions::Player_GetGravity(self)
}
pub fn set_admin(&self, set: bool) -> bool {
functions::Player_SetAdmin(self, set)
}
pub fn is_spawned(&self) -> bool {
functions::Player_IsSpawned(self)
}
pub fn is_controllable(&self) -> bool {
functions::Player_IsControllable(self)
}
pub fn is_camera_target_enabled(&self) -> bool {
functions::Player_IsCameraTargetEnabled(self)
}
pub fn toggle_ghost_mode(&self, toggle: bool) -> bool {
functions::Player_ToggleGhostMode(self, toggle)
}
pub fn get_ghost_mode(&self) -> bool {
functions::Player_GetGhostMode(self)
}
pub fn allow_weapons(&self, allow: bool) -> bool {
functions::Player_AllowWeapons(self, allow)
}
pub fn are_weapons_allowed(&self) -> bool {
functions::Player_AreWeaponsAllowed(self)
}
pub fn is_using_official_client(&self) -> bool {
functions::Player_IsPlayerUsingOfficialClient(self)
}
pub fn get_animation_data(&self) -> PlayerAnimationData {
PlayerAnimationData {
id: functions::Player_GetAnimationIndex(self) as u16,
flags: functions::Player_GetAnimationFlags(self) as u16,
}
}
pub fn is_in_drive_by_mode(&self) -> bool {
functions::Player_IsInDriveByMode(self)
}
pub fn is_cuffed(&self) -> bool {
functions::Player_IsCuffed(self)
}
pub fn get_custom_skin(&self) -> i32 {
functions::Player_GetCustomSkin(self)
}
pub fn redirect_download(&self, url: &str) -> bool {
models::functions::CustomModel_RedirectDownload(self, url)
}
pub fn set_player_checkpoint(&self, centre_position: Vector3, radius: f32) -> bool {
checkpoints::functions::Checkpoint_Set(
self,
centre_position.x,
centre_position.y,
centre_position.z,
radius,
)
}
pub fn disable_player_checkpoint(&self) -> bool {
checkpoints::functions::Checkpoint_Disable(self)
}
pub fn is_player_in_checkpoint(&self) -> bool {
checkpoints::functions::Checkpoint_IsPlayerIn(self)
}
pub fn set_player_race_checkpoint(
&self,
race_check_point_type: RaceCheckpointType,
centre_position: Vector3,
next_position: Vector3,
radius: f32,
) -> bool {
checkpoints::functions::RaceCheckpoint_Set(
self,
race_check_point_type as i32,
centre_position.x,
centre_position.y,
centre_position.z,
next_position.x,
next_position.y,
next_position.z,
radius,
)
}
pub fn disable_player_race_checkpoint(&self) -> bool {
checkpoints::functions::Checkpoint_Disable(self)
}
pub fn is_player_in_race_checkpoint(&self) -> bool {
checkpoints::functions::Checkpoint_IsPlayerIn(self)
}
pub fn is_player_checkpoint_active(&self) -> bool {
checkpoints::functions::Checkpoint_IsActive(self)
}
pub fn get_player_checkpoint(&self) -> PlayerCheckPointData {
let mut center_pos = Vector3::default();
let mut radius = 0.0;
checkpoints::functions::Checkpoint_Get(
self,
&mut center_pos.x,
&mut center_pos.y,
&mut center_pos.z,
&mut radius,
);
PlayerCheckPointData::new(center_pos, radius)
}
pub fn is_player_race_checkpoint_active(&self) -> bool {
checkpoints::functions::RaceCheckpoint_IsActive(self)
}
pub fn get_player_race_checkpoint(&self) -> PlayerRaceCheckPointData {
let mut center_pos = Vector3::default();
let mut next_pos = Vector3::default();
let mut radius = 0.0;
checkpoints::functions::RaceCheckpoint_Get(
self,
&mut center_pos.x,
&mut center_pos.y,
&mut center_pos.z,
&mut next_pos.x,
&mut next_pos.y,
&mut next_pos.z,
&mut radius,
);
PlayerRaceCheckPointData::new(center_pos, next_pos, radius)
}
pub fn set_spawn_info(&self, player_class: PlayerClass) -> bool {
functions::Player_SetSpawnInfo(
self,
player_class.team,
player_class.skin,
player_class.spawn.x,
player_class.spawn.y,
player_class.spawn.z,
player_class.angle,
player_class.weapons[0].id as u8,
player_class.weapons[0].ammo,
player_class.weapons[1].id as u8,
player_class.weapons[1].ammo,
player_class.weapons[2].id as u8,
player_class.weapons[2].ammo,
)
}
pub fn get_spawn_info(&self) -> PlayerClass {
let mut player_class = PlayerClass::default();
let (mut weapon1, mut ammo1, mut weapon2, mut ammo2, mut weapon3, mut ammo3): (
u8,
u32,
u8,
u32,
u8,
u32,
) = (0, 0, 0, 0, 0, 0);
functions::Player_GetSpawnInfo(
self,
&mut player_class.team,
&mut player_class.skin,
&mut player_class.spawn.x,
&mut player_class.spawn.y,
&mut player_class.spawn.z,
&mut player_class.angle,
&mut weapon1,
&mut ammo1,
&mut weapon2,
&mut ammo2,
&mut weapon3,
&mut ammo3,
);
player_class.weapons[0].id = unsafe { transmute(weapon1) };
player_class.weapons[0].ammo = ammo1;
player_class.weapons[1].id = unsafe { transmute(weapon2) };
player_class.weapons[1].ammo = ammo2;
player_class.weapons[2].id = unsafe { transmute(weapon3) };
player_class.weapons[2].ammo = ammo3;
player_class
}
pub fn show_dialog(
&self,
dialog: i32,
style: DialogStyle,
title: &str,
body: &str,
button1: &str,
button2: &str,
) -> bool {
dialogs::functions::Dialog_Show(self, dialog, style as i32, title, body, button1, button2)
}
pub fn get_dialog_id(&self) -> i32 {
functions::Player_GetDialog(self)
}
pub fn hide_dialog(&self) -> bool {
dialogs::functions::Dialog_Hide(self)
}
pub fn get_id(&self) -> i32 {
functions::Player_GetID(self) as i32
}
pub fn from_id(playerid: i32) -> Option<Player> {
functions::Player_FromID(playerid)
}
pub fn get_menu(&self) -> Option<Menu> {
functions::Player_GetMenu(self)
}
pub fn edit_object(&self, object: &Object) -> bool {
objects::functions::Object_BeginEditing(self, object)
}
pub fn select_object(&self) -> bool {
objects::functions::Object_BeginSelecting(self)
}
pub fn end_object_editing(&self) -> bool {
objects::functions::Object_EndEditing(self)
}
pub fn create_player_object(
&self,
modelid: i32,
position: Vector3,
rotation: Vector3,
drawDistance: f32,
) -> Option<PlayerObject> {
let mut _id = -1;
objects::functions::PlayerObject_Create(
self,
modelid,
position.x,
position.y,
position.z,
rotation.x,
rotation.y,
rotation.z,
drawDistance,
&mut _id,
)
}
pub fn destroy_player_object(&self, object: PlayerObject) -> bool {
objects::functions::PlayerObject_Destroy(self, &object)
}
pub fn edit_player_object(&self, object: &PlayerObject) -> bool {
objects::functions::PlayerObject_BeginEditing(self, object)
}
pub fn get_player_object_from_id(&self, id: i32) -> Option<PlayerObject> {
objects::functions::PlayerObject_FromID(self, id)
}
pub fn create_player_text_draw(&self, position: Vector2, text: &str) -> Option<PlayerTextDraw> {
let mut _id = 0;
textdraws::functions::PlayerTextDraw_Create(self, position.x, position.y, text, &mut _id)
}
pub fn player_text_draw_destroy(&self, textdraw: &PlayerTextDraw) -> bool {
textdraws::functions::PlayerTextDraw_Destroy(self, textdraw)
}
pub fn create_player_text_label_on_player(
&self,
attachedPlayer: &Player,
text: &str,
colour: Colour,
position: Vector3,
drawDistance: f32,
los: bool,
) -> Option<PlayerTextLabel> {
let mut _id = 0;
textlabels::functions::PlayerTextLabel_Create(
self,
text,
colour.rgba(),
position.x,
position.y,
position.z,
drawDistance,
attachedPlayer,
&Vehicle::new(std::ptr::null()),
los,
&mut _id,
)
}
pub fn create_player_text_label_on_vehicle(
&self,
attachedVehicle: &Vehicle,
text: &str,
colour: Colour,
position: Vector3,
drawDistance: f32,
los: bool,
) -> Option<PlayerTextLabel> {
let mut _id = 0;
textlabels::functions::PlayerTextLabel_Create(
self,
text,
colour.rgba(),
position.x,
position.y,
position.z,
drawDistance,
&Player::new(std::ptr::null()),
attachedVehicle,
los,
&mut _id,
)
}
pub fn create_player_text_label(
&self,
text: &str,
colour: Colour,
position: Vector3,
drawDistance: f32,
los: bool,
) -> Option<PlayerTextLabel> {
let mut _id = 0;
textlabels::functions::PlayerTextLabel_Create(
self,
text,
colour.rgba(),
position.x,
position.y,
position.z,
drawDistance,
&Player::new(std::ptr::null()),
&Vehicle::new(std::ptr::null()),
los,
&mut _id,
)
}
pub fn delete_player_text_label(&self, textlabel: PlayerTextLabel) -> bool {
textlabels::functions::PlayerTextLabel_Destroy(self, &textlabel)
}
pub fn is_player_in_mod_shop(&self) -> bool {
functions::Player_IsInModShop(self)
}
pub fn get_player_siren_state(&self) -> i32 {
functions::Player_GetSirenState(self)
}
pub fn get_player_landing_gear_state(&self) -> i32 {
functions::Player_GetLandingGearState(self)
}
pub fn get_player_hydra_reactor_angle(&self) -> u32 {
functions::Player_GetHydraReactorAngle(self)
}
pub fn get_player_train_speed(&self) -> f32 {
functions::Player_GetTrainSpeed(self)
}
pub fn get_net_stats(&self) -> String {
let mut output = String::new();
functions::Player_GetNetworkStats(self, &mut output, 400);
output
}
pub fn net_stats_get_ip_port(&self) -> String {
let mut output = String::new();
functions::Player_NetStatsGetIpPort(self, &mut output, 22);
output
}
pub fn set_attached_object(&self, index: i32, attachment: ObjectAttachmentSlotData) -> bool {
functions::Player_SetAttachedObject(
self,
index,
attachment.model,
attachment.bone,
attachment.offset.x,
attachment.offset.y,
attachment.offset.z,
attachment.rotation.x,
attachment.rotation.y,
attachment.rotation.z,
attachment.scale.x,
attachment.scale.y,
attachment.scale.z,
attachment.colour1.argb(),
attachment.colour2.argb(),
)
}
pub fn get_attached_object(&self, index: i32) -> ObjectAttachmentSlotData {
let mut attachment = ObjectAttachmentSlotData::default();
let mut colour1 = 0;
let mut colour2 = 0;
functions::Player_GetAttachedObject(
self,
index,
&mut attachment.model,
&mut attachment.bone,
&mut attachment.offset.x,
&mut attachment.offset.y,
&mut attachment.offset.z,
&mut attachment.rotation.x,
&mut attachment.rotation.y,
&mut attachment.rotation.z,
&mut attachment.scale.x,
&mut attachment.scale.y,
&mut attachment.scale.z,
&mut colour1,
&mut colour2,
);
attachment.colour1 = Colour::from_argb(colour1 as u32);
attachment.colour2 = Colour::from_argb(colour2 as u32);
attachment
}
pub fn is_using_omp(&self) -> bool {
functions::Player_IsUsingOmp(self)
}
fn defer_api_call(&self, callback: Box<dyn FnOnce(Self)>) {
let player_id = self.get_id();
queue_api_call(Box::new(move || {
let player = match Self::from_id(player_id) {
Some(player) => player,
None => {
log::error!("player with id={player_id} not found");
return;
}
};
callback(player);
}));
}
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum MapIconStyle {
Local,
Global,
LocalCheckpoint,
GlobalCheckpoint,
}
#[repr(u8)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum ClientVersion {
Samp037,
Samp03dl,
Openmp,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PlayerCameraCutType {
Cut,
Move,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PlayerNameStatus {
Updated,
Taken,
Invalid,
}
impl From<i32> for PlayerNameStatus {
fn from(value: i32) -> Self {
match value {
0 => PlayerNameStatus::Updated,
1 => PlayerNameStatus::Taken,
_ => PlayerNameStatus::Invalid,
}
}
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PlayerAnimationSyncType {
NoSync,
Sync,
SyncOthers,
}
#[repr(C)]
#[derive(Default, Clone, Copy, Debug)]
pub struct WeaponSlotData {
pub id: PlayerWeapon,
pub ammo: u32,
}
impl WeaponSlotData {
pub fn new(id: PlayerWeapon, ammo: u32) -> Self {
Self { id, ammo }
}
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub struct PlayerAnimationData {
pub id: u16,
pub flags: u16,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PlayerFightingStyle {
Normal = 4,
Boxing = 5,
KungFu = 6,
KneeHead = 7,
GrabKick = 15,
Elbow = 16,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PlayerState {
None = 0,
OnFoot = 1,
Driver = 2,
Passenger = 3,
ExitVehicle = 4,
EnterVehicleDriver = 5,
EnterVehiclePassenger = 6,
Wasted = 7,
Spawned = 8,
Spectating = 9,
}
impl From<i32> for PlayerState {
fn from(value: i32) -> Self {
match value {
1 => PlayerState::OnFoot,
2 => PlayerState::Driver,
3 => PlayerState::Passenger,
4 => PlayerState::ExitVehicle,
5 => PlayerState::EnterVehicleDriver,
6 => PlayerState::EnterVehiclePassenger,
7 => PlayerState::Wasted,
8 => PlayerState::Spawned,
9 => PlayerState::Spectating,
_ => PlayerState::None,
}
}
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PlayerWeaponSkill {
Pistol,
SilencedPistol,
DesertEagle,
Shotgun,
SawnOff,
Spas12,
Uzi,
Mp5,
Ak47,
M4,
Sniper,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PlayerSpecialAction {
None,
Duck,
Jetpack,
EnterVehicle,
ExitVehicle,
Dance1,
Dance2,
Dance3,
Dance4,
HandsUp = 10,
Cellphone,
Sitting,
StopCellphone,
Beer = 20,
Smoke,
Wine,
Sprunk,
Cuffed,
Carry,
Pissing = 68,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub struct PlayerSurfingData {
pub surftype: i32,
pub id: i32,
pub offset: Vector3,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub struct PlayerKeyData {
pub keys: u32,
pub upDown: i16,
pub leftRight: i16,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug, Default)]
pub struct PlayerBulletData {
pub origin: Vector3,
pub hitPos: Vector3,
pub offset: Vector3,
pub weapon: PlayerWeapon,
pub hitType: PlayerBulletHitType,
pub hitID: u16,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug, Default)]
pub enum PlayerBulletHitType {
#[default]
None,
Player = 1,
Vehicle = 2,
Object = 3,
PlayerObject = 4,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum SpectateType {
None,
Vehicle,
Player,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub struct PlayerSpectateData {
pub spectating: bool,
pub spectateID: i32,
pub spectate_type: SpectateType,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PlayerSpectateMode {
Normal = 1,
Fixed,
Side,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub struct PlayerAimData {
pub camFrontVector: Vector3,
pub camPos: Vector3,
pub aimZ: f32,
pub camZoom: f32,
pub aspectRatio: f32,
pub weaponState: PlayerWeaponState,
pub camMode: u8,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PlayerWeaponState {
Unknown = -1,
NoBullets,
LastBullet,
MoreBullets,
Reloading,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum BodyPart {
Torso = 3,
Groin,
LeftArm,
RightArm,
LeftLeg,
RightLeg,
Head,
}
#[repr(C)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PlayerClickSource {
Scoreboard,
}
pub type WeaponSlots = StaticArray<WeaponSlotData, 13>;
#[repr(u8)]
#[derive(PartialEq, Copy, Clone, Default, Debug)]
pub enum PlayerWeapon {
#[default]
Fist,
BrassKnuckle,
GolfClub,
NiteStick,
Knife,
Bat,
Shovel,
PoolStick,
Katana,
Chainsaw,
Dildo,
Dildo2,
Vibrator,
Vibrator2,
Flower,
Cane,
Grenade,
Teargas,
Moltov,
Colt45 = 22,
Silenced,
Deagle,
Shotgun,
Sawedoff,
Shotgspa,
UZI,
MP5,
AK47,
M4,
TEC9,
Rifle,
Sniper,
RocketLauncher,
HeatSeeker,
FlameThrower,
Minigun,
Satchel,
Bomb,
SprayCan,
FireExtinguisher,
Camera,
NightVisGoggles,
ThermalGoggles,
Parachute,
Vehicle = 49,
Heliblades,
Explosion,
Drown = 53,
Collision,
End,
Connect = 200,
Disconnect,
Suicide = 255,
}
pub mod PlayerKeys {
pub const ACTION: u32 = 1;
pub const CROUCH: u32 = 2;
pub const FIRE: u32 = 4;
pub const SPRINT: u32 = 8;
pub const SECONDARY_ATTACK: u32 = 16;
pub const JUMP: u32 = 32;
pub const LOOK_RIGHT: u32 = 64;
pub const HANDBRAKE: u32 = 128;
pub const LOOK_LEFT: u32 = 256;
pub const SUBMISSION: u32 = 512;
pub const LOOK_BEHIND: u32 = 512;
pub const WALK: u32 = 1024;
pub const ANALOG_UP: u32 = 2048;
pub const ANALOG_DOWN: u32 = 4096;
pub const ANALOG_LEFT: u32 = 8192;
pub const ANALOG_RIGHT: u32 = 16384;
pub const YES: u32 = 65536;
pub const NO: u32 = 131072;
pub const CTRL_BACK: u32 = 262144;
pub const UP: i32 = -128;
pub const DOWN: i32 = 128;
pub const LEFT: i32 = -128;
pub const RIGHT: i32 = 128;
}