Exemplo n.º 1
0
        /// <summary>
        /// Because HitPosition and SurfaceNormal are currently broken in platform function
        /// </summary>
        /// <returns></returns>
        public static _RaycastResult CrosshairRaycast(Entity ignore, float distance = 1000f)
        {
            try
            {
                // Uncomment these to potentially save on raycasts (don't think they're ridiculously costly, but there's a # limit per tick)
                //if(CrosshairRaycastThisTick != null && distance == 1000f) return (_RaycastResult) CrosshairRaycastThisTick;

                Vector3        start         = CitizenFX.Core.GameplayCamera.Position;
                Vector3        end           = CitizenFX.Core.GameplayCamera.Position + distance * GameplayCamForwardVector();
                int            raycastHandle = Function.Call <int>(Hash._START_SHAPE_TEST_RAY, start.X, start.Y, start.Z, end.X, end.Y, end.Z, IntersectOptions.Everything, ignore.Handle, 0);
                OutputArgument DitHit        = new OutputArgument();
                OutputArgument HitPosition   = new OutputArgument();
                OutputArgument SurfaceNormal = new OutputArgument();
                OutputArgument HitEntity     = new OutputArgument();
                Function.Call <int>(Hash.GET_SHAPE_TEST_RESULT, raycastHandle, DitHit, HitPosition, SurfaceNormal, HitEntity);

                var result = new _RaycastResult(DitHit.GetResult <bool>(), HitPosition.GetResult <Vector3>(), SurfaceNormal.GetResult <Vector3>(), HitEntity.GetResult <int>(), raycastHandle);

                //if(distance == 1000f) CrosshairRaycastThisTick = result;
                return(result);
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
            return(default(_RaycastResult));
        }
Exemplo n.º 2
0
        public static void Render()
        {
            if (CinematicMode.DoHideHud)
            {
                return;
            }

            float row = 0.027f;

            if (DevCommands.IsDevEntityUIEnabled && !disableEntityUI)
            {
                row += 0.04f;

                _RaycastResult raycast = WorldProbe.CrosshairRaycast();
                if (!ReferenceEquals(raycast, null) && !ReferenceEquals(raycast.DitHit, null) && raycast.DitHit)
                {
                    World.DrawLine(CitizenFX.Core.GameplayCamera.Position, raycast.HitPosition, System.Drawing.Color.FromArgb(255, 0, 0));
                    World.DrawLine(raycast.HitPosition, raycast.HitPosition + 1000 * raycast.SurfaceNormal, System.Drawing.Color.FromArgb(0, 255, 0));
                    DrawText($"Pos: {String.Join(" ", raycast.HitPosition.ToArray().Select(f => $"{f,6:0.000}"))}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    row += 0.02f;
                    DrawText($"Normal: {String.Join(" ", raycast.SurfaceNormal.ToArray().Select(f => $"{f,6:0.000}")).ToString()}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                }
                else
                {
                    DrawText($"Hit: false", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    World.DrawLine(CitizenFX.Core.GameplayCamera.Position, CitizenFX.Core.GameplayCamera.Position + 1000 * WorldProbe.GameplayCamForwardVector(), System.Drawing.Color.FromArgb(255, 0, 0));
                }
                row += 0.02f;
                if (!ReferenceEquals(raycast, null) && !ReferenceEquals(raycast.DitHitEntity, null) && !ReferenceEquals(raycast.HitEntity, null) && !ReferenceEquals(raycast.HitEntity.Handle, null) && raycast.DitHitEntity)
                {
                    DrawText($"Ent ID: {raycast.HitEntity.Handle}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    string type = WorldProbe.GetEntityType(raycast.HitEntity.Handle);
                    DrawText($"Type: {type}", 0, false, 0.84f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"MISSION: {Function.Call<bool>(Hash.IS_ENTITY_A_MISSION_ENTITY, raycast.HitEntity.Handle)}", 0, false, 0.89f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"isNet: {Function.Call<bool>(Hash.NETWORK_GET_ENTITY_IS_NETWORKED, raycast.HitEntity.Handle)}", 0, false, 0.95f, row, 0.25f, 255, 255, 255, 255);
                    row += 0.02f;

                    DrawText($"hasNETID: {Function.Call<bool>(Hash.NETWORK_GET_NETWORK_ID_FROM_ENTITY, raycast.HitEntity.Handle)}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"NETID: {Function.Call<int>(Hash.NETWORK_GET_NETWORK_ID_FROM_ENTITY, raycast.HitEntity.Handle)}", 0, false, 0.84f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"EntCtr: {Function.Call<bool>(Hash.NETWORK_HAS_CONTROL_OF_ENTITY, raycast.HitEntity.Handle)}", 0, false, 0.90f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"isLoc: {Function.Call<bool>(Hash.NETWORK_GET_ENTITY_IS_LOCAL, raycast.HitEntity.Handle)}", 0, false, 0.95f, row, 0.25f, 255, 255, 255, 255);
                    row += 0.02f;
                    DrawText($"NETID to ENTID: {Function.Call<int>(Hash.NETWORK_GET_ENTITY_FROM_NETWORK_ID, Function.Call<int>(Hash.NETWORK_GET_NETWORK_ID_FROM_ENTITY, raycast.HitEntity.Handle))} (Broken)", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"NETIDCtr: {Function.Call<bool>(Hash.NETWORK_HAS_CONTROL_OF_NETWORK_ID, Function.Call<int>(Hash.NETWORK_GET_NETWORK_ID_FROM_ENTITY, raycast.HitEntity.Handle))}", 0, false, 0.88f, row, 0.25f, 255, 255, 255, 255);
                    row += 0.02f;

                    bool decorTestExists = Function.Call <bool>(Hash.DECOR_EXIST_ON, raycast.HitEntity.Handle, "TEST");
                    DrawText($"Decor TEST exists: {decorTestExists}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    if (decorTestExists)
                    {
                        DrawText($"TEST: {Function.Call<int>(Hash.DECOR_GET_INT, raycast.HitEntity.Handle, "TEST")}", 0, false, 0.90f, row, 0.25f, 255, 255, 255, 255);
                    }
                    row += 0.02f;

                    Vector3 coords = Function.Call <Vector3>(Hash.GET_ENTITY_COORDS, raycast.HitEntity.Handle);
                    DrawText($"x: {coords.X:0.000}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"y: {coords.Y:0.000}", 0, false, 0.85f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"z: {coords.Z:0.000}", 0, false, 0.90f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"h: {Function.Call<float>(Hash.GET_ENTITY_HEADING, raycast.HitEntity.Handle):0.000}", 0, false, 0.95f, row, 0.25f, 255, 255, 255, 255);
                    row += 0.02f;

                    Vector3 rot = Function.Call <Vector3>(Hash.GET_ENTITY_ROTATION, raycast.HitEntity.Handle, 2);
                    DrawText($"Rot x: {rot.X:0.000}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"y: {rot.Y:0.000}", 0, false, 0.85f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"z: {rot.Z:0.000}", 0, false, 0.90f, row, 0.25f, 255, 255, 255, 255);
                    row += 0.02f;

                    OutputArgument max       = new OutputArgument();
                    OutputArgument min       = new OutputArgument();
                    int            modelHash = Function.Call <int>(Hash.GET_ENTITY_MODEL, raycast.HitEntity.Handle);
                    Function.Call(Hash.GET_MODEL_DIMENSIONS, modelHash, max, min);
                    Vector3 dim = max.GetResult <Vector3>() - min.GetResult <Vector3>();
                    DrawText($"x: {dim.X:0.000}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"y: {dim.Y:0.000}", 0, false, 0.85f, row, 0.25f, 255, 255, 255, 255);
                    DrawText($"z: {dim.Z:0.000}", 0, false, 0.90f, row, 0.25f, 255, 255, 255, 255);
                    row += 0.02f;

                    DrawText($"Model hash (int): {Function.Call<int>(Hash.GET_ENTITY_MODEL, raycast.HitEntity.Handle)}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    row += 0.02f;
                    DrawText($"Model hash (uint): {Function.Call<uint>(Hash.GET_ENTITY_MODEL, raycast.HitEntity.Handle)}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    row += 0.02f;
                    DrawText($"Model hash (hex): {Function.Call<uint>(Hash.GET_ENTITY_MODEL, raycast.HitEntity.Handle):X}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    row += 0.02f;
                    if (type == "VEH")
                    {
                        // This commented version is not going to work for custom vehicles
                        //DrawText($"Model name: {Enum.GetName(typeof(VehicleHash), Function.Call<uint>(Hash.GET_ENTITY_MODEL, raycast.HitEntity.Handle))}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                        //row += 0.02f;
                        //DrawText($"Class name: {Enum.GetName(typeof(VehicleClass), Function.Call<uint>(Hash.GET_VEHICLE_CLASS, raycast.HitEntity.Handle))}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                        DrawText($"Model name: {Game.GetGXTEntry(Function.Call<string>(Hash.GET_DISPLAY_NAME_FROM_VEHICLE_MODEL, raycast.HitEntity.Model))}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                        row += 0.02f;
                        DrawText($"Class name: {Game.GetGXTEntry(CitizenFX.Core.Vehicle.GetClassDisplayName((VehicleClass)Function.Call<int>(Hash.GET_VEHICLE_CLASS, raycast.HitEntity.Handle)))}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                        row += 0.02f;
                        DrawText($"Plate: {Function.Call<string>(Hash.GET_VEHICLE_NUMBER_PLATE_TEXT, raycast.HitEntity.Handle)}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    }
                    else if (type == "PED")
                    {
                        DrawText($"Model name: {Enum.GetName(typeof(PedHash), Function.Call<uint>(Hash.GET_ENTITY_MODEL, raycast.HitEntity.Handle))}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    }
                    else if (type == "OBJ")
                    {
                        DrawText($"Model name: {Enum.GetName(typeof(ObjectHash), Function.Call<int>(Hash.GET_ENTITY_MODEL, raycast.HitEntity.Handle))}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                    }
                    row += 0.02f;

                    if (Function.Call <bool>(Hash.IS_ENTITY_A_VEHICLE, raycast.HitEntity.Handle))
                    {
                        DrawText($"LOCKS: {Function.Call<int>(Hash.GET_VEHICLE_DOOR_LOCK_STATUS, raycast.HitEntity.Handle)}", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
                        DrawText($"LK4ME: {Function.Call<bool>(Hash.GET_VEHICLE_DOORS_LOCKED_FOR_PLAYER, raycast.HitEntity.Handle, CitizenFX.Core.Game.Player.Handle)}", 0, false, 0.85f, row, 0.25f, 255, 255, 255, 255);
                        DrawText($"SPED: {Function.Call<float>(Hash._GET_VEHICLE_MODEL_MAX_SPEED, Function.Call<uint>(Hash.GET_ENTITY_MODEL, raycast.HitEntity.Handle)):0.00}", 0, false, 0.90f, row, 0.25f, 255, 255, 255, 255);
                        DrawText($"ACCL: {Function.Call<float>(Hash.GET_VEHICLE_MODEL_ACCELERATION, Function.Call<uint>(Hash.GET_ENTITY_MODEL, raycast.HitEntity.Handle)):0.00}", 0, false, 0.95f, row, 0.25f, 255, 255, 255, 255);
                        row += 0.02f;
                    }
                }
            }
            else if (disableEntityUI)
            {
                DrawText($"Entity UI temporarily disabled while manipulating objects (native errors occur)", 0, false, 0.78f, row, 0.25f, 255, 255, 255, 255);
            }
            // TODO: Draw debug information for the developer when desired
        }