From 3c089e2c472bc07583008cd82842de440a6d3284 Mon Sep 17 00:00:00 2001 From: Sardelka Date: Mon, 15 Aug 2022 19:39:36 +0800 Subject: [PATCH] Fix looking coordinate in first person --- RageCoop.Client/Main.cs | 2 + .../Sync/Entities/Ped/SyncedPed.cs | 34 +++---- RageCoop.Client/Util/PedExtensions.cs | 97 ++++++++++++++++++- RageCoop.Core/MathExtensions.cs | 15 +++ 4 files changed, 123 insertions(+), 25 deletions(-) diff --git a/RageCoop.Client/Main.cs b/RageCoop.Client/Main.cs index d2b35c6..9574659 100644 --- a/RageCoop.Client/Main.cs +++ b/RageCoop.Client/Main.cs @@ -113,6 +113,8 @@ namespace RageCoop.Client P= Game.Player.Character; PlayerPosition=P.ReadPosition(); FPS=Game.FPS; + World.DrawMarker(MarkerType.DebugSphere, PedExtensions.RaycastEverything(default), default, default, new Vector3(0.2f, 0.2f, 0.2f), Color.AliceBlue); + /* try { diff --git a/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs b/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs index 7e73819..ca0222b 100644 --- a/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs +++ b/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs @@ -89,6 +89,7 @@ namespace RageCoop.Client internal PedDataFlags Flags; internal bool IsAiming => Flags.HasPedFlag(PedDataFlags.IsAiming); + internal bool _lastDriveBy; internal bool IsReloading => Flags.HasPedFlag(PedDataFlags.IsReloading); internal bool IsJumping => Flags.HasPedFlag(PedDataFlags.IsJumping); internal bool IsRagdoll => Flags.HasPedFlag(PedDataFlags.IsRagdoll); @@ -758,31 +759,24 @@ namespace RageCoop.Client // World.DrawMarker(MarkerType.DebugSphere,AimCoords,default,default,new Vector3(0.2f,0.2f,0.2f),Color.AliceBlue); CheckCurrentWeapon(); if (IsAiming) + { + Function.Call(Hash.SET_DRIVEBY_TASK_TARGET, MainPed, 0, 0, AimCoords.X, AimCoords.Y, AimCoords.Z); + if (!_lastDriveBy) + { + _lastDriveBy=true; + Function.Call(Hash.TASK_DRIVE_BY, MainPed, 0, 0, AimCoords.X, AimCoords.Y, AimCoords.Z, 1, 100, 1, FiringPattern.SingleShot); + } + } + else { if (MainPed.IsTaskActive(TaskType.CTaskAimGunVehicleDriveBy)) { - - Function.Call(Hash.SET_DRIVEBY_TASK_TARGET, MainPed , 0, 0, AimCoords.X, AimCoords.Y, AimCoords.Z); - } - else - { - Function.Call(Hash.SET_PED_INFINITE_AMMO_CLIP, MainPed, true); - /* - Main.QueueAction(() => - { - if (!IsAiming) { return true; } - Function.Call(Hash.SET_PED_AMMO, MainPed, CurrentWeaponHash, 0); - return false; - }); - */ - Function.Call(Hash.TASK_DRIVE_BY, MainPed, 0, 0, AimCoords.X, AimCoords.Y, AimCoords.Z, 1, 100, 1,FiringPattern.SingleShot); + + MainPed.Task.ClearAll(); } + _lastDriveBy=false; } - else if (MainPed.IsTaskActive(TaskType.CTaskAimGunVehicleDriveBy)) - { - MainPed.Task.ClearAll(); - } - + } else if (MainPed.VehicleWeapon!=(VehicleWeaponHash)CurrentWeaponHash) { diff --git a/RageCoop.Client/Util/PedExtensions.cs b/RageCoop.Client/Util/PedExtensions.cs index b560a48..5366a3d 100644 --- a/RageCoop.Client/Util/PedExtensions.cs +++ b/RageCoop.Client/Util/PedExtensions.cs @@ -3,6 +3,7 @@ using GTA.Math; using GTA.Native; using RageCoop.Core; using System.Collections.Generic; +using System; namespace RageCoop.Client { @@ -340,15 +341,14 @@ namespace RageCoop.Client } public static Vector3 GetLookingCoord(this Ped p) { + if (p==Main.P && Function.Call(Hash.GET_FOLLOW_PED_CAM_VIEW_MODE)==4) + { + return RaycastEverything(default); + } EntityBone b = p.Bones[Bone.FacialForehead]; Vector3 v = b.UpVector.Normalized; return b.Position+200*v; } - - public static void StayInCover(this Ped p) - { - Function.Call(Hash.TASK_STAY_IN_COVER, p); - } public static VehicleSeat GetSeatTryingToEnter(this Ped p) { return (VehicleSeat)Function.Call(Hash.GET_SEAT_PED_IS_TRYING_TO_ENTER, p); @@ -363,6 +363,93 @@ namespace RageCoop.Client + public static Vector3 RaycastEverything(Vector2 screenCoord) + { + Vector3 camPos = GameplayCamera.Position; + Vector3 camRot = GameplayCamera.Rotation; + const float raycastToDist = 100.0f; + const float raycastFromDist = 1f; + + Vector3 target3D = ScreenRelToWorld(camPos, camRot, screenCoord); + Vector3 source3D = camPos; + + Entity ignoreEntity = Game.Player.Character; + if (Game.Player.Character.IsInVehicle()) + { + ignoreEntity = Game.Player.Character.CurrentVehicle; + } + + Vector3 dir = target3D - source3D; + dir.Normalize(); + RaycastResult raycastResults = World.Raycast(source3D + dir * raycastFromDist, + source3D + dir * raycastToDist, + IntersectFlags.Everything, + ignoreEntity); + + if (raycastResults.DidHit) + { + return raycastResults.HitPosition; + } + + return camPos + dir * raycastToDist; + } + public static Vector3 ScreenRelToWorld(Vector3 camPos, Vector3 camRot, Vector2 coord) + { + Vector3 camForward = camRot.ToDirection(); + Vector3 rotUp = camRot + new Vector3(10, 0, 0); + Vector3 rotDown = camRot + new Vector3(-10, 0, 0); + Vector3 rotLeft = camRot + new Vector3(0, 0, -10); + Vector3 rotRight = camRot + new Vector3(0, 0, 10); + + Vector3 camRight = rotRight.ToDirection() - rotLeft.ToDirection(); + Vector3 camUp = rotUp.ToDirection() - rotDown.ToDirection(); + + double rollRad = -camRot.Y.ToRadians(); + + Vector3 camRightRoll = camRight * (float)Math.Cos(rollRad) - camUp * (float)Math.Sin(rollRad); + Vector3 camUpRoll = camRight * (float)Math.Sin(rollRad) + camUp * (float)Math.Cos(rollRad); + + Vector3 point3D = camPos + camForward * 10.0f + camRightRoll + camUpRoll; + if (!WorldToScreenRel(point3D, out Vector2 point2D)) + { + return camPos + camForward * 10.0f; + } + + Vector3 point3DZero = camPos + camForward * 10.0f; + if (!WorldToScreenRel(point3DZero, out Vector2 point2DZero)) + { + return camPos + camForward * 10.0f; + } + + const double eps = 0.001; + if (Math.Abs(point2D.X - point2DZero.X) < eps || Math.Abs(point2D.Y - point2DZero.Y) < eps) + { + return camPos + camForward * 10.0f; + } + + float scaleX = (coord.X - point2DZero.X) / (point2D.X - point2DZero.X); + float scaleY = (coord.Y - point2DZero.Y) / (point2D.Y - point2DZero.Y); + + return camPos + camForward * 10.0f + camRightRoll * scaleX + camUpRoll * scaleY; + } + public static bool WorldToScreenRel(Vector3 worldCoords, out Vector2 screenCoords) + { + OutputArgument num1 = new OutputArgument(); + OutputArgument num2 = new OutputArgument(); + + if (!Function.Call(Hash.GET_SCREEN_COORD_FROM_WORLD_COORD, worldCoords.X, worldCoords.Y, worldCoords.Z, num1, num2)) + { + screenCoords = new Vector2(); + return false; + } + + screenCoords = new Vector2((num1.GetResult() - 0.5f) * 2, (num2.GetResult() - 0.5f) * 2); + return true; + } + public static void StayInCover(this Ped p) + { + Function.Call(Hash.TASK_STAY_IN_COVER, p); + } public static bool IsTurretSeat(this Vehicle veh, int seat) { diff --git a/RageCoop.Core/MathExtensions.cs b/RageCoop.Core/MathExtensions.cs index 75f58d6..c10d150 100644 --- a/RageCoop.Core/MathExtensions.cs +++ b/RageCoop.Core/MathExtensions.cs @@ -8,6 +8,21 @@ namespace RageCoop.Core { public const float Deg2Rad=(float)(Math.PI* 2) / 360; public const float Rad2Deg = 360 / (float)(Math.PI * 2); + + public static Vector3 ToDirection(this Vector3 rotation) + { + double z = DegToRad(rotation.Z); + double x = DegToRad(rotation.X); + double num = Math.Abs(Math.Cos(x)); + + return new Vector3 + { + X = (float)(-Math.Sin(z) * num), + Y = (float)(Math.Cos(z) * num), + Z = (float)Math.Sin(x) + }; + } + /// /// ///