omp_gdk/scripting/players/
mod.rs

1pub mod events;
2pub mod functions;
3
4pub use functions::load_functions;
5
6use crate::{
7    actors::Actor,
8    classes::PlayerClass,
9    dialogs::{self, DialogStyle},
10    models,
11    objects::{self, Object, ObjectAttachmentSlotData, PlayerObject},
12    runtime::queue_api_call,
13    textdraws::{self, PlayerTextDraw},
14    types::{
15        animationdata::AnimationData,
16        colour::Colour,
17        staticarray::StaticArray,
18        vector::{Vector2, Vector3, Vector4},
19    },
20    vehicles::Vehicle,
21};
22use std::{mem::transmute, os::raw::c_void};
23
24use super::{
25    checkpoints::{self, PlayerCheckPointData, PlayerRaceCheckPointData, RaceCheckpointType},
26    menus::Menu,
27    textlabels::{self, PlayerTextLabel},
28};
29
30#[derive(Clone, Copy)]
31pub struct Player {
32    handle: *const c_void,
33}
34
35impl Player {
36    pub fn new(handle: *const c_void) -> Self {
37        Self { handle }
38    }
39
40    pub fn get_handle(&self) -> *const c_void {
41        self.handle
42    }
43
44    /// This function sends a message to a specific player with a chosen color in the chat.
45    pub fn send_client_message(&self, colour: Colour, message: &str) -> bool {
46        functions::Player_SendClientMessage(self, colour.rgba(), message)
47    }
48
49    /// Get a player's name.
50    pub fn get_name(&self) -> String {
51        let mut name = String::new();
52        functions::Player_GetName(self, &mut name, 24);
53        name
54    }
55
56    /// Sets the camera to a specific position for a player.
57    pub fn set_camera_pos(&self, pos: Vector3) -> bool {
58        functions::Player_SetCameraPos(self, pos.x, pos.y, pos.z)
59    }
60
61    /// Sets the drunk level of a player which makes the player's camera sway and vehicles hard to control.
62    pub fn set_drunk_level(&self, level: i32) -> bool {
63        functions::Player_SetDrunkLevel(self, level)
64    }
65
66    /// Set a player's interior.
67    pub fn set_interior(&self, interiorid: i32) {
68        self.defer_api_call(Box::new(move |player| {
69            functions::Player_SetInterior(&player, interiorid);
70        }));
71    }
72
73    /// Set a player's wanted level (6 brown stars under HUD).
74    pub fn set_wanted_level(&self, level: i32) -> bool {
75        functions::Player_SetWantedLevel(self, level)
76    }
77
78    /// Set a player's weather.
79    pub fn set_weather(&self, weatherid: i32) -> bool {
80        functions::Player_SetWeather(self, weatherid)
81    }
82
83    /// Get a player's weather.
84    pub fn get_weather(&self) -> i32 {
85        functions::Player_GetWeather(self)
86    }
87
88    /// Set the skin of a player.
89    pub fn set_skin(&self, skinid: i32) -> bool {
90        functions::Player_SetSkin(self, skinid)
91    }
92
93    /// Loads or unloads an interior script for a player (for example the ammunation menu).
94    pub fn set_shop_name(&self, shopname: &str) -> bool {
95        functions::Player_SetShopName(self, shopname)
96    }
97
98    /// Give money to or take money from a player.
99    pub fn give_money(&self, amount: i32) -> bool {
100        functions::Player_GiveMoney(self, amount)
101    }
102
103    /// Set the direction a player's camera looks at.
104    pub fn set_camera_look_at(&self, pos: Vector3, cut: PlayerCameraCutType) -> bool {
105        functions::Player_SetCameraLookAt(self, pos.x, pos.y, pos.z, cut as i32)
106    }
107
108    /// Restore the camera to a place behind the player, after using a function like SetPlayerCameraPos.
109    pub fn set_camera_behind_player(&self) -> bool {
110        functions::Player_SetCameraBehind(self)
111    }
112
113    /// Creates an explosion that is only visible to a single player.
114    pub fn create_explosion(&self, pos: Vector3, explosion_type: i32, radius: f32) -> bool {
115        functions::Player_CreateExplosion(self, pos.x, pos.y, pos.z, explosion_type, radius)
116    }
117
118    /// Play an 'audio stream' for a player.
119    pub fn play_audio_stream(&self, url: &str, pos: Vector3, distance: f32, use_pos: bool) -> bool {
120        functions::Player_PlayAudioStream(self, url, pos.x, pos.y, pos.z, distance, use_pos)
121    }
122
123    /// Stops the current audio stream for a player.
124    pub fn stop_audio_stream(&self) -> bool {
125        functions::Player_StopAudioStream(self)
126    }
127
128    /// Adds a death to the 'killfeed' on the right-hand side of the screen for all players.
129    pub fn send_death_message(
130        &self,
131        killer: &Player,
132        killee: &Player,
133        weapon: PlayerWeapon,
134    ) -> bool {
135        functions::Player_SendDeathMessage(self, killer, killee, weapon as i32)
136    }
137
138    /// Toggle player's widescreen.
139    pub fn toggle_widescreen(&self, enable: bool) -> bool {
140        functions::Player_ToggleWidescreen(self, enable)
141    }
142
143    /// Checks if a player widescreen is on or off.
144    pub fn is_widescreen_toggled(&self) -> bool {
145        functions::Player_IsWidescreenToggled(self)
146    }
147
148    /// Set the health of a player.
149    pub fn set_health(&self, health: f32) {
150        self.defer_api_call(Box::new(move |player| {
151            functions::Player_SetHealth(&player, health);
152        }));
153    }
154
155    /// The function GetPlayerHealth allows you to retrieve the health of a player.
156    pub fn get_health(&self) -> f32 {
157        functions::Player_GetHealth(self)
158    }
159
160    /// Set a player's armor level.
161    pub fn set_armour(&self, armour: f32) -> bool {
162        functions::Player_SetArmor(self, armour)
163    }
164
165    /// This function stores the armour of a player into a variable.
166    pub fn get_armour(&self) -> f32 {
167        functions::Player_GetArmor(self)
168    }
169
170    /// Set the team of a player.
171    pub fn set_team(&self, teamid: i32) -> bool {
172        functions::Player_SetTeam(self, teamid)
173    }
174
175    /// Get the ID of the team the player is on.
176    pub fn get_team(&self) -> i32 {
177        functions::Player_GetTeam(self)
178    }
179
180    /// Set a player's score.
181    pub fn set_score(&self, score: i32) -> bool {
182        functions::Player_SetScore(self, score)
183    }
184
185    /// This function returns a player's score as it was set using SetPlayerScore.
186    pub fn get_score(&self) -> i32 {
187        functions::Player_GetScore(self)
188    }
189
190    /// Returns the class of the players skin.
191    pub fn get_skin(&self) -> i32 {
192        functions::Player_GetSkin(self)
193    }
194
195    /// Set the colour of a player's nametag and marker (radar blip).
196    pub fn set_color(&self, colour: Colour) -> bool {
197        functions::Player_SetColor(self, colour.rgba())
198    }
199
200    /// Gets the color of the player's name and radar marker.
201    pub fn get_color(&self) -> Colour {
202        Colour::from_rgba(functions::Player_GetColor(self))
203    }
204
205    /// Gets the default colour for the player ID.
206    pub fn get_default_colour(&self) -> Colour {
207        Colour::from_rgba(functions::Player_GetDefaultColor(self))
208    }
209
210    /// Checks the player's level of drunkenness.
211    pub fn get_drunk_level(&self) -> i32 {
212        functions::Player_GetDrunkLevel(self)
213    }
214
215    /// Give a player a weapon with a specified amount of ammo.
216    pub fn give_weapon(&self, data: WeaponSlotData) -> bool {
217        functions::Player_GiveWeapon(self, data.id as i32, data.ammo as i32)
218    }
219
220    /// Remove a specified weapon from a player.
221    pub fn remove_weapon(&self, weaponid: u8) -> bool {
222        functions::Player_RemoveWeapon(self, weaponid as i32)
223    }
224
225    /// Retrieves the amount of money a player has.
226    pub fn get_money(&self) -> i32 {
227        functions::Player_GetMoney(self)
228    }
229
230    /// Reset a player's money to $0.
231    pub fn reset_money(&self) -> bool {
232        functions::Player_ResetMoney(self)
233    }
234
235    /// Sets the name of a player.
236    pub fn set_name(&self, name: &str) -> PlayerNameStatus {
237        PlayerNameStatus::from(functions::Player_SetName(self, name))
238    }
239
240    /// Get a player's current state.
241    pub fn get_state(&self) -> PlayerState {
242        PlayerState::from(functions::Player_GetState(self))
243    }
244
245    /// Get the ping of a player.
246    pub fn get_ping(&self) -> i32 {
247        functions::Player_GetPing(self)
248    }
249
250    /// Returns the ID of the weapon a player is currently holding.
251    pub fn get_weapon(&self) -> PlayerWeapon {
252        // May be i should stop  being lazy and implement from trait..maybe
253        unsafe { transmute(functions::Player_GetWeapon(self) as u8) }
254    }
255
256    /// Sets the game time for a player.
257    pub fn set_time(&self, hour: i32, minute: i32) -> bool {
258        functions::Player_SetTime(self, hour, minute)
259    }
260
261    /// Get the player's current game time.
262    pub fn get_time(&self) -> (i32, i32) {
263        let mut hour = 0;
264        let mut minute = 0;
265        functions::Player_GetTime(self, &mut hour, &mut minute);
266        (hour, minute)
267    }
268
269    /// Toggle the in-game clock (top-right corner) for a specific player.
270    pub fn toggle_clock(&self, enable: bool) -> bool {
271        functions::Player_ToggleClock(self, enable)
272    }
273
274    /// Checks whether the player has their in-game clock enabled.
275    pub fn has_clock_enabled(&self) -> bool {
276        functions::Player_HasClock(self)
277    }
278
279    /// Forces a player to go back to class selection.
280    pub fn force_class_selection(&self) {
281        self.defer_api_call(Box::new(move |player| {
282            functions::Player_ForceClassSelection(&player);
283        }));
284    }
285
286    /// Gets the wanted level of a player.
287    pub fn get_wanted_level(&self) -> i32 {
288        functions::Player_GetWantedLevel(self)
289    }
290
291    /// Set a player's special fighting style.
292    pub fn set_fighting_style(&self, style: PlayerFightingStyle) -> bool {
293        functions::Player_SetFightingStyle(self, style as i32)
294    }
295
296    /// Get the fighting style the player currently using.
297    pub fn get_fighting_style(&self) -> PlayerFightingStyle {
298        unsafe { transmute(functions::Player_GetFightingStyle(self)) }
299    }
300
301    /// Set a player's velocity on the X, Y and Z axes.
302    pub fn set_velocity(&self, pos: Vector3) {
303        self.defer_api_call(Box::new(move |player| {
304            functions::Player_SetVelocity(&player, pos.x, pos.y, pos.z);
305        }));
306    }
307
308    /// Get the velocity (speed) of a player on the X, Y and Z axes.
309    pub fn get_velocity(&self) -> Vector3 {
310        let mut pos = Vector3 {
311            x: 0.0,
312            y: 0.0,
313            z: 0.0,
314        };
315        functions::Player_GetVelocity(self, &mut pos.x, &mut pos.y, &mut pos.z);
316        pos
317    }
318
319    /// Get the position of the player's camera.
320    pub fn get_camera_pos(&self) -> Vector3 {
321        let mut pos = Vector3 {
322            x: 0.0,
323            y: 0.0,
324            z: 0.0,
325        };
326        functions::Player_GetCameraPos(self, &mut pos.x, &mut pos.y, &mut pos.z);
327        pos
328    }
329
330    /// Calculate the distance between a player and a map coordinate.
331    pub fn get_distance_from_point(&self, pos: Vector3) -> f32 {
332        functions::Player_GetDistanceFromPoint(self, pos.x, pos.y, pos.z)
333    }
334
335    /// Retrieves the player's current interior.
336    pub fn get_interior(&self) -> i32 {
337        functions::Player_GetInterior(self)
338    }
339
340    /// Set a player's position.
341    pub fn set_pos(&self, pos: Vector3) {
342        self.defer_api_call(Box::new(move |player| {
343            functions::Player_SetPos(&player, pos.x, pos.y, pos.z);
344        }));
345    }
346
347    /// Get the position of a player, represented by X, Y and Z coordinates.
348    pub fn get_pos(&self) -> Vector3 {
349        let mut pos = Vector3 {
350            x: 0.0,
351            y: 0.0,
352            z: 0.0,
353        };
354        functions::Player_GetPos(self, &mut pos.x, &mut pos.y, &mut pos.z);
355        pos
356    }
357
358    /// Retrieves the current virtual world the player is in.
359    pub fn get_virtual_world(&self) -> i32 {
360        functions::Player_GetVirtualWorld(self)
361    }
362
363    /// Check if a player is an actual player or an NPC.
364    pub fn is_npc(&self) -> bool {
365        functions::Player_IsNPC(self)
366    }
367
368    /// Checks if a player is streamed in another player's client.
369    pub fn is_streamed_in(&self, other: &Player) -> bool {
370        functions::Player_IsStreamedIn(self, other)
371    }
372
373    /// Plays the specified sound for a player.
374    pub fn play_sound(&self, sound: usize, pos: Vector3) -> bool {
375        functions::Player_PlayGameSound(self, sound as i32, pos.x, pos.y, pos.z)
376    }
377
378    /// Makes a player spectate (watch) another player.
379    pub fn spectate_player(&self, target: &Player, mode: PlayerSpectateMode) {
380        let target_id = target.get_id();
381        self.defer_api_call(Box::new(move |player| {
382            let target = match Player::from_id(target_id) {
383                Some(target) => target,
384                None => {
385                    log::error!("target player with id={target_id} not found");
386                    return;
387                }
388            };
389            functions::Player_SpectatePlayer(&player, &target, mode as i32);
390        }));
391    }
392
393    /// Sets a player to spectate another vehicle.
394    pub fn spectate_vehicle(&self, vehicle: &Vehicle, mode: PlayerSpectateMode) {
395        let vehicle_id = vehicle.get_id();
396        self.defer_api_call(Box::new(move |player| {
397            let vehicle = match Vehicle::get_from_id(vehicle_id) {
398                Some(vehicle) => vehicle,
399                None => {
400                    log::error!("vehicle with id={vehicle_id} not found");
401                    return;
402                }
403            };
404            functions::Player_SpectateVehicle(&player, &vehicle, mode as i32);
405        }));
406    }
407
408    /// Set the virtual world of a player.
409    pub fn set_virtual_world(&self, vw: i32) -> bool {
410        functions::Player_SetVirtualWorld(self, vw)
411    }
412
413    /// Set the world boundaries for a player.
414    pub fn set_world_bounds(&self, coords: Vector4) -> bool {
415        functions::Player_SetWorldBounds(self, coords.x, coords.y, coords.z, coords.w)
416    }
417
418    /// Reset the player's world boundaries to default world boundaries.
419    pub fn clear_world_bounds(&self) -> bool {
420        functions::Player_ClearWorldBounds(self)
421    }
422
423    /// Get a player's world boundaries.
424    pub fn get_world_bounds(&self) -> Vector4 {
425        let mut pos = Vector4 {
426            x: 0.0,
427            y: 0.0,
428            z: 0.0,
429            w: 0.0,
430        };
431        functions::Player_GetWorldBounds(self, &mut pos.x, &mut pos.y, &mut pos.z, &mut pos.w);
432        pos
433    }
434
435    /// Clears all animations for the given player (it also cancels all current tasks such as jetpacking, parachuting, entering vehicles, driving (removes player out of vehicle), swimming, etc).
436    pub fn clear_animations(&self, sync_type: PlayerAnimationSyncType) {
437        self.defer_api_call(Box::new(move |player| {
438            functions::Player_ClearAnimations(&player, sync_type as i32);
439        }));
440    }
441
442    /// Retrieves the start and end (hit) position of the last bullet a player fired.
443    pub fn get_last_shot_vectors(&self) -> PlayerBulletData {
444        let mut data = PlayerBulletData::default();
445        functions::Player_GetLastShotVectors(
446            self,
447            &mut data.origin.x,
448            &mut data.origin.y,
449            &mut data.origin.z,
450            &mut data.hitPos.x,
451            &mut data.hitPos.y,
452            &mut data.hitPos.z,
453        );
454        data
455    }
456
457    /// Allows you to retrieve the ID of the player the playerid is looking at.
458    pub fn get_camera_target_player(&self) -> Option<Player> {
459        functions::Player_GetCameraTargetPlayer(self)
460    }
461
462    /// Allows you to retrieve the ID of the actor the player is looking at (in any).
463    pub fn get_camera_target_actor(&self) -> Option<Actor> {
464        functions::Player_GetCameraTargetActor(self)
465    }
466
467    /// Allows you to retrieve the ID of the object the player is looking at.
468    pub fn get_camera_target_object(&self) -> Option<Object> {
469        functions::Player_GetCameraTargetObject(self)
470    }
471
472    /// Get the ID of the vehicle the player is looking at.
473    pub fn get_camera_target_vehicle(&self) -> Option<Vehicle> {
474        functions::Player_GetCameraTargetVehicle(self)
475    }
476
477    /// Puts a player in a vehicle.
478    pub fn put_in_vehicle(&self, vehicle: &Vehicle, seat_id: i32) {
479        let vehicle_id = vehicle.get_id();
480        self.defer_api_call(Box::new(move |player| {
481            let vehicle = match Vehicle::get_from_id(vehicle_id) {
482                Some(vehicle) => vehicle,
483                None => {
484                    log::error!("vehicle with id={vehicle_id} not found");
485                    return;
486                }
487            };
488            functions::Player_PutInVehicle(&player, &vehicle, seat_id);
489        }));
490    }
491
492    /// Removes a standard San Andreas model for a single player within a specified range.
493    pub fn remove_building(&self, model: i32, pos: Vector3, radius: f32) -> bool {
494        functions::Player_RemoveBuilding(self, model, pos.x, pos.y, pos.z, radius)
495    }
496
497    /// Gets the number of removed buildings for a player.
498    pub fn get_buildings_removed(&self) -> i32 {
499        functions::Player_GetBuildingsRemoved(self)
500    }
501
502    /// Removes/ejects a player from their vehicle.
503    pub fn remove_from_vehicle(&self, force: bool) {
504        self.defer_api_call(Box::new(move |player| {
505            functions::Player_RemoveFromVehicle(&player, force);
506        }));
507    }
508
509    /// Removes a map icon that was set earlier for a player using SetPlayerMapIcon.
510    pub fn remove_map_icon(&self, icon_id: i32) -> bool {
511        functions::Player_RemoveMapIcon(self, icon_id)
512    }
513
514    /// Place an icon/marker on a player's map.
515    pub fn set_map_icon(
516        &self,
517        icon_id: i32,
518        pos: Vector3,
519        icon_type: i32,
520        colour: Colour,
521        style: MapIconStyle,
522    ) -> bool {
523        functions::Player_SetMapIcon(
524            self,
525            icon_id,
526            pos.x,
527            pos.y,
528            pos.z,
529            icon_type,
530            colour.rgba(),
531            style as i32,
532        )
533    }
534
535    /// Removes all weapons from a player.
536    pub fn reset_weapons(&self) -> bool {
537        functions::Player_ResetWeapons(self)
538    }
539
540    /// Set the ammo of a player's weapon.
541    pub fn set_ammo(&self, data: WeaponSlotData) -> bool {
542        functions::Player_SetAmmo(self, data.id as u8, data.ammo)
543    }
544
545    /// Sets which weapon (that a player already has) the player is holding.
546    pub fn set_armed_weapon(&self, weapon: PlayerWeapon) -> bool {
547        functions::Player_SetArmedWeapon(self, weapon as u8)
548    }
549
550    /// Creates a chat bubble above a player's name tag.
551    pub fn set_chat_bubble(
552        &self,
553        text: &str,
554        colour: Colour,
555        drawdistance: f32,
556        expiretime: i32,
557    ) -> bool {
558        functions::Player_SetChatBubble(self, text, colour.rgba(), drawdistance, expiretime)
559    }
560
561    /// This sets the players position then adjusts the players z-coordinate to the nearest solid ground under the position.
562    pub fn set_pos_find_z(&self, pos: Vector3) {
563        self.defer_api_call(Box::new(move |player| {
564            functions::Player_SetPosFindZ(&player, pos.x, pos.y, pos.z);
565        }));
566    }
567
568    /// Set the skill level of a certain weapon type for a player.
569    pub fn set_skill_level(&self, weapon: PlayerWeaponSkill, level: i32) -> bool {
570        functions::Player_SetSkillLevel(self, weapon as u8, level)
571    }
572
573    /// This function allows to set players special action.
574    pub fn set_special_action(&self, action: PlayerSpecialAction) -> bool {
575        functions::Player_SetSpecialAction(self, action as u32)
576    }
577
578    /// This functions allows you to toggle the drawing of player nametags, healthbars and armor bars which display above their head.
579    pub fn show_name_tag(&self, other: &Player, enable: bool) -> bool {
580        functions::Player_ShowNameTagForPlayer(self, other, enable)
581    }
582
583    /// Toggles whether a player can control their character or not.
584    pub fn toggle_controllable(&self, enable: bool) -> bool {
585        functions::Player_ToggleControllable(self, enable)
586    }
587
588    /// Toggle whether a player is in spectator mode or not.
589    pub fn toggle_spectating(&self, enable: bool) {
590        self.defer_api_call(Box::new(move |player| {
591            functions::Player_ToggleSpectating(&player, enable);
592        }));
593    }
594
595    /// Apply an animation to a player.
596    pub fn apply_animation(
597        &self,
598        animation_data: AnimationData,
599        sync: PlayerAnimationSyncType,
600    ) -> bool {
601        functions::Player_ApplyAnimation(
602            self,
603            &animation_data.get_animation_library(),
604            &animation_data.get_name(),
605            animation_data.delta,
606            animation_data.looping,
607            animation_data.lockX,
608            animation_data.lockY,
609            animation_data.freeze,
610            animation_data.time as u32,
611            sync as i32,
612        )
613    }
614
615    /// Enter edition mode for an attached object.
616    pub fn edit_attached_object(&self, index: i32) -> bool {
617        functions::Player_EditAttachedObject(self, index)
618    }
619
620    /// Toggle camera targeting functions for a player.
621    pub fn enable_camera_target(&self, enable: bool) -> bool {
622        functions::Player_EnableCameraTarget(self, enable)
623    }
624
625    /// Toggle stunt bonuses for a player.
626    pub fn enable_stunt_bonus(&self, enable: bool) -> bool {
627        functions::Player_EnableStuntBonus(self, enable)
628    }
629
630    /// Gets the amount of ammo in a player's current weapon.
631    pub fn get_ammo(&self) -> i32 {
632        functions::Player_GetPlayerAmmo(self)
633    }
634
635    /// Returns the index of any running applied animations.
636    pub fn get_animation_index(&self) -> i32 {
637        functions::Player_GetAnimationIndex(self)
638    }
639
640    /// Gets the angle a player is facing.
641    pub fn get_facing_angle(&self) -> f32 {
642        functions::Player_GetFacingAngle(self)
643    }
644
645    /// Get the specified player's IP address and store it in a string.
646    pub fn get_ip(&self) -> String {
647        let mut ip = String::new();
648        functions::Player_GetIp(self, &mut ip, 15);
649        ip
650    }
651
652    /// Retrieves a player's current special action.
653    pub fn get_special_action(&self) -> PlayerSpecialAction {
654        unsafe { transmute(functions::Player_GetSpecialAction(self)) }
655    }
656
657    /// This function gets the ID of the vehicle the player is currently in.
658    pub fn get_vehicle_id(&self) -> i32 {
659        functions::Player_GetVehicleID(self)
660    }
661
662    /// Find out which seat a player is in.
663    pub fn get_vehicle_seat(&self) -> i32 {
664        functions::Player_GetVehicleSeat(self)
665    }
666
667    /// Get the weapon and ammo in a specific player's weapon slot (e.
668    pub fn get_weapon_data(&self, slot: i32) -> WeaponSlotData {
669        let mut ammo: i32 = 0;
670        let mut id: i32 = 0;
671        functions::Player_GetWeaponData(self, slot, &mut id, &mut ammo);
672        WeaponSlotData {
673            ammo: ammo as _,
674            id: unsafe { transmute(id as u8) },
675        }
676    }
677
678    /// Check the state of a player's weapon.
679    pub fn get_weapon_state(&self) -> i32 {
680        functions::Player_GetWeaponState(self)
681    }
682
683    /// Move a player's camera from one position to another, within the set time.
684    pub fn interpolate_camera_pos(
685        &self,
686        from: Vector3,
687        to: Vector3,
688        time: i32,
689        cut: PlayerCameraCutType,
690    ) -> bool {
691        functions::Player_InterpolateCameraPos(
692            self, from.x, from.y, from.z, to.x, to.y, to.z, time, cut as i32,
693        )
694    }
695
696    /// Interpolate a player's camera's 'look at' point between two coordinates with a set speed.
697    pub fn interpolate_camera_look_at(
698        &self,
699        from: Vector3,
700        to: Vector3,
701        time: i32,
702        cut: PlayerCameraCutType,
703    ) -> bool {
704        functions::Player_InterpolateCameraLookAt(
705            self, from.x, from.y, from.z, to.x, to.y, to.z, time, cut as i32,
706        )
707    }
708
709    /// Check if a player has an object attached in the specified index (slot).
710    pub fn is_attached_object_slot_used(&self, index: i32) -> bool {
711        functions::Player_IsPlayerAttachedObjectSlotUsed(self, index)
712    }
713
714    /// You can use this function to attach the player camera to objects.
715    pub fn attach_camera_to_object(&self, object: &Object) -> bool {
716        functions::Player_AttachCameraToObject(self, object)
717    }
718
719    /// Attaches a player's camera to a player-object.
720    pub fn attach_camera_to_player_object(&self, object: &PlayerObject) -> bool {
721        functions::Player_AttachCameraToPlayerObject(self, object)
722    }
723
724    /* pub fn get_aim_data(&self) -> PlayerAimData {
725        functions::GetPlayerAimData(self)
726    } */
727
728    /// Check which keys a player is pressing.
729    pub fn get_keys(&self) -> PlayerKeyData {
730        let mut keys = 0;
731        let mut updown = 0;
732        let mut leftright = 0;
733        functions::Player_GetKeys(self, &mut keys, &mut updown, &mut leftright);
734        PlayerKeyData {
735            keys: keys as _,
736            leftRight: leftright as _,
737            upDown: updown as _,
738        }
739    }
740
741    pub fn get_surfing_object(&self) -> Option<Object> {
742        functions::Player_GetSurfingObject(self)
743    }
744
745    pub fn get_surfing_vehicle(&self) -> Option<Vehicle> {
746        functions::Player_GetSurfingVehicle(self)
747    }
748
749    /// Check who a player is aiming at.
750    pub fn get_target_player(&self) -> Option<Player> {
751        functions::Player_GetCameraTargetPlayer(self)
752    }
753
754    /// Gets id of an actor which is aimed by certain player.
755    pub fn get_target_actor(&self) -> Option<Actor> {
756        functions::Player_GetCameraTargetActor(self)
757    }
758
759    /// Checks if a player is in a specific vehicle.
760    pub fn is_in_vehicle(&self, target_vehicle: &Vehicle) -> bool {
761        functions::Player_IsInVehicle(self, target_vehicle)
762    }
763
764    /// Check if a player is inside any vehicle (as a driver or passenger).
765    pub fn is_in_any_vehicle(&self) -> bool {
766        functions::Player_IsInAnyVehicle(self)
767    }
768
769    /// Checks if a player is in range of a point.
770    pub fn is_in_range_of_point(&self, range: f32, coord: Vector3) -> bool {
771        functions::Player_IsInRangeOfPoint(self, range, coord.x, coord.y, coord.z)
772    }
773
774    /// This function plays a crime report for a player - just like in single-player when CJ commits a crime.
775    pub fn play_crime_report(&self, suspect: &Player, crime: i32) -> bool {
776        functions::Player_PlayCrimeReport(self, suspect, crime)
777    }
778
779    /// Remove an attached object from a player.
780    pub fn remove_attached_object(&self, index: i32) -> bool {
781        functions::Player_RemoveAttachedObject(self, index)
782    }
783
784    /// Set a player's facing angle (Z rotation).
785    pub fn set_facing_angle(&self, angle: f32) -> bool {
786        functions::Player_SetFacingAngle(self, angle)
787    }
788
789    /// Change the colour of a player's nametag and radar blip for another player.
790    pub fn set_marker_for_player(&self, other: &Player, colour: Colour) -> bool {
791        functions::Player_SetMarkerForPlayer(self, other, colour.rgba())
792    }
793
794    /// Get the colour of a player's nametag and radar blip for another player.
795    pub fn get_marker_for_player(&self, other: &Player) -> u32 {
796        functions::Player_GetMarkerForPlayer(self, other)
797    }
798
799    /// Enable/Disable the teleporting ability for a player by right-clicking on the map.
800    pub fn allow_teleport(&self, allow: bool) -> bool {
801        functions::Player_AllowTeleport(self, allow)
802    }
803
804    /// Can this player teleport by right-clicking on the map?
805    pub fn is_teleport_allowed(&self) -> bool {
806        functions::Player_IsTeleportAllowed(self)
807    }
808
809    pub fn set_remote_vehicle_collisions(&self, collide: bool) -> bool {
810        functions::Player_DisableRemoteVehicleCollisions(self, !collide)
811    }
812
813    /// Display the cursor and allow the player to select a textdraw.
814    pub fn select_text_draw(&self, hover_colour: Colour) -> bool {
815        functions::Player_SelectTextDraw(self, hover_colour.rgba())
816    }
817
818    /// Cancel textdraw selection with the mouse.
819    pub fn cancel_select_text_draw(&self) -> bool {
820        functions::Player_CancelSelectTextDraw(self)
821    }
822
823    /// Perform a memory check on the client.
824    pub fn send_client_check(
825        &self,
826        action_type: i32,
827        address: i32,
828        offset: i32,
829        count: i32,
830    ) -> bool {
831        functions::Player_SendClientCheck(self, action_type, address, offset, count)
832    }
833
834    /// (Re)Spawns a player.
835    pub fn spawn(&self) {
836        self.defer_api_call(Box::new(move |player| {
837            functions::Player_Spawn(&player);
838        }));
839    }
840
841    /// Fetch the CI (computer/client identification) of a user, this is linked to their SAMP/GTA on their computer.
842    pub fn gpci(&self) -> String {
843        let mut output = String::new();
844        functions::Player_GPCI(self, &mut output, 41);
845        output
846    }
847
848    /// Check if a player is logged in as an RCON admin.
849    pub fn is_admin(&self) -> bool {
850        functions::Player_IsAdmin(self)
851    }
852    /// Kicks a player from the server. They will have to quit the game and re-connect if they wish to continue playing.
853    pub fn kick(&self) {
854        self.defer_api_call(Box::new(move |player| {
855            functions::Player_Kick(&player);
856        }));
857    }
858
859    /// Shows 'game text' (on-screen text) for a certain length of time for a specific player.
860    pub fn show_game_text(&self, msg: &str, time: i32, style: i32) -> bool {
861        functions::Player_ShowGameText(self, msg, time, style)
862    }
863
864    /// Stop showing a gametext style to a player.
865    pub fn hide_game_text(&self, style: i32) -> bool {
866        functions::Player_HideGameText(self, style)
867    }
868
869    /// Does the player currently have text in the given gametext style displayed?
870    pub fn has_game_text(&self, style: i32) -> bool {
871        functions::Player_HasGameText(self, style)
872    }
873
874    /// Returns all the information on the given game text style.
875    pub fn get_game_text(
876        &self,
877        style: i32,
878        message: &mut String,
879        time: &mut i32,
880        remaining: &mut i32,
881    ) -> bool {
882        functions::Player_GetGameText(self, style, message, 32, time, remaining)
883    }
884
885    /// Ban a player who is currently in the server.
886    pub fn ban(&self) {
887        self.defer_api_call(Box::new(move |player| {
888            functions::Player_Ban(&player);
889        }));
890    }
891
892    /// Ban a player with a reason.
893    pub fn ban_ex(&self, msg: &str) {
894        let msg = msg.to_owned();
895        self.defer_api_call(Box::new(move |player| {
896            functions::Player_BanEx(&player, &msg);
897        }));
898    }
899
900    /// Sends a message in the name of a player to another player on the server.
901    pub fn send_message_to_player(&self, sender: &Player, message: &str) -> bool {
902        functions::Player_SendMessageToPlayer(self, sender, message)
903    }
904
905    /// Returns the SA-MP client version, as reported by the player.
906    pub fn get_version(&self) -> String {
907        let mut output = String::new();
908        functions::Player_GetVersion(self, &mut output, 24);
909        output
910    }
911
912    /// Get the player skill level of a certain weapon type.
913    pub fn get_skill_level(&self, skill: i32) -> i32 {
914        functions::Player_GetSkillLevel(self, skill)
915    }
916
917    /// Gets the ID of the player or vehicle the player is spectating (watching).
918    pub fn get_spectate_id(&self) -> i32 {
919        functions::Player_GetPlayerSpectateID(self)
920    }
921
922    pub fn get_spectate_data(&self) -> PlayerSpectateData {
923        let mut spectate_data = PlayerSpectateData {
924            spectating: false,
925            spectateID: self.get_spectate_id(),
926            spectate_type: unsafe { transmute(functions::Player_GetSpectateType(self)) },
927        };
928        spectate_data.spectating = spectate_data.spectateID != 0xFFFF;
929
930        spectate_data
931    }
932
933    /// Get the specified player's Raw IP address (v4).
934    pub fn get_raw_ip(&self) -> u32 {
935        functions::Player_GetRawIp(self)
936    }
937
938    /// Set a player's gravity.
939    pub fn set_gravity(&self, gravity: f32) {
940        self.defer_api_call(Box::new(move |player| {
941            functions::Player_SetGravity(&player, gravity);
942        }));
943    }
944
945    /// Get a player's gravity.
946    pub fn get_gravity(&self) -> f32 {
947        functions::Player_GetGravity(self)
948    }
949
950    /// Sets the player as an RCON admin.
951    pub fn set_admin(&self, set: bool) -> bool {
952        functions::Player_SetAdmin(self, set)
953    }
954
955    /// Checks if a player is spawned.
956    pub fn is_spawned(&self) -> bool {
957        functions::Player_IsSpawned(self)
958    }
959
960    /// Check if the player is controllable.
961    pub fn is_controllable(&self) -> bool {
962        functions::Player_IsControllable(self)
963    }
964
965    /// Check if the player camera target is enabled.
966    pub fn is_camera_target_enabled(&self) -> bool {
967        functions::Player_IsCameraTargetEnabled(self)
968    }
969
970    /// Toggle player's ghost mode.
971    pub fn toggle_ghost_mode(&self, toggle: bool) -> bool {
972        functions::Player_ToggleGhostMode(self, toggle)
973    }
974
975    /// Get player's ghost mode.
976    pub fn get_ghost_mode(&self) -> bool {
977        functions::Player_GetGhostMode(self)
978    }
979
980    /// Enable/Disable weapons for a player.
981    pub fn allow_weapons(&self, allow: bool) -> bool {
982        functions::Player_AllowWeapons(self, allow)
983    }
984
985    /// Can the player use weapons?
986    pub fn are_weapons_allowed(&self) -> bool {
987        functions::Player_AreWeaponsAllowed(self)
988    }
989
990    /// Check if the player is using the official SA-MP client.
991    pub fn is_using_official_client(&self) -> bool {
992        functions::Player_IsPlayerUsingOfficialClient(self)
993    }
994
995    pub fn get_animation_data(&self) -> PlayerAnimationData {
996        PlayerAnimationData {
997            id: functions::Player_GetAnimationIndex(self) as u16,
998            flags: functions::Player_GetAnimationFlags(self) as u16,
999        }
1000    }
1001
1002    /// Check if the player is in driveby mode.
1003    pub fn is_in_drive_by_mode(&self) -> bool {
1004        functions::Player_IsInDriveByMode(self)
1005    }
1006
1007    /// Checks if the player special action is cuffed.
1008    pub fn is_cuffed(&self) -> bool {
1009        functions::Player_IsCuffed(self)
1010    }
1011
1012    /// Returns the class of the players custom skin downloaded from the server.
1013    pub fn get_custom_skin(&self) -> i32 {
1014        functions::Player_GetCustomSkin(self)
1015    }
1016
1017    /// Redirect a player custom AddCharModel or AddSimpleModel download to a specific HTTP webpage.
1018    pub fn redirect_download(&self, url: &str) -> bool {
1019        models::functions::CustomModel_RedirectDownload(self, url)
1020    }
1021
1022    // Player Checkpoints methods
1023    /// Sets a checkpoint (red cylinder) for a player.
1024    pub fn set_player_checkpoint(&self, centre_position: Vector3, radius: f32) -> bool {
1025        checkpoints::functions::Checkpoint_Set(
1026            self,
1027            centre_position.x,
1028            centre_position.y,
1029            centre_position.z,
1030            radius,
1031        )
1032    }
1033
1034    /// Disables (hides/destroys) a player's set checkpoint.
1035    pub fn disable_player_checkpoint(&self) -> bool {
1036        checkpoints::functions::Checkpoint_Disable(self)
1037    }
1038
1039    /// Check if the player is currently inside a checkpoint, this could be used for properties or teleport points for example.
1040    pub fn is_player_in_checkpoint(&self) -> bool {
1041        checkpoints::functions::Checkpoint_IsPlayerIn(self)
1042    }
1043
1044    /// Creates a race checkpoint.
1045    pub fn set_player_race_checkpoint(
1046        &self,
1047        race_check_point_type: RaceCheckpointType,
1048        centre_position: Vector3,
1049        next_position: Vector3,
1050        radius: f32,
1051    ) -> bool {
1052        checkpoints::functions::RaceCheckpoint_Set(
1053            self,
1054            race_check_point_type as i32,
1055            centre_position.x,
1056            centre_position.y,
1057            centre_position.z,
1058            next_position.x,
1059            next_position.y,
1060            next_position.z,
1061            radius,
1062        )
1063    }
1064
1065    /// Disable any initialized race checkpoints for a specific player, since you can only have one at any given time.
1066    pub fn disable_player_race_checkpoint(&self) -> bool {
1067        checkpoints::functions::Checkpoint_Disable(self)
1068    }
1069
1070    /// Check if the player is inside their current set race checkpoint (SetPlayerRaceCheckpoint).
1071    pub fn is_player_in_race_checkpoint(&self) -> bool {
1072        checkpoints::functions::Checkpoint_IsPlayerIn(self)
1073    }
1074
1075    /// Check if the player currently has a checkpoint visible.
1076    pub fn is_player_checkpoint_active(&self) -> bool {
1077        checkpoints::functions::Checkpoint_IsActive(self)
1078    }
1079
1080    /// Get the location of the current checkpoint.
1081    pub fn get_player_checkpoint(&self) -> PlayerCheckPointData {
1082        let mut center_pos = Vector3::default();
1083        let mut radius = 0.0;
1084        checkpoints::functions::Checkpoint_Get(
1085            self,
1086            &mut center_pos.x,
1087            &mut center_pos.y,
1088            &mut center_pos.z,
1089            &mut radius,
1090        );
1091        PlayerCheckPointData::new(center_pos, radius)
1092    }
1093
1094    /// Check if the player currently has a race checkpoint visible.
1095    pub fn is_player_race_checkpoint_active(&self) -> bool {
1096        checkpoints::functions::RaceCheckpoint_IsActive(self)
1097    }
1098
1099    /// Get the location of the current race checkpoint.
1100    pub fn get_player_race_checkpoint(&self) -> PlayerRaceCheckPointData {
1101        let mut center_pos = Vector3::default();
1102        let mut next_pos = Vector3::default();
1103        let mut radius = 0.0;
1104        checkpoints::functions::RaceCheckpoint_Get(
1105            self,
1106            &mut center_pos.x,
1107            &mut center_pos.y,
1108            &mut center_pos.z,
1109            &mut next_pos.x,
1110            &mut next_pos.y,
1111            &mut next_pos.z,
1112            &mut radius,
1113        );
1114        PlayerRaceCheckPointData::new(center_pos, next_pos, radius)
1115    }
1116
1117    /// This function can be used to change the spawn information of a specific player.
1118    pub fn set_spawn_info(&self, player_class: PlayerClass) -> bool {
1119        functions::Player_SetSpawnInfo(
1120            self,
1121            player_class.team,
1122            player_class.skin,
1123            player_class.spawn.x,
1124            player_class.spawn.y,
1125            player_class.spawn.z,
1126            player_class.angle,
1127            player_class.weapons[0].id as u8,
1128            player_class.weapons[0].ammo,
1129            player_class.weapons[1].id as u8,
1130            player_class.weapons[1].ammo,
1131            player_class.weapons[2].id as u8,
1132            player_class.weapons[2].ammo,
1133        )
1134    }
1135
1136    /// Return the current spawn data for a player, where they will spawn next.
1137    pub fn get_spawn_info(&self) -> PlayerClass {
1138        let mut player_class = PlayerClass::default();
1139        let (mut weapon1, mut ammo1, mut weapon2, mut ammo2, mut weapon3, mut ammo3): (
1140            u8,
1141            u32,
1142            u8,
1143            u32,
1144            u8,
1145            u32,
1146        ) = (0, 0, 0, 0, 0, 0);
1147
1148        functions::Player_GetSpawnInfo(
1149            self,
1150            &mut player_class.team,
1151            &mut player_class.skin,
1152            &mut player_class.spawn.x,
1153            &mut player_class.spawn.y,
1154            &mut player_class.spawn.z,
1155            &mut player_class.angle,
1156            &mut weapon1,
1157            &mut ammo1,
1158            &mut weapon2,
1159            &mut ammo2,
1160            &mut weapon3,
1161            &mut ammo3,
1162        );
1163        player_class.weapons[0].id = unsafe { transmute(weapon1) };
1164        player_class.weapons[0].ammo = ammo1;
1165        player_class.weapons[1].id = unsafe { transmute(weapon2) };
1166        player_class.weapons[1].ammo = ammo2;
1167        player_class.weapons[2].id = unsafe { transmute(weapon3) };
1168        player_class.weapons[2].ammo = ammo3;
1169        player_class
1170    }
1171
1172    /// Shows the player a synchronous (only one at a time) dialog box.
1173    pub fn show_dialog(
1174        &self,
1175        dialog: i32,
1176        style: DialogStyle,
1177        title: &str,
1178        body: &str,
1179        button1: &str,
1180        button2: &str,
1181    ) -> bool {
1182        dialogs::functions::Dialog_Show(self, dialog, style as i32, title, body, button1, button2)
1183    }
1184
1185    /// Get the ID of the dialog currently show to the player.
1186    pub fn get_dialog_id(&self) -> i32 {
1187        functions::Player_GetDialog(self)
1188    }
1189
1190    /// Hides any dialog the player may currently be able to see.
1191    pub fn hide_dialog(&self) -> bool {
1192        dialogs::functions::Dialog_Hide(self)
1193    }
1194
1195    pub fn get_id(&self) -> i32 {
1196        functions::Player_GetID(self) as i32
1197    }
1198    pub fn from_id(playerid: i32) -> Option<Player> {
1199        functions::Player_FromID(playerid)
1200    }
1201    /// Gets the ID of the menu the player is currently viewing (shown by ShowMenuForPlayer).
1202    pub fn get_menu(&self) -> Option<Menu> {
1203        functions::Player_GetMenu(self)
1204    }
1205
1206    /// Allows a player to edit an object (position and rotation) using their mouse on a GUI (Graphical User Interface).
1207    pub fn edit_object(&self, object: &Object) -> bool {
1208        objects::functions::Object_BeginEditing(self, object)
1209    }
1210    /// Display the cursor and allow the player to select an object.
1211    pub fn select_object(&self) -> bool {
1212        objects::functions::Object_BeginSelecting(self)
1213    }
1214    /// Cancel object edition mode for a player.
1215    pub fn end_object_editing(&self) -> bool {
1216        objects::functions::Object_EndEditing(self)
1217    }
1218    /// Creates an object which will be visible to only one player.
1219    pub fn create_player_object(
1220        &self,
1221        modelid: i32,
1222        position: Vector3,
1223        rotation: Vector3,
1224        drawDistance: f32,
1225    ) -> Option<PlayerObject> {
1226        let mut _id = -1;
1227        objects::functions::PlayerObject_Create(
1228            self,
1229            modelid,
1230            position.x,
1231            position.y,
1232            position.z,
1233            rotation.x,
1234            rotation.y,
1235            rotation.z,
1236            drawDistance,
1237            &mut _id,
1238        )
1239    }
1240    /// Destroy a player-object created using CreatePlayerObject.
1241    pub fn destroy_player_object(&self, object: PlayerObject) -> bool {
1242        objects::functions::PlayerObject_Destroy(self, &object)
1243    }
1244    /// Allows players to edit a player-object (position and rotation) with a GUI and their mouse.
1245    pub fn edit_player_object(&self, object: &PlayerObject) -> bool {
1246        objects::functions::PlayerObject_BeginEditing(self, object)
1247    }
1248
1249    /// Get Object from an id
1250    pub fn get_player_object_from_id(&self, id: i32) -> Option<PlayerObject> {
1251        objects::functions::PlayerObject_FromID(self, id)
1252    }
1253
1254    /// Creates a textdraw for a single player.
1255    pub fn create_player_text_draw(&self, position: Vector2, text: &str) -> Option<PlayerTextDraw> {
1256        let mut _id = 0;
1257        textdraws::functions::PlayerTextDraw_Create(self, position.x, position.y, text, &mut _id)
1258    }
1259    /// Destroy a player-textdraw.
1260    pub fn player_text_draw_destroy(&self, textdraw: &PlayerTextDraw) -> bool {
1261        textdraws::functions::PlayerTextDraw_Destroy(self, textdraw)
1262    }
1263
1264    pub fn create_player_text_label_on_player(
1265        &self,
1266        attachedPlayer: &Player,
1267        text: &str,
1268        colour: Colour,
1269        position: Vector3,
1270        drawDistance: f32,
1271        los: bool,
1272    ) -> Option<PlayerTextLabel> {
1273        let mut _id = 0;
1274        textlabels::functions::PlayerTextLabel_Create(
1275            self,
1276            text,
1277            colour.rgba(),
1278            position.x,
1279            position.y,
1280            position.z,
1281            drawDistance,
1282            attachedPlayer,
1283            &Vehicle::new(std::ptr::null()),
1284            los,
1285            &mut _id,
1286        )
1287    }
1288    pub fn create_player_text_label_on_vehicle(
1289        &self,
1290        attachedVehicle: &Vehicle,
1291        text: &str,
1292        colour: Colour,
1293        position: Vector3,
1294        drawDistance: f32,
1295        los: bool,
1296    ) -> Option<PlayerTextLabel> {
1297        let mut _id = 0;
1298        textlabels::functions::PlayerTextLabel_Create(
1299            self,
1300            text,
1301            colour.rgba(),
1302            position.x,
1303            position.y,
1304            position.z,
1305            drawDistance,
1306            &Player::new(std::ptr::null()),
1307            attachedVehicle,
1308            los,
1309            &mut _id,
1310        )
1311    }
1312    /// Creates a 3D Text Label only for a specific player.
1313    pub fn create_player_text_label(
1314        &self,
1315        text: &str,
1316        colour: Colour,
1317        position: Vector3,
1318        drawDistance: f32,
1319        los: bool,
1320    ) -> Option<PlayerTextLabel> {
1321        let mut _id = 0;
1322        textlabels::functions::PlayerTextLabel_Create(
1323            self,
1324            text,
1325            colour.rgba(),
1326            position.x,
1327            position.y,
1328            position.z,
1329            drawDistance,
1330            &Player::new(std::ptr::null()),
1331            &Vehicle::new(std::ptr::null()),
1332            los,
1333            &mut _id,
1334        )
1335    }
1336    /// Destroy a 3D text label that was created using CreatePlayer3DTextLabel.
1337    pub fn delete_player_text_label(&self, textlabel: PlayerTextLabel) -> bool {
1338        textlabels::functions::PlayerTextLabel_Destroy(self, &textlabel)
1339    }
1340
1341    /// Check if the player is in the mod shop.
1342    pub fn is_player_in_mod_shop(&self) -> bool {
1343        functions::Player_IsInModShop(self)
1344    }
1345    /// Gets the siren state of the player's vehicle.
1346    pub fn get_player_siren_state(&self) -> i32 {
1347        functions::Player_GetSirenState(self)
1348    }
1349    /// Gets the landing gear state of the current player's vehicle.
1350    pub fn get_player_landing_gear_state(&self) -> i32 {
1351        functions::Player_GetLandingGearState(self)
1352    }
1353    /// Gets the hydra reactor angle of the player's vehicle.
1354    pub fn get_player_hydra_reactor_angle(&self) -> u32 {
1355        functions::Player_GetHydraReactorAngle(self)
1356    }
1357    /// Gets the speed of the player's train.
1358    pub fn get_player_train_speed(&self) -> f32 {
1359        functions::Player_GetTrainSpeed(self)
1360    }
1361
1362    /// Get a player's network stats.
1363    pub fn get_net_stats(&self) -> String {
1364        let mut output = String::new();
1365        functions::Player_GetNetworkStats(self, &mut output, 400);
1366        output
1367    }
1368
1369    /// Get a player's IP and port.
1370    pub fn net_stats_get_ip_port(&self) -> String {
1371        let mut output = String::new();
1372        functions::Player_NetStatsGetIpPort(self, &mut output, 22);
1373        output
1374    }
1375
1376    /* /// Sends a message in the name of a player to all other players on the server.
1377    pub fn send_message_to_all(&self, message: &str) -> bool {
1378        core::functions::All_SendClientMessage(self, message)
1379    } */
1380
1381    /// Attach an object to a specific bone on a player.
1382    pub fn set_attached_object(&self, index: i32, attachment: ObjectAttachmentSlotData) -> bool {
1383        functions::Player_SetAttachedObject(
1384            self,
1385            index,
1386            attachment.model,
1387            attachment.bone,
1388            attachment.offset.x,
1389            attachment.offset.y,
1390            attachment.offset.z,
1391            attachment.rotation.x,
1392            attachment.rotation.y,
1393            attachment.rotation.z,
1394            attachment.scale.x,
1395            attachment.scale.y,
1396            attachment.scale.z,
1397            attachment.colour1.argb(),
1398            attachment.colour2.argb(),
1399        )
1400    }
1401    /// Gets the player attachment object data by index.
1402    pub fn get_attached_object(&self, index: i32) -> ObjectAttachmentSlotData {
1403        let mut attachment = ObjectAttachmentSlotData::default();
1404        let mut colour1 = 0;
1405        let mut colour2 = 0;
1406        functions::Player_GetAttachedObject(
1407            self,
1408            index,
1409            &mut attachment.model,
1410            &mut attachment.bone,
1411            &mut attachment.offset.x,
1412            &mut attachment.offset.y,
1413            &mut attachment.offset.z,
1414            &mut attachment.rotation.x,
1415            &mut attachment.rotation.y,
1416            &mut attachment.rotation.z,
1417            &mut attachment.scale.x,
1418            &mut attachment.scale.y,
1419            &mut attachment.scale.z,
1420            &mut colour1,
1421            &mut colour2,
1422        );
1423        attachment.colour1 = Colour::from_argb(colour1 as u32);
1424        attachment.colour2 = Colour::from_argb(colour2 as u32);
1425
1426        attachment
1427    }
1428
1429    /// Check if the player is using the open.mp launcher
1430    pub fn is_using_omp(&self) -> bool {
1431        functions::Player_IsPlayerUsingOmp(self)
1432    }
1433
1434    fn defer_api_call(&self, callback: Box<dyn FnOnce(Self)>) {
1435        let player_id = self.get_id();
1436        queue_api_call(Box::new(move || {
1437            let player = match Self::from_id(player_id) {
1438                Some(player) => player,
1439                None => {
1440                    log::error!("player with id={player_id} not found");
1441                    return;
1442                }
1443            };
1444            callback(player);
1445        }));
1446    }
1447}
1448
1449/// Map Icon Styles
1450#[repr(C)]
1451#[derive(PartialEq, Clone, Copy, Debug)]
1452pub enum MapIconStyle {
1453    Local,
1454    Global,
1455    LocalCheckpoint,
1456    GlobalCheckpoint,
1457}
1458
1459/// Client Versions
1460#[repr(u8)]
1461#[derive(PartialEq, Clone, Copy, Debug)]
1462pub enum ClientVersion {
1463    Samp037,
1464    Samp03dl,
1465    Openmp,
1466}
1467
1468/// Camera Cut Types
1469#[repr(C)]
1470#[derive(PartialEq, Clone, Copy, Debug)]
1471pub enum PlayerCameraCutType {
1472    Cut,
1473    Move,
1474}
1475
1476/// The player's name status returned when updating their name
1477#[repr(C)]
1478#[derive(PartialEq, Clone, Copy, Debug)]
1479pub enum PlayerNameStatus {
1480    /// The name has successfully been updated
1481    Updated,
1482    /// The name is already taken by another player
1483    Taken,
1484    /// The name is invalid
1485    Invalid,
1486}
1487
1488impl From<i32> for PlayerNameStatus {
1489    fn from(value: i32) -> Self {
1490        match value {
1491            0 => PlayerNameStatus::Updated,
1492            1 => PlayerNameStatus::Taken,
1493            _ => PlayerNameStatus::Invalid,
1494        }
1495    }
1496}
1497/// Animation sync type
1498#[repr(C)]
1499#[derive(PartialEq, Clone, Copy, Debug)]
1500pub enum PlayerAnimationSyncType {
1501    /// No sync
1502    NoSync,
1503    // Make server sync the animation with all other players in streaming radius
1504    Sync,
1505    /// works same as Sync, but will ONLY apply the animation to streamed-in players, but NOT the actual player being animated (useful for npc animations and persistent animations when players are being streamed)
1506    SyncOthers,
1507}
1508
1509/// Weapon Information
1510#[repr(C)]
1511#[derive(Default, Clone, Copy, Debug)]
1512pub struct WeaponSlotData {
1513    /// weapon id
1514    pub id: PlayerWeapon,
1515    /// amount of ammunition
1516    pub ammo: u32,
1517}
1518
1519impl WeaponSlotData {
1520    pub fn new(id: PlayerWeapon, ammo: u32) -> Self {
1521        Self { id, ammo }
1522    }
1523}
1524
1525/// Animation Data Of Player
1526#[repr(C)]
1527#[derive(PartialEq, Clone, Copy, Debug)]
1528pub struct PlayerAnimationData {
1529    pub id: u16,
1530    /// Animation flags
1531    /// FREEZE_FLAG -> 0b0000000000000100
1532    /// LOCK_X_FLAG -> 0b0010000000000
1533    /// LOCK_Y_FLAG -> 0b0001000000000
1534    /// LOOP_FLAG -> 0b0000100000000
1535    pub flags: u16,
1536}
1537
1538/// Player's Fighting Style
1539#[repr(C)]
1540#[derive(PartialEq, Clone, Copy, Debug)]
1541pub enum PlayerFightingStyle {
1542    Normal = 4,
1543    Boxing = 5,
1544    KungFu = 6,
1545    KneeHead = 7,
1546    GrabKick = 15,
1547    Elbow = 16,
1548}
1549
1550/// State of the player
1551#[repr(C)]
1552#[derive(PartialEq, Clone, Copy, Debug)]
1553pub enum PlayerState {
1554    None = 0,
1555    OnFoot = 1,
1556    Driver = 2,
1557    Passenger = 3,
1558    ExitVehicle = 4,
1559    EnterVehicleDriver = 5,
1560    EnterVehiclePassenger = 6,
1561    Wasted = 7,
1562    Spawned = 8,
1563    Spectating = 9,
1564}
1565
1566impl From<i32> for PlayerState {
1567    fn from(value: i32) -> Self {
1568        match value {
1569            1 => PlayerState::OnFoot,
1570            2 => PlayerState::Driver,
1571            3 => PlayerState::Passenger,
1572            4 => PlayerState::ExitVehicle,
1573            5 => PlayerState::EnterVehicleDriver,
1574            6 => PlayerState::EnterVehiclePassenger,
1575            7 => PlayerState::Wasted,
1576            8 => PlayerState::Spawned,
1577            9 => PlayerState::Spectating,
1578            _ => PlayerState::None,
1579        }
1580    }
1581}
1582
1583/// a list of valid weapon skill types used by set_skill_level and get_skill_level methods
1584#[repr(C)]
1585#[derive(PartialEq, Clone, Copy, Debug)]
1586pub enum PlayerWeaponSkill {
1587    Pistol,
1588    SilencedPistol,
1589    DesertEagle,
1590    Shotgun,
1591    SawnOff,
1592    Spas12,
1593    Uzi,
1594    Mp5,
1595    Ak47,
1596    M4,
1597    Sniper,
1598}
1599
1600/// list of all the player special actions
1601#[repr(C)]
1602#[derive(PartialEq, Clone, Copy, Debug)]
1603pub enum PlayerSpecialAction {
1604    /// Clears player of special actions
1605    None,
1606    /// Detect if the player is crouching.
1607    Duck,
1608    /// Will make the player using jetpack
1609    Jetpack,
1610    /// Detect if the player is entering a vehicle via an animation.
1611    EnterVehicle,
1612    /// Detect if the player is exiting a vehicle via an animation.
1613    ExitVehicle,
1614    /// Applies dancing animation for player
1615    Dance1,
1616    /// Applies dancing animation for player
1617    Dance2,
1618    /// Applies dancing animation for player
1619    Dance3,
1620    /// Applies dancing animation for player
1621    Dance4,
1622    /// Will make the player put hands up
1623    HandsUp = 10,
1624    /// Will make the player speaking on cellphone
1625    Cellphone,
1626    /// Detects if the player is sitting
1627    Sitting,
1628    /// Makes players stop using cellphone
1629    StopCellphone,
1630    /// Will increase the player's drunk level when used
1631    Beer = 20,
1632    /// Will give the player a cigar.
1633    Smoke,
1634    /// Will give the player a wine bottle to get drunk from
1635    Wine,
1636    /// Will give the player a sprunk bottle to drink from
1637    Sprunk,
1638    /// Will force the player in to cuffs (hands are behind their back) (does not work on CJ skin).
1639    Cuffed,
1640    /// Will apply a 'carrying' animation to the player and make them unable to sprint, jump or punch (does not work on CJ skin).
1641    Carry,
1642    /// Will make the player perform the pissing animation with visible pee
1643    Pissing = 68,
1644}
1645
1646/// Player surfing information
1647#[repr(C)]
1648#[derive(PartialEq, Clone, Copy, Debug)]
1649pub struct PlayerSurfingData {
1650    pub surftype: i32,
1651    pub id: i32,
1652    pub offset: Vector3,
1653}
1654
1655#[repr(C)]
1656#[derive(PartialEq, Clone, Copy, Debug)]
1657pub struct PlayerKeyData {
1658    pub keys: u32,
1659    pub upDown: i16,
1660    pub leftRight: i16,
1661}
1662
1663#[repr(C)]
1664#[derive(PartialEq, Clone, Copy, Debug, Default)]
1665pub struct PlayerBulletData {
1666    pub origin: Vector3,
1667    pub hitPos: Vector3,
1668    pub offset: Vector3,
1669    pub weapon: PlayerWeapon,
1670    pub hitType: PlayerBulletHitType,
1671    pub hitID: u16,
1672}
1673#[repr(C)]
1674#[derive(PartialEq, Clone, Copy, Debug, Default)]
1675pub enum PlayerBulletHitType {
1676    #[default]
1677    None,
1678    Player = 1,
1679    Vehicle = 2,
1680    Object = 3,
1681    PlayerObject = 4,
1682}
1683
1684#[repr(C)]
1685#[derive(PartialEq, Clone, Copy, Debug)]
1686pub enum SpectateType {
1687    None,
1688    Vehicle,
1689    Player,
1690}
1691
1692#[repr(C)]
1693#[derive(PartialEq, Clone, Copy, Debug)]
1694pub struct PlayerSpectateData {
1695    pub spectating: bool,
1696    pub spectateID: i32,
1697    pub spectate_type: SpectateType,
1698}
1699
1700#[repr(C)]
1701#[derive(PartialEq, Clone, Copy, Debug)]
1702pub enum PlayerSpectateMode {
1703    Normal = 1,
1704    Fixed,
1705    Side,
1706}
1707
1708#[repr(C)]
1709#[derive(PartialEq, Clone, Copy, Debug)]
1710pub struct PlayerAimData {
1711    pub camFrontVector: Vector3,
1712    pub camPos: Vector3,
1713    pub aimZ: f32,
1714    pub camZoom: f32,
1715    pub aspectRatio: f32,
1716    pub weaponState: PlayerWeaponState,
1717    pub camMode: u8,
1718}
1719
1720#[repr(C)]
1721#[derive(PartialEq, Clone, Copy, Debug)]
1722pub enum PlayerWeaponState {
1723    Unknown = -1,
1724    NoBullets,
1725    LastBullet,
1726    MoreBullets,
1727    Reloading,
1728}
1729
1730#[repr(C)]
1731#[derive(PartialEq, Clone, Copy, Debug)]
1732pub enum BodyPart {
1733    Torso = 3,
1734    Groin,
1735    LeftArm,
1736    RightArm,
1737    LeftLeg,
1738    RightLeg,
1739    Head,
1740}
1741
1742#[repr(C)]
1743#[derive(PartialEq, Clone, Copy, Debug)]
1744pub enum PlayerClickSource {
1745    Scoreboard,
1746}
1747
1748pub type WeaponSlots = StaticArray<WeaponSlotData, 13>;
1749
1750#[repr(u8)]
1751#[derive(PartialEq, Copy, Clone, Default, Debug)]
1752pub enum PlayerWeapon {
1753    #[default]
1754    Fist,
1755    BrassKnuckle,
1756    GolfClub,
1757    NiteStick,
1758    Knife,
1759    Bat,
1760    Shovel,
1761    PoolStick,
1762    Katana,
1763    Chainsaw,
1764    Dildo,
1765    Dildo2,
1766    Vibrator,
1767    Vibrator2,
1768    Flower,
1769    Cane,
1770    Grenade,
1771    Teargas,
1772    Moltov,
1773    Colt45 = 22,
1774    Silenced,
1775    Deagle,
1776    Shotgun,
1777    Sawedoff,
1778    Shotgspa,
1779    UZI,
1780    MP5,
1781    AK47,
1782    M4,
1783    TEC9,
1784    Rifle,
1785    Sniper,
1786    RocketLauncher,
1787    HeatSeeker,
1788    FlameThrower,
1789    Minigun,
1790    Satchel,
1791    Bomb,
1792    SprayCan,
1793    FireExtinguisher,
1794    Camera,
1795    NightVisGoggles,
1796    ThermalGoggles,
1797    Parachute,
1798    Vehicle = 49,
1799    Heliblades,
1800    Explosion,
1801    Drown = 53,
1802    Collision,
1803    End,
1804    Connect = 200,
1805    Disconnect,
1806    Suicide = 255,
1807}
1808
1809/// Player Keys
1810pub mod PlayerKeys {
1811    pub const ACTION: u32 = 1;
1812    pub const CROUCH: u32 = 2;
1813    pub const FIRE: u32 = 4;
1814    pub const SPRINT: u32 = 8;
1815    pub const SECONDARY_ATTACK: u32 = 16;
1816    pub const JUMP: u32 = 32;
1817    pub const LOOK_RIGHT: u32 = 64;
1818    pub const HANDBRAKE: u32 = 128;
1819    pub const LOOK_LEFT: u32 = 256;
1820    pub const SUBMISSION: u32 = 512;
1821    pub const LOOK_BEHIND: u32 = 512;
1822    pub const WALK: u32 = 1024;
1823    pub const ANALOG_UP: u32 = 2048;
1824    pub const ANALOG_DOWN: u32 = 4096;
1825    pub const ANALOG_LEFT: u32 = 8192;
1826    pub const ANALOG_RIGHT: u32 = 16384;
1827    pub const YES: u32 = 65536;
1828    pub const NO: u32 = 131072;
1829    pub const CTRL_BACK: u32 = 262144;
1830    pub const UP: i32 = -128;
1831    pub const DOWN: i32 = 128;
1832    pub const LEFT: i32 = -128;
1833    pub const RIGHT: i32 = 128;
1834}