using System; using System.IO; using System.Xml.Serialization; using System.Collections.Generic; using System.Runtime.InteropServices; using RageCoop.Core; using GTA; using GTA.Native; using GTA.Math; using System.Linq; using System.Diagnostics; namespace RageCoop.Client { /// /// /// internal static partial class Util { #region -- POINTER -- private static int _steeringAngleOffset { get; set; } public static unsafe void NativeMemory() { IntPtr address; address = Game.FindPattern("\x74\x0A\xF3\x0F\x11\xB3\x1C\x09\x00\x00\xEB\x25", "xxxxxx????xx"); if (address != IntPtr.Zero) { _steeringAngleOffset = *(int*)(address + 6) + 8; } // breaks some stuff. /* address = Game.FindPattern("\x32\xc0\xf3\x0f\x11\x09", "xxxxxx"); // Weapon / Radio slowdown if (address != IntPtr.Zero) { for (int i = 0; i < 6; i++) { *(byte*)(address + i).ToPointer() = 0x90; } } */ } public static unsafe void CustomSteeringAngle(this Vehicle veh, float value) { IntPtr address = new IntPtr((long)veh.MemoryAddress); if (address == IntPtr.Zero || _steeringAngleOffset == 0) { return; } *(float*)(address + _steeringAngleOffset).ToPointer() = value; } #endregion public static Settings ReadSettings() { XmlSerializer ser = new XmlSerializer(typeof(Settings)); string path = Directory.GetCurrentDirectory() + "\\Scripts\\RageCoop\\RageCoop.Client.Settings.xml"; Settings settings = null; if (File.Exists(path)) { using (FileStream stream = File.OpenRead(path)) { settings = (RageCoop.Client.Settings)ser.Deserialize(stream); } using (FileStream stream = new FileStream(path, FileMode.Truncate, FileAccess.ReadWrite)) { ser.Serialize(stream, settings); } } else { using (FileStream stream = File.OpenWrite(path)) { ser.Serialize(stream, settings = new Settings()); } } return settings; } public static void SaveSettings() { try { string path = Directory.GetCurrentDirectory() + "\\Scripts\\RageCoop\\RageCoop.Client.Settings.xml"; using (FileStream stream = new FileStream(path, File.Exists(path) ? FileMode.Truncate : FileMode.Create, FileAccess.ReadWrite)) { XmlSerializer ser = new XmlSerializer(typeof(Settings)); ser.Serialize(stream, Main.Settings); } } catch (Exception ex) { GTA.UI.Notification.Show("Error saving player settings: " + ex.Message); } } public static bool IsBetween(this T item, T start, T end) { return Comparer.Default.Compare(item, start) >= 0 && Comparer.Default.Compare(item, end) <= 0; } public static bool Compare(this Dictionary item, Dictionary item2) { if (item == null || item2 == null || item.Count != item2.Count) { return false; } foreach (KeyValuePair pair in item) { if (item2.TryGetValue(pair.Key, out Y value) && Equals(value, pair.Value)) { continue; } // TryGetValue() or Equals failed return false; } // No difference between item and item2 return true; } #region MATH public static Vector3 LinearVectorLerp(Vector3 start, Vector3 end, ulong currentTime, int duration) { return new Vector3() { X = LinearFloatLerp(start.X, end.X, currentTime, duration), Y = LinearFloatLerp(start.Y, end.Y, currentTime, duration), Z = LinearFloatLerp(start.Z, end.Z, currentTime, duration), }; } public static float LinearFloatLerp(float start, float end, ulong currentTime, int duration) { return (end - start) * currentTime / duration + start; } public static float Lerp(float from, float to, float fAlpha) { return (from * (1.0f - fAlpha)) + (to * fAlpha); //from + (to - from) * fAlpha } public static Vector3 RotationToDirection(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) }; } #endregion public static Model ModelRequest(this int hash) { Model model = new Model(hash); if (!model.IsValid) { //GTA.UI.Notification.Show("~y~Not valid!"); return null; } if (!model.IsLoaded) { return model.Request(1000) ? model : null; } return model; } #region PED public static byte GetPedSpeed(this Ped ped) { if (ped.IsSprinting) { return 3; } if (ped.IsRunning) { return 2; } if (ped.IsWalking) { return 1; } return 0; } public static Dictionary GetPedClothes(this Ped ped) { Dictionary result = new Dictionary(); for (byte i = 0; i < 11; i++) { short mod = Function.Call(Hash.GET_PED_DRAWABLE_VARIATION, ped.Handle, i); result.Add(i, mod); } return result; } public static PedDataFlags GetPedFlags(this Ped ped) { PedDataFlags flags = PedDataFlags.None; if (ped.IsAiming || ped.IsOnTurretSeat()) { flags |= PedDataFlags.IsAiming; } if (ped.IsReloading) { flags |= PedDataFlags.IsReloading; } if (ped.IsJumping) { flags |= PedDataFlags.IsJumping; } if (ped.IsRagdoll) { flags |= PedDataFlags.IsRagdoll; } if (ped.IsOnFire) { flags |= PedDataFlags.IsOnFire; } if (ped.IsInParachuteFreeFall) { flags |= PedDataFlags.IsInParachuteFreeFall; } if (ped.ParachuteState == ParachuteState.Gliding) { flags |= PedDataFlags.IsParachuteOpen; } bool climbingLadder = ped.IsTaskActive(TaskType.CTaskGoToAndClimbLadder); if (climbingLadder) { flags |= PedDataFlags.IsOnLadder; } if (ped.IsVaulting && !climbingLadder) { flags |= PedDataFlags.IsVaulting; } if (ped.IsInCover || ped.IsGoingIntoCover) { flags |=PedDataFlags.IsInCover; } return flags; } public static string[] GetReloadingAnimation(this Ped ped) { switch (ped.Weapons.Current.Hash) { case WeaponHash.Revolver: case WeaponHash.RevolverMk2: case WeaponHash.DoubleActionRevolver: case WeaponHash.NavyRevolver: return new string[2] { "anim@weapons@pistol@revolver_str", "reload_aim" }; case WeaponHash.APPistol: return new string[2] { "weapons@pistol@ap_pistol_str", "reload_aim" }; case WeaponHash.Pistol50: return new string[2] { "weapons@pistol@pistol_50_str", "reload_aim" }; case WeaponHash.Pistol: case WeaponHash.PistolMk2: case WeaponHash.PericoPistol: case WeaponHash.SNSPistol: case WeaponHash.SNSPistolMk2: case WeaponHash.HeavyPistol: case WeaponHash.VintagePistol: case WeaponHash.CeramicPistol: case WeaponHash.MachinePistol: return new string[2] { "weapons@pistol@pistol_str", "reload_aim" }; case WeaponHash.AssaultRifle: case WeaponHash.AssaultrifleMk2: return new string[2] { "weapons@rifle@hi@assault_rifle_str", "reload_aim" }; case WeaponHash.SniperRifle: return new string[2] { "weapons@rifle@hi@sniper_rifle_str", "reload_aim" }; case WeaponHash.HeavySniper: case WeaponHash.HeavySniperMk2: return new string[2] { "weapons@rifle@lo@sniper_heavy_str", "reload_aim" }; case WeaponHash.PumpShotgun: case WeaponHash.PumpShotgunMk2: return new string[2] { "weapons@rifle@pump_str", "reload_aim" }; case WeaponHash.Railgun: return new string[2] { "weapons@rifle@lo@rail_gun_str", "reload_aim" }; case WeaponHash.SawnOffShotgun: return new string[2] { "weapons@rifle@lo@sawnoff_str", "reload_aim" }; case WeaponHash.AssaultShotgun: return new string[2] { "weapons@rifle@lo@shotgun_assault_str", "reload_aim" }; case WeaponHash.BullpupShotgun: return new string[2] { "weapons@rifle@lo@shotgun_bullpup_str", "reload_aim" }; case WeaponHash.AdvancedRifle: return new string[2] { "weapons@submg@advanced_rifle_str", "reload_aim" }; case WeaponHash.CarbineRifle: case WeaponHash.CarbineRifleMk2: case WeaponHash.CompactRifle: return new string[2] { "weapons@rifle@lo@carbine_str", "reload_aim" }; case WeaponHash.Gusenberg: return new string[2] { "anim@weapons@machinegun@gusenberg_str", "reload_aim" }; case WeaponHash.Musket: return new string[2] { "anim@weapons@musket@musket_str", "reload_aim" }; case WeaponHash.FlareGun: return new string[2] { "anim@weapons@pistol@flare_str", "reload_aim" }; case WeaponHash.SpecialCarbine: case WeaponHash.SpecialCarbineMk2: return new string[2] { "anim@weapons@rifle@lo@spcarbine_str", "reload_aim" }; case WeaponHash.CombatPDW: return new string[2] { "anim@weapons@rifle@lo@pdw_str", "reload_aim" }; case WeaponHash.BullpupRifle: case WeaponHash.BullpupRifleMk2: return new string[2] { "anim@weapons@submg@bullpup_rifle_str", "reload_aim" }; case WeaponHash.AssaultSMG: return new string[2] { "weapons@submg@assault_smg_str", "reload_aim" }; case WeaponHash.MicroSMG: case WeaponHash.MiniSMG: return new string[2] { "weapons@submg@lo@micro_smg_str", "reload_aim" }; case WeaponHash.SMG: case WeaponHash.SMGMk2: return new string[2] { "weapons@rifle@smg_str", "reload_aim" }; case WeaponHash.GrenadeLauncher: case WeaponHash.GrenadeLauncherSmoke: case WeaponHash.CompactGrenadeLauncher: return new string[2] { "weapons@heavy@grenade_launcher_str", "reload_aim" }; case WeaponHash.RPG: case WeaponHash.Firework: return new string[2] { "weapons@heavy@rpg_str", "reload_aim" }; case WeaponHash.CombatMG: case WeaponHash.CombatMGMk2: return new string[2] { "weapons@machinegun@combat_mg_str", "reload_aim" }; case WeaponHash.MG: return new string[2] { "weapons@machinegun@mg_str", "reload_aim" }; default: Main.Logger.Warning($"~r~Reloading failed! Weapon ~g~[{ped.Weapons.Current.Hash}]~r~ could not be found!"); return null; } } public static VehicleSeat GetNearestSeat(Ped ped, Vehicle veh, float distanceToignoreDoors = 50f) { float num = 99f; int result = -2; Dictionary dictionary = new Dictionary(); dictionary.Add("door_dside_f", -1); dictionary.Add("door_pside_f", 0); dictionary.Add("door_dside_r", 1); dictionary.Add("door_pside_r", 2); foreach (string text in dictionary.Keys) { bool flag = veh.Bones[text].Position != Vector3.Zero; if (flag) { float num2 = ped.Position.DistanceTo(Function.Call(Hash.GET_WORLD_POSITION_OF_ENTITY_BONE, new InputArgument[] { veh, veh.Bones[text].Index })); bool flag2 = (num2 < distanceToignoreDoors) && (num2 < num)&& IsSeatUsableByPed(ped, veh, dictionary[text]); if (flag2) { num = num2; result = dictionary[text]; } } } return (VehicleSeat)result; } public static bool IsSeatUsableByPed(Ped ped, Vehicle veh, int _seat) { VehicleSeat seat = (VehicleSeat)_seat; bool result = false; bool flag = veh.IsSeatFree(seat); if (flag) { result = true; } else { bool isDead = veh.GetPedOnSeat(seat).IsDead; if (isDead) { result = true; } else { int num = Function.Call(Hash.GET_RELATIONSHIP_BETWEEN_PEDS, new InputArgument[] { ped, veh.GetPedOnSeat(seat) }); bool flag2 = num > 2; if (flag2) { result = true; } } } return result; } public static bool IsTaskActive(this Ped p,TaskType task) { return Function.Call(Hash.GET_IS_TASK_ACTIVE, p.Handle, task); } public static Vector3 GetAimCoord(this Ped p) { var weapon = p.Weapons.CurrentWeaponObject; if (p.IsOnTurretSeat()) { return p.GetLookingCoord(); } if (weapon!=null) { // Not very accurate, but doesn't matter Vector3 dir = weapon.RightVector; return weapon.Position+dir*20; /* RaycastResult result = World.Raycast(weapon.Position+dir, weapon.Position+dir*10000, IntersectFlags.Everything, p.IsInVehicle() ? (Entity)p : p.CurrentVehicle); if (result.DidHit) { return result.HitPosition; } else { return weapon.Position+dir*20; } */ } return GetLookingCoord(p); } public static Vector3 GetLookingCoord(this Ped p) { 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); } public static Vector3 GetMuzzlePosition(this Ped p) { var w = p.Weapons.CurrentWeaponObject; if (w!=null) { var hash = p.Weapons.Current.Hash; if (MuzzleBoneIndexes.ContainsKey(hash)) { return w.Bones[MuzzleBoneIndexes[hash]].Position; } return w.Position; } return p.Bones[Bone.SkelRightHand].Position; } public static bool IsUsingProjectileWeapon(this Ped p) { var w = p.Weapons.Current; return w.Group==WeaponGroup.Thrown||ProjectileWeapons.Contains(w.Hash); } #endregion #region VEHICLE public static VehicleDataFlags GetVehicleFlags(this Vehicle veh) { VehicleDataFlags flags = 0; if (veh.IsEngineRunning) { flags |= VehicleDataFlags.IsEngineRunning; } if (veh.AreLightsOn) { flags |= VehicleDataFlags.AreLightsOn; } if (veh.BrakePower >= 0.01f) { flags |= VehicleDataFlags.AreBrakeLightsOn; } if (veh.AreHighBeamsOn) { flags |= VehicleDataFlags.AreHighBeamsOn; } if (veh.IsSirenActive) { flags |= VehicleDataFlags.IsSirenActive; } if (veh.IsDead) { flags |= VehicleDataFlags.IsDead; } if (Function.Call(Hash.IS_HORN_ACTIVE, veh.Handle)) { flags |= VehicleDataFlags.IsHornActive; } if (veh.IsSubmarineCar && Function.Call(Hash._GET_IS_SUBMARINE_VEHICLE_TRANSFORMED, veh.Handle)) { flags |= VehicleDataFlags.IsTransformed; } if (veh.HasRoof && (veh.RoofState == VehicleRoofState.Opened || veh.RoofState == VehicleRoofState.Opening)) { flags |= VehicleDataFlags.RoofOpened; } if (veh.IsAircraft) { flags |= VehicleDataFlags.IsAircraft; } return flags; } public static bool HasFlag(this PedDataFlags flagToCheck,PedDataFlags flag) { return (flagToCheck & flag)!=0; } public static bool HasFlag(this VehicleDataFlags flagToCheck, VehicleDataFlags flag) { return (flagToCheck & flag)!=0; } public static Dictionary GetWeaponComponents(this Weapon weapon) { Dictionary result = null; if (weapon.Components.Count > 0) { result = new Dictionary(); foreach (var comp in weapon.Components) { result.Add((uint)comp.ComponentHash, comp.Active); } } return result; } public static Dictionary GetVehicleMods(this VehicleModCollection mods) { Dictionary result = new Dictionary(); foreach (VehicleMod mod in mods.ToArray()) { result.Add((int)mod.Type, mod.Index); } return result; } public static VehicleDamageModel GetVehicleDamageModel(this Vehicle veh) { // Broken windows byte brokenWindows = 0; for (int i = 0; i < 8; i++) { if (!veh.Windows[(VehicleWindowIndex)i].IsIntact) { brokenWindows |= (byte)(1 << i); } } // Broken doors byte brokenDoors = 0; byte openedDoors = 0; foreach (VehicleDoor door in veh.Doors) { if (door.IsBroken) { brokenDoors |= (byte)(1 << (byte)door.Index); } else if (door.IsOpen) { openedDoors |= (byte)(1 << (byte)door.Index); } } // Bursted tires short burstedTires = 0; foreach (VehicleWheel wheel in veh.Wheels.GetAllWheels()) { if (wheel.IsBursted) { burstedTires |= (short)(1 << (int)wheel.BoneId); } } return new VehicleDamageModel() { BrokenDoors = brokenDoors, OpenedDoors = openedDoors, BrokenWindows = brokenWindows, BurstedTires = burstedTires, LeftHeadLightBroken = (byte)(veh.IsLeftHeadLightBroken ? 1 : 0), RightHeadLightBroken = (byte)(veh.IsRightHeadLightBroken ? 1 : 0) }; } public static Dictionary GetPassengers(this Vehicle veh) { Dictionary ps=new Dictionary(); var d = veh.Driver; if (d!=null&&d.IsSittingInVehicle()) { ps.Add(-1, d.GetSyncEntity().ID); } foreach(Ped p in veh.Passengers) { if (p.IsSittingInVehicle()) { ps.Add((int)p.SeatIndex, (int)p.GetSyncEntity().ID); } } return ps; } public static void SetDamageModel(this Vehicle veh, VehicleDamageModel model, bool leavedoors = true) { for (int i = 0; i < 8; i++) { var door = veh.Doors[(VehicleDoorIndex)i]; if ((model.BrokenDoors & (byte)(1 << i)) != 0) { door.Break(leavedoors); } else if (door.IsBroken) { // The vehicle can only fix a door if the vehicle was completely fixed veh.Repair(); return; } if ((model.OpenedDoors & (byte)(1 << i)) != 0) { if ((!door.IsOpen)&&(!door.IsBroken)) { door.Open(); } } else if (door.IsOpen) { if (!door.IsBroken) { door.Close(); } } if ((model.BrokenWindows & (byte)(1 << i)) != 0) { veh.Windows[(VehicleWindowIndex)i].Smash(); } else if (!veh.Windows[(VehicleWindowIndex)i].IsIntact) { veh.Windows[(VehicleWindowIndex)i].Repair(); } } foreach (VehicleWheel wheel in veh.Wheels) { if ((model.BurstedTires & (short)(1 << (int)wheel.BoneId)) != 0) { if (!wheel.IsBursted) { wheel.Puncture(); wheel.Burst(); } } else if (wheel.IsBursted) { wheel.Fix(); } } veh.IsLeftHeadLightBroken = model.LeftHeadLightBroken > 0; veh.IsRightHeadLightBroken = model.RightHeadLightBroken > 0; } #endregion public static void SetOnFire(this Entity e,bool toggle) { if (toggle) { Function.Call(Hash.START_ENTITY_FIRE, e.Handle); } else { Function.Call(Hash.STOP_ENTITY_FIRE, e.Handle); } } public static SyncedPed GetSyncEntity(this Ped p) { if(p == null) { return null; } var c = EntityPool.GetPedByHandle(p.Handle); if(c==null) { EntityPool.Add(c=new SyncedPed(p)); } return c; } public static SyncedVehicle GetSyncEntity(this Vehicle veh) { if(veh == null) { return null; } var v=EntityPool.GetVehicleByHandle(veh.Handle); if (v==null) { EntityPool.Add(v=new SyncedVehicle(veh)); } return v; } public static double DegToRad(double deg) { return deg * Math.PI / 180.0; } public static bool IsTurretSeat(this Vehicle veh, int seat) { if (!Function.Call(Hash.DOES_VEHICLE_HAVE_WEAPONS, veh.Handle)) { return false; } switch (seat) { case -1: return (VehicleHash)veh.Model.Hash == VehicleHash.Rhino || (VehicleHash)veh.Model.Hash == VehicleHash.Khanjari || (VehicleHash)veh.Model.Hash == VehicleHash.FireTruck || (VehicleHash)veh.Model.Hash == VehicleHash.Riot2 || (VehicleHash)veh.Model.Hash == VehicleHash.Cerberus || (VehicleHash)veh.Model.Hash == VehicleHash.Cerberus2 || (VehicleHash)veh.Model.Hash == VehicleHash.Cerberus3; case 0: return (VehicleHash)veh.Model.Hash == VehicleHash.Apc; case 1: return (VehicleHash)veh.Model.Hash == VehicleHash.Valkyrie || (VehicleHash)veh.Model.Hash == VehicleHash.Valkyrie2 || (VehicleHash)veh.Model.Hash == VehicleHash.Technical || (VehicleHash)veh.Model.Hash == VehicleHash.Technical2 || (VehicleHash)veh.Model.Hash == VehicleHash.Technical3 || (VehicleHash)veh.Model.Hash == VehicleHash.HalfTrack || (VehicleHash)veh.Model.Hash == VehicleHash.Barrage; case 2: return (VehicleHash)veh.Model.Hash == VehicleHash.Valkyrie || (VehicleHash)veh.Model.Hash == VehicleHash.Valkyrie2 || (VehicleHash)veh.Model.Hash == VehicleHash.Barrage; case 3: return (VehicleHash)veh.Model.Hash == VehicleHash.Limo2 || (VehicleHash)veh.Model.Hash == VehicleHash.Dinghy5; case 7: return (VehicleHash)veh.Model.Hash == VehicleHash.Insurgent; } return false; } public static bool IsOnTurretSeat(this Ped P) { if (P.CurrentVehicle == null) { return false; } return IsTurretSeat(P.CurrentVehicle, (int)P.SeatIndex); } public static readonly Model[] WeaponModels = Weapon.GetAllModels(); [DllImport("kernel32.dll")] public static extern ulong GetTickCount64(); public static int GetDamage(this Weapon w) { int damage=0; switch (w.Group) { case WeaponGroup.AssaultRifle: damage=30;break; case WeaponGroup.Heavy: damage=30;break; case WeaponGroup.MG: damage=30;break; case WeaponGroup.PetrolCan: damage=0;break; case WeaponGroup.Pistol: damage=30;break; case WeaponGroup.Shotgun: damage=30; break; case WeaponGroup.SMG: damage=20; break; case WeaponGroup.Sniper: damage=100; break; case WeaponGroup.Thrown: damage=0; break; case WeaponGroup.Unarmed: damage=0; break; } return damage; } public static readonly Dictionary MuzzleBoneIndexes = new Dictionary { {WeaponHash.HeavySniper,6}, {WeaponHash.MarksmanRifle,9}, {WeaponHash.SniperRifle,9}, {WeaponHash.AdvancedRifle,5}, {WeaponHash.SpecialCarbine,9}, {WeaponHash.BullpupRifle,7}, {WeaponHash.AssaultRifle,9}, {WeaponHash.CarbineRifle,6}, {WeaponHash.MachinePistol,5}, {WeaponHash.SMG,5}, {WeaponHash.AssaultSMG,6}, {WeaponHash.CombatPDW,5}, {WeaponHash.MG,6}, {WeaponHash.CombatMG,7}, {WeaponHash.Gusenberg,7}, {WeaponHash.MicroSMG,10}, {WeaponHash.APPistol,8}, {WeaponHash.StunGun,4}, {WeaponHash.Pistol,8}, {WeaponHash.CombatPistol,8}, {WeaponHash.Pistol50,7}, {WeaponHash.SNSPistol,8}, {WeaponHash.HeavyPistol,8}, {WeaponHash.VintagePistol,8}, {WeaponHash.Railgun,9}, {WeaponHash.Minigun,5}, {WeaponHash.Musket,3}, {WeaponHash.HeavyShotgun,10}, {WeaponHash.PumpShotgun,11}, {WeaponHash.SawnOffShotgun,8}, {WeaponHash.BullpupShotgun,8}, {WeaponHash.AssaultShotgun,9}, {WeaponHash.HeavySniperMk2,11}, {WeaponHash.MarksmanRifleMk2,9}, {WeaponHash.CarbineRifleMk2,13}, {WeaponHash.SpecialCarbineMk2,16}, {WeaponHash.BullpupRifleMk2,8}, {WeaponHash.CompactRifle,7}, {WeaponHash.MilitaryRifle,11}, {WeaponHash.AssaultrifleMk2,17}, {WeaponHash.MiniSMG,5}, {WeaponHash.SMGMk2,6}, {WeaponHash.CombatMGMk2,16}, {WeaponHash.UnholyHellbringer,4}, {WeaponHash.PistolMk2,12}, {WeaponHash.SNSPistolMk2,15}, {WeaponHash.CeramicPistol,10}, {WeaponHash.MarksmanPistol,4}, {WeaponHash.Revolver,7}, {WeaponHash.RevolverMk2,7}, {WeaponHash.DoubleActionRevolver,7}, {WeaponHash.NavyRevolver,7}, {WeaponHash.PericoPistol,4}, {WeaponHash.FlareGun,4}, {WeaponHash.UpNAtomizer,4}, {WeaponHash.HomingLauncher,5}, {WeaponHash.CompactGrenadeLauncher,8}, {WeaponHash.Widowmaker,6}, {WeaponHash.GrenadeLauncher,3}, {WeaponHash.RPG,9}, {WeaponHash.DoubleBarrelShotgun,8}, {WeaponHash.SweeperShotgun,7}, {WeaponHash.CombatShotgun,7}, {WeaponHash.PumpShotgunMk2,7}, }; public static readonly HashSet ProjectileWeapons = new HashSet { WeaponHash.HomingLauncher, WeaponHash.RPG, WeaponHash.Firework, WeaponHash.UpNAtomizer, WeaponHash.GrenadeLauncher, WeaponHash.GrenadeLauncherSmoke, WeaponHash.CompactGrenadeLauncher }; /* public static readonly Dictionary WeaponExplosionTypes = new Dictionary { { WeaponHash.Grenade,ExplosionType.Grenade}, { WeaponHash.GrenadeLauncher,ExplosionType.Grenade}, { WeaponHash.CompactGrenadeLauncher,ExplosionType.Grenade}, { WeaponHash.SmokeGrenade,ExplosionType.SmokeG}, { WeaponHash.GrenadeLauncherSmoke,ExplosionType.SmokeG}, { WeaponHash.StickyBomb,ExplosionType.StickyBomb}, { WeaponHash.Flare,ExplosionType.Flare}, { WeaponHash.FlareGun,ExplosionType.Flare}, { WeaponHash.Molotov,ExplosionType.Molotov1}, { WeaponHash.BZGas,ExplosionType.BZGas}, { WeaponHash.PipeBomb,ExplosionType.PipeBomb}, { WeaponHash.ProximityMine,ExplosionType.ProxMine}, { WeaponHash.Firework,ExplosionType.FireWork}, { WeaponHash.RPG,ExplosionType.Rocket}, }; */ } /// /// /// public static class VectorExtensions { /// /// /// public static Vector3 ToVector(this Quaternion vec) { return new Vector3() { X = vec.X, Y = vec.Y, Z = vec.Z }; } /// /// /// public static Quaternion ToQuaternion(this Vector3 vec, float vW = 0.0f) { return new Quaternion() { X = vec.X, Y = vec.Y, Z = vec.Z, W = vW }; } public static float Denormalize(this float h) { return h < 0f ? h + 360f : h; } public static float ToRadians(this float val) { return (float)(Math.PI / 180) * val; } public static Vector3 ToRadians(this Vector3 i) { return new Vector3() { X = ToRadians(i.X), Y = ToRadians(i.Y), Z = ToRadians(i.Z), }; } public static Quaternion ToQuaternion(this Vector3 vect) { vect = new Vector3() { X = vect.X.Denormalize() * -1, Y = vect.Y.Denormalize() - 180f, Z = vect.Z.Denormalize() - 180f, }; vect = vect.ToRadians(); float rollOver2 = vect.Z * 0.5f; float sinRollOver2 = (float)Math.Sin((double)rollOver2); float cosRollOver2 = (float)Math.Cos((double)rollOver2); float pitchOver2 = vect.Y * 0.5f; float sinPitchOver2 = (float)Math.Sin((double)pitchOver2); float cosPitchOver2 = (float)Math.Cos((double)pitchOver2); float yawOver2 = vect.X * 0.5f; // pitch float sinYawOver2 = (float)Math.Sin((double)yawOver2); float cosYawOver2 = (float)Math.Cos((double)yawOver2); Quaternion result = new Quaternion() { X = cosYawOver2 * cosPitchOver2 * cosRollOver2 + sinYawOver2 * sinPitchOver2 * sinRollOver2, Y = cosYawOver2 * cosPitchOver2 * sinRollOver2 - sinYawOver2 * sinPitchOver2 * cosRollOver2, Z = cosYawOver2 * sinPitchOver2 * cosRollOver2 + sinYawOver2 * cosPitchOver2 * sinRollOver2, W = sinYawOver2 * cosPitchOver2 * cosRollOver2 - cosYawOver2 * sinPitchOver2 * sinRollOver2 }; return result; } /// /// /// public static LVector3 ToLVector(this Vector3 vec) { return new LVector3() { X = vec.X, Y = vec.Y, Z = vec.Z }; } /// /// /// public static LQuaternion ToLQuaternion(this Quaternion vec) { return new LQuaternion() { X = vec.X, Y = vec.Y, Z = vec.Z, W = vec.W }; } } }