Read quaternion and rotation directly from memory
This commit is contained in:
@ -32,7 +32,7 @@ namespace RageCoop.Client
|
||||
ID =c.ID,
|
||||
OwnerID=c.OwnerID,
|
||||
Health = p.Health,
|
||||
Rotation = p.Rotation,
|
||||
Rotation = p.ReadRotation(),
|
||||
Velocity = p.Velocity,
|
||||
Speed = p.GetPedSpeed(),
|
||||
CurrentWeaponHash = (uint)p.Weapons.Current.Hash,
|
||||
@ -91,7 +91,7 @@ namespace RageCoop.Client
|
||||
Flags = veh.GetVehicleFlags(),
|
||||
SteeringAngle = veh.SteeringAngle,
|
||||
Position = veh.PredictPosition(),
|
||||
Quaternion=veh.Quaternion,
|
||||
Quaternion=veh.ReadQuaternion(),
|
||||
Velocity = veh.Velocity,
|
||||
RotationVelocity=veh.RotationVelocity,
|
||||
ThrottlePower = veh.ThrottlePower,
|
||||
|
@ -57,6 +57,7 @@
|
||||
<Compile Include="Sync\SyncEvents.cs" />
|
||||
<Compile Include="Sync\SyncParameters.cs" />
|
||||
<Compile Include="Util\Memory.cs" />
|
||||
<Compile Include="Util\NativeCaller.cs" />
|
||||
<Compile Include="Util\PedConfigFlags.cs" />
|
||||
<Compile Include="Util\PedExtensions.cs" />
|
||||
<Compile Include="Util\TaskType.cs" />
|
||||
@ -83,6 +84,7 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\libs\Lidgren.Network.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\libs\Newtonsoft.Json.dll</HintPath>
|
||||
|
@ -361,7 +361,7 @@ namespace RageCoop.Client
|
||||
model.Request(1000);
|
||||
if (model != null)
|
||||
{
|
||||
ParachuteProp = World.CreateProp(model, MainPed.ReadPosition(), MainPed.Rotation, false, false);
|
||||
ParachuteProp = World.CreateProp(model, MainPed.ReadPosition(), MainPed.ReadRotation(), false, false);
|
||||
model.MarkAsNoLongerNeeded();
|
||||
ParachuteProp.IsPositionFrozen = true;
|
||||
ParachuteProp.IsCollisionEnabled = false;
|
||||
|
@ -356,7 +356,7 @@ namespace RageCoop.Client
|
||||
MainVehicle.Velocity = Velocity+5*(predicted - current);
|
||||
if (IsFlipped)
|
||||
{
|
||||
MainVehicle.Quaternion=Quaternion.Slerp(MainVehicle.Quaternion, Quaternion, 0.5f);
|
||||
MainVehicle.Quaternion=Quaternion.Slerp(MainVehicle.ReadQuaternion(), Quaternion, 0.5f);
|
||||
MainVehicle.RotationVelocity=RotationVelocity;
|
||||
}
|
||||
else
|
||||
@ -383,7 +383,7 @@ namespace RageCoop.Client
|
||||
private Vector3 GetCalibrationRotation()
|
||||
{
|
||||
var rot = Quaternion.LookRotation(Quaternion*Vector3.RelativeFront, Quaternion*Vector3.RelativeTop).ToEulerAngles();
|
||||
var curRot = Quaternion.LookRotation(MainVehicle.Quaternion*Vector3.RelativeFront, MainVehicle.Quaternion*Vector3.RelativeTop).ToEulerAngles();
|
||||
var curRot = Quaternion.LookRotation(MainVehicle.ReadQuaternion()*Vector3.RelativeFront, MainVehicle.ReadQuaternion()*Vector3.RelativeTop).ToEulerAngles();
|
||||
|
||||
var r = (rot-curRot).ToDegree();
|
||||
if (r.X>180) { r.X=r.X-360; }
|
||||
|
@ -5,6 +5,8 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GTA.Math;
|
||||
using GTA;
|
||||
using SHVDN;
|
||||
using RageCoop.Core;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -17,6 +19,14 @@ namespace RageCoop.Client
|
||||
{
|
||||
return ReadVector3(e.MemoryAddress+PositionOffset);
|
||||
}
|
||||
public static Quaternion ReadQuaternion(this Entity e)
|
||||
{
|
||||
return Quaternion.RotationMatrix(e.Matrix);
|
||||
}
|
||||
public static Vector3 ReadRotation(this Entity e)
|
||||
{
|
||||
return e.ReadQuaternion().ToEulerDegrees();
|
||||
}
|
||||
public unsafe static Vector3 ReadVector3(IntPtr address)
|
||||
{
|
||||
float* ptr = (float*)address.ToPointer();
|
||||
|
152
RageCoop.Client/Util/NativeCaller.cs
Normal file
152
RageCoop.Client/Util/NativeCaller.cs
Normal file
@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GTA;
|
||||
using GTA.Native;
|
||||
using GTA.Math;
|
||||
using System.Runtime.InteropServices;
|
||||
using LemonUI.Elements;
|
||||
using System.Drawing;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Size = 80)]
|
||||
public struct HeadBlendData
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public int ShapeFirst;
|
||||
|
||||
[FieldOffset(8)]
|
||||
public int ShapeSecond;
|
||||
|
||||
[FieldOffset(16)]
|
||||
public int ShapeThird;
|
||||
|
||||
[FieldOffset(24)]
|
||||
public int SkinFirst;
|
||||
|
||||
[FieldOffset(32)]
|
||||
public int SkinSecond;
|
||||
|
||||
[FieldOffset(40)]
|
||||
public int SkinThird;
|
||||
|
||||
[FieldOffset(48)]
|
||||
public float ShapeMix;
|
||||
|
||||
[FieldOffset(56)]
|
||||
public float SkinMix;
|
||||
|
||||
[FieldOffset(64)]
|
||||
public float ThirdMix;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 24)]
|
||||
public struct NativeVector3
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public float X;
|
||||
|
||||
[FieldOffset(8)]
|
||||
public float Y;
|
||||
|
||||
[FieldOffset(16)]
|
||||
public float Z;
|
||||
|
||||
public static implicit operator Vector3(NativeVector3 vec)
|
||||
{
|
||||
return new Vector3() { X=vec.X, Y=vec.Y, Z=vec.Z };
|
||||
}
|
||||
public static implicit operator NativeVector3(Vector3 vec)
|
||||
{
|
||||
return new NativeVector3() { X=vec.X, Y=vec.Y, Z=vec.Z };
|
||||
}
|
||||
}
|
||||
public static class NativeCaller
|
||||
{
|
||||
// These are borrowed from ScriptHookVDotNet's
|
||||
[DllImport("ScriptHookV.dll", ExactSpelling = true, EntryPoint = "?nativeInit@@YAX_K@Z")]
|
||||
static extern void NativeInit(ulong hash);
|
||||
|
||||
[DllImport("ScriptHookV.dll", ExactSpelling = true, EntryPoint = "?nativePush64@@YAX_K@Z")]
|
||||
static extern void NativePush64(ulong val);
|
||||
|
||||
[DllImport("ScriptHookV.dll", ExactSpelling = true, EntryPoint = "?nativeCall@@YAPEA_KXZ")]
|
||||
static extern unsafe ulong* NativeCall();
|
||||
|
||||
// These are from ScriptHookV's nativeCaller.h
|
||||
static unsafe void NativePush<T>(T val) where T : unmanaged
|
||||
{
|
||||
ulong val64 = 0;
|
||||
*(T*)(&val64) = val;
|
||||
NativePush64(val64);
|
||||
}
|
||||
|
||||
public static unsafe R Invoke<R>(ulong hash) where R : unmanaged
|
||||
{
|
||||
NativeInit(hash);
|
||||
return *(R*)(NativeCall());
|
||||
}
|
||||
public static unsafe R Invoke<R>(Hash hash, params object[] args)
|
||||
where R : unmanaged
|
||||
{
|
||||
NativeInit((ulong)hash);
|
||||
var arguments=ConvertPrimitiveArguments(args);
|
||||
foreach (var arg in arguments)
|
||||
NativePush(arg);
|
||||
|
||||
return *(R*)(NativeCall());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper function that converts an array of primitive values to a native stack.
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
static unsafe ulong[] ConvertPrimitiveArguments(object[] args)
|
||||
{
|
||||
var result = new ulong[args.Length];
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
{
|
||||
if (args[i] is bool valueBool)
|
||||
{
|
||||
result[i] = valueBool ? 1ul : 0ul;
|
||||
continue;
|
||||
}
|
||||
if (args[i] is byte valueByte)
|
||||
{
|
||||
result[i] = (ulong)valueByte;
|
||||
continue;
|
||||
}
|
||||
if (args[i] is int valueInt32)
|
||||
{
|
||||
result[i] = (ulong)valueInt32;
|
||||
continue;
|
||||
}
|
||||
if (args[i] is ulong valueUInt64)
|
||||
{
|
||||
result[i] = valueUInt64;
|
||||
continue;
|
||||
}
|
||||
if (args[i] is float valueFloat)
|
||||
{
|
||||
result[i] = *(ulong*)&valueFloat;
|
||||
continue;
|
||||
}
|
||||
if (args[i] is IntPtr valueIntPtr)
|
||||
{
|
||||
result[i] = (ulong)valueIntPtr.ToInt64();
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new ArgumentException("Unknown primitive type in native argument list", nameof(args));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -98,6 +98,10 @@ namespace RageCoop.Core
|
||||
{
|
||||
return radian*(float)(180/Math.PI);
|
||||
}
|
||||
public static Vector3 ToEulerDegrees(this Quaternion q)
|
||||
{
|
||||
return q.ToEulerAngles().ToDegree();
|
||||
}
|
||||
public static Vector3 ToEulerAngles(this Quaternion q)
|
||||
{
|
||||
Vector3 angles = new Vector3();
|
||||
|
Reference in New Issue
Block a user