From 91053f016202218177aaa98df5ed90bad6888c22 Mon Sep 17 00:00:00 2001 From: blattersturm Date: Sun, 12 Sep 2021 11:45:54 +0200 Subject: [PATCH] Fix faraway spectate teleporting/GPS routes --- vMenu/CommonFunctions.cs | 39 ++++++++++++++++++++++- vMenu/FunctionsController.cs | 22 ++++++++++--- vMenu/menus/OnlinePlayers.cs | 60 ++++++++++++++++++++++++++---------- 3 files changed, 99 insertions(+), 22 deletions(-) diff --git a/vMenu/CommonFunctions.cs b/vMenu/CommonFunctions.cs index 6d789ac5..7c8a627c 100644 --- a/vMenu/CommonFunctions.cs +++ b/vMenu/CommonFunctions.cs @@ -950,9 +950,39 @@ public static async void SpectatePlayer(IPlayer player, bool forceDisable = fals } else { + Camera camera = null; + if (!player.IsActive) { - await TeleportToPlayer(player); + // get the player position and make a cam to ensure they load in + var playerPos = await MainMenu.RequestPlayerCoordinates(player.ServerId); + + DoScreenFadeOut(500); + while (IsScreenFadingOut()) await Delay(0); + + camera = new Camera(CreateCam("DEFAULT_SCRIPTED_CAMERA", false)); + camera.Position = playerPos + new Vector3(0, -5, 0); + camera.PointAt(playerPos); + World.RenderingCamera = camera; + + // wait for the player to become active + var timeout = GetGameTimer() + 1000; + while (!player.IsActive || player.Character == null) + { + await Delay(0); + World.RenderingCamera = camera; + + if (GetGameTimer() > timeout) + { + break; + } + } + + // fade back in if the player wasn't active + if (!player.IsActive) + { + DoScreenFadeIn(500); + } } if (player.Handle == Game.Player.Handle) @@ -1019,6 +1049,13 @@ public static async void SpectatePlayer(IPlayer player, bool forceDisable = fals } } } + + if (camera != null) + { + // unset the camera + camera.Delete(); + World.RenderingCamera = null; + } } } #endregion diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index d7d86b35..425f160c 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -2216,7 +2216,7 @@ private async Task PlayerBlipsControl() } else // blips are not enabled. { - if (!(p.Character.AttachedBlip == null || !p.Character.AttachedBlip.Exists()) && MainMenu.OnlinePlayersMenu != null && !MainMenu.OnlinePlayersMenu.PlayersWaypointList.Contains(p.Handle)) + if (!(p.Character.AttachedBlip == null || !p.Character.AttachedBlip.Exists()) && MainMenu.OnlinePlayersMenu != null && !MainMenu.OnlinePlayersMenu.PlayersWaypointList.Contains(p.ServerId)) { p.Character.AttachedBlip.Delete(); // remove player blip if it exists. } @@ -2329,14 +2329,17 @@ private async Task OnlinePlayersTasks() await Delay(500); if (MainMenu.OnlinePlayersMenu.PlayersWaypointList.Count > 0) { - foreach (int playerId in MainMenu.OnlinePlayersMenu.PlayersWaypointList) + foreach (int serverId in MainMenu.OnlinePlayersMenu.PlayersWaypointList) { - if (!NetworkIsPlayerActive(playerId)) + var player = MainMenu.PlayersList.FirstOrDefault(a => a.ServerId == serverId); + + if (player == null) { - waypointPlayerIdsToRemove.Add(playerId); + waypointPlayerIdsToRemove.Add(serverId); } - else + else if (player.Character != null) { + var playerId = player.Handle; Vector3 pos1 = GetEntityCoords(GetPlayerPed(playerId), true); Vector3 pos2 = Game.PlayerPed.Position; if (Vdist2(pos1.X, pos1.Y, pos1.Z, pos2.X, pos2.Y, pos2.Z) < 20f) @@ -2357,6 +2360,15 @@ private async Task OnlinePlayersTasks() { foreach (int id in waypointPlayerIdsToRemove) { + if (MainMenu.OnlinePlayersMenu.PlayerCoordWaypoints.TryGetValue(id, out var blip)) + { + if (DoesBlipExist(blip)) + { + SetBlipRoute(blip, false); + RemoveBlip(ref blip); + } + } + MainMenu.OnlinePlayersMenu.PlayersWaypointList.Remove(id); } await Delay(10); diff --git a/vMenu/menus/OnlinePlayers.cs b/vMenu/menus/OnlinePlayers.cs index a9e6e711..9c920bf8 100644 --- a/vMenu/menus/OnlinePlayers.cs +++ b/vMenu/menus/OnlinePlayers.cs @@ -16,6 +16,7 @@ namespace vMenuClient public class OnlinePlayers { public List PlayersWaypointList = new List(); + public Dictionary PlayerCoordWaypoints = new Dictionary(); // Menu variable, will be defined in CreateMenu() private Menu menu; @@ -39,8 +40,8 @@ private void CreateMenu() MenuItem teleport = new MenuItem("Teleport To Player", "Teleport to this player."); MenuItem teleportVeh = new MenuItem("Teleport Into Player Vehicle", "Teleport into the vehicle of the player."); MenuItem summon = new MenuItem("Summon Player", "Teleport the player to you."); - MenuItem toggleGPS = new MenuItem("Toggle GPS", "Enables or disables the GPS route on your radar to this player. ~y~Note for when the server is using OneSync Infinity: this may not work if the player is too far away."); - MenuItem spectate = new MenuItem("Spectate Player", "Spectate this player. Click this button again to stop spectating. ~y~Note for when the server is using OneSync Infinity: You will be teleported to the player if you're too far away, you might want to go into noclip to become invisible, before using this option!"); + MenuItem toggleGPS = new MenuItem("Toggle GPS", "Enables or disables the GPS route on your radar to this player."); + MenuItem spectate = new MenuItem("Spectate Player", "Spectate this player. Click this button again to stop spectating."); MenuItem printIdentifiers = new MenuItem("Print Identifiers", "This will print the player's identifiers to the client console (F8). And also save it to the CitizenFX.log file."); MenuItem kill = new MenuItem("~r~Kill Player", "Kill this player, note they will receive a notification saying that you killed them. It will also be logged in the Staff Actions log."); MenuItem kick = new MenuItem("~r~Kick Player", "Kick the player from the server."); @@ -157,12 +158,29 @@ private void CreateMenu() bool selectedPedRouteAlreadyActive = false; if (PlayersWaypointList.Count > 0) { - if (PlayersWaypointList.Contains(currentPlayer.Handle)) + if (PlayersWaypointList.Contains(currentPlayer.ServerId)) { selectedPedRouteAlreadyActive = true; } - foreach (int playerId in PlayersWaypointList) + foreach (int serverId in PlayersWaypointList) { + // remove any coord blip + if (PlayerCoordWaypoints.TryGetValue(serverId, out var wp)) + { + SetBlipRoute(wp, false); + RemoveBlip(ref wp); + + PlayerCoordWaypoints.Remove(serverId); + } + + // remove any entity blip + int playerId = GetPlayerFromServerId(serverId); + + if (playerId < 0) + { + continue; + } + int playerPed = GetPlayerPed(playerId); if (DoesEntityExist(playerPed) && DoesBlipExist(GetBlipFromEntity(playerPed))) { @@ -177,24 +195,34 @@ private void CreateMenu() if (!selectedPedRouteAlreadyActive) { - if (currentPlayer.Handle != Game.Player.Handle) + if (currentPlayer.ServerId != Game.Player.ServerId) { - int ped = GetPlayerPed(currentPlayer.Handle); - int blip = GetBlipFromEntity(ped); - if (DoesBlipExist(blip)) + int blip; + + if (currentPlayer.IsActive && currentPlayer.Character != null) { - SetBlipColour(blip, 58); - SetBlipRouteColour(blip, 58); - SetBlipRoute(blip, true); + int ped = GetPlayerPed(currentPlayer.Handle); + blip = GetBlipFromEntity(ped); + if (!DoesBlipExist(blip)) + { + blip = AddBlipForEntity(ped); + } } else { - blip = AddBlipForEntity(ped); - SetBlipColour(blip, 58); - SetBlipRouteColour(blip, 58); - SetBlipRoute(blip, true); + if (!PlayerCoordWaypoints.TryGetValue(currentPlayer.ServerId, out blip)) + { + var coords = await MainMenu.RequestPlayerCoordinates(currentPlayer.ServerId); + blip = AddBlipForCoord(coords.X, coords.Y, coords.Z); + PlayerCoordWaypoints[currentPlayer.ServerId] = blip; + } } - PlayersWaypointList.Add(currentPlayer.Handle); + + SetBlipColour(blip, 58); + SetBlipRouteColour(blip, 58); + SetBlipRoute(blip, true); + + PlayersWaypointList.Add(currentPlayer.ServerId); Notify.Custom($"~g~GPS route to ~s~{GetSafePlayerName(currentPlayer.Name)}~g~ is now active, press the ~s~Toggle GPS Route~g~ button again to disable the route."); } else