diff --git a/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs b/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs index d21b5e073..4dfa008d2 100644 --- a/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs +++ b/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs @@ -1,20 +1,22 @@ using System; +using System.Numerics; using System.Runtime.InteropServices; using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Utils; +using Vector = CounterStrikeSharp.API.Modules.Utils.Vector; namespace CounterStrikeSharp.API.Core; public partial class CBaseEntity { /// Entity is not valid - /// No valid argument + /// At least one parameter must be specified public void Teleport(Vector? position = null, QAngle? angles = null, Vector? velocity = null) { Guard.IsValidEntity(this); if (position == null && angles == null && velocity == null) - throw new ArgumentNullException("No valid argument"); + throw new ArgumentException("At least one parameter must be specified"); nint _position = position?.Handle ?? 0; nint _angles = angles?.Handle ?? 0; @@ -25,6 +27,47 @@ public void Teleport(Vector? position = null, QAngle? angles = null, Vector? vel _angles, _velocity); } + /// + /// Teleports the entity to the specified position, angles, and velocity using Vector3 parameters. + /// This overload is optimized for memory efficiency by directly working with a Vector3 struct. + /// + /// Entity is not valid + /// At least one parameter must be specified + public void Teleport(Vector3? position = null, Vector3? angles = null, Vector3? velocity = null) + { + Guard.IsValidEntity(this); + + if (position == null && angles == null && velocity == null) + throw new ArgumentException("At least one parameter must be specified"); + + unsafe + { + void* positionPtr = null, anglePtr = null, velocityPtr = null; + + if (position.HasValue) + { + var pos = position.Value; + positionPtr = &pos; + } + + if (angles.HasValue) + { + var ang = angles.Value; + anglePtr = ∠ + } + + if (velocity.HasValue) + { + var vel = velocity.Value; + velocityPtr = &vel; + } + + VirtualFunction.CreateVoid(Handle, GameData.GetOffset("CBaseEntity_Teleport"))(Handle, + (nint)positionPtr, + (nint)anglePtr, (nint)velocityPtr); + } + } + /// Entity is not valid public void DispatchSpawn() { @@ -62,7 +105,7 @@ public void DispatchSpawn() public uint EmitSound(string soundEventName, RecipientFilter? recipients = null, float volume = 1f, float pitch = 0) { Guard.IsValidEntity(this); - + if (recipients == null) { recipients = new RecipientFilter(); diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/QAngle.cs b/managed/CounterStrikeSharp.API/Modules/Utils/QAngle.cs index e3a022083..99ab3dfdc 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/QAngle.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/QAngle.cs @@ -14,6 +14,7 @@ * along with CounterStrikeSharp. If not, see . * */ +using System.Numerics; using System.Runtime.CompilerServices; namespace CounterStrikeSharp.API.Modules.Utils @@ -21,11 +22,11 @@ namespace CounterStrikeSharp.API.Modules.Utils public class QAngle : NativeObject { public static readonly QAngle Zero = new(); - + public QAngle(IntPtr pointer) : base(pointer) { } - + public QAngle(float? x = null, float? y = null, float? z = null) : this(NativeAPI.AngleNew()) { this.X = x ?? 0; @@ -36,10 +37,23 @@ public QAngle(float? x = null, float? y = null, float? z = null) : this(NativeAP public unsafe ref float X => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 0); public unsafe ref float Y => ref Unsafe.Add(ref *(float*)Handle, 1); public unsafe ref float Z => ref Unsafe.Add(ref *(float*)Handle, 2); - + public override string ToString() { return $"{X:n2} {Y:n2} {Z:n2}"; } + + public static explicit operator Vector3(QAngle q) + { + unsafe + { + if (q is null) + { + throw new ArgumentNullException(nameof(q), "Input QAngle cannot be null."); + } + + return new Vector3(new ReadOnlySpan(q.Handle.ToPointer(), 3)); + } + } } } \ No newline at end of file diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/Vector.cs b/managed/CounterStrikeSharp.API/Modules/Utils/Vector.cs index 7dfe83990..e802ca390 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/Vector.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/Vector.cs @@ -297,6 +297,7 @@ public void Zero() NativePINVOKE.Vector_Zero(ptr); } */ + #region Operators public float this[int i] @@ -351,12 +352,27 @@ public float this[int i] { return new Vector(a.X * b, a.Y * b, a.Z * b); } + public static Vector operator /(Vector a, float b) { return new Vector(a.X / b, a.Y / b, a.Z / b); } + public static explicit operator Vector3(Vector v) + { + unsafe + { + if (v is null) + { + throw new ArgumentNullException(nameof(v), "Input Vector cannot be null."); + } + + return new Vector3(new ReadOnlySpan(v.Handle.ToPointer(), 3)); + } + } + #endregion + /* public override bool Equals(object obj)