Advertisement
Guest User

Untitled

a guest
Dec 31st, 2016
279
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.62 KB | None | 0 0
  1. using System.Collections.Generic;
  2. using System.Threading.Tasks;
  3.  
  4. using CitizenFX.Core;
  5. using CitizenFX.Core.Native;
  6.  
  7. namespace Afterburners
  8. {
  9.     public class Afterburners : BaseScript
  10.     {
  11.         /// <summary>
  12.         ///     Player vehicle
  13.         /// </summary>
  14.         private readonly Dictionary<int, PlayerScriptData> m_players = new Dictionary<int, PlayerScriptData>();
  15.  
  16.         /// <summary>
  17.         ///     Initialize the script
  18.         /// </summary>
  19.         public Afterburners()
  20.         {
  21.             Tick += OnTick;
  22.         }
  23.  
  24.         /// <summary>
  25.         ///     Tick event
  26.         /// </summary>
  27.         private async Task OnTick()
  28.         {
  29.             foreach (var playerIdx in Players)
  30.             {
  31.                 var player = playerIdx.Character;
  32.  
  33.                 if (!m_players.ContainsKey(playerIdx.Handle))
  34.                 {
  35.                     m_players.Add(playerIdx.Handle, new PlayerScriptData());
  36.                 }
  37.  
  38.                 await m_players[playerIdx.Handle].Run(player);
  39.             }
  40.         }
  41.  
  42.         private class PlayerScriptData
  43.         {
  44.             private PlayerVehicle m_mainVehicle;
  45.  
  46.             public async Task Run(Ped player)
  47.             {
  48.                 if ((m_mainVehicle != null) && !player.IsInVehicle(m_mainVehicle.Vehicle))
  49.                 {
  50.                     m_mainVehicle.KillAfterburner();
  51.                     m_mainVehicle = default(PlayerVehicle);
  52.                 }
  53.  
  54.                 if (player.IsInVehicle())
  55.                 {
  56.                     if ((m_mainVehicle != null) && player.CurrentVehicle.IsDriveable)
  57.                     {
  58.                         m_mainVehicle.Update();
  59.                     }
  60.  
  61.                     foreach (var vehicle in Vehicles)
  62.                     {
  63.                         if ((player.CurrentVehicle.Model == vehicle) && ((m_mainVehicle == null) || (m_mainVehicle.Handle != player.CurrentVehicle.Handle)))
  64.                         {
  65.                             m_mainVehicle = new PlayerVehicle(player.CurrentVehicle);
  66.                             await m_mainVehicle.InitializeAfterburner();
  67.                         }
  68.                     }
  69.                 }
  70.             }
  71.         }
  72.  
  73.         #region Constant Vars
  74.  
  75.         /// <summary>
  76.         ///     Scale of afterburners.
  77.         /// </summary>
  78.         public static readonly float Scale = 0.1f;
  79.  
  80.         /// <summary>
  81.         ///     Left afterburner relative offset.
  82.         /// </summary>
  83.         public static readonly Vector3 LeftOffset = new Vector3(-0.0f, -0f, 0.0f);
  84.  
  85.         /// <summary>
  86.         ///     Right afterburner relative offset.
  87.         /// </summary>
  88.         public static readonly Vector3 RightOffset = new Vector3(0.0f, -0f, 0.0f);
  89.  
  90.         /// <summary>
  91.         ///     Vehicles with afterburner support.
  92.         /// </summary>
  93.         public static readonly VehicleHash[] Vehicles =
  94.         {
  95.             (VehicleHash)0xF93D230C, // yMetalSlugA
  96.             (VehicleHash)0x0CC34A18, // yMetalSlugB
  97.         };
  98.  
  99.         #endregion
  100.     }
  101.  
  102.     public class PlayerVehicle : Entity
  103.     {
  104.         private readonly LoopedPtfx m_afterburnerL = new LoopedPtfx("core", "veh_exhaust_afterburner");
  105.         private readonly LoopedPtfx m_afterburnerR = new LoopedPtfx("core", "veh_exhaust_afterburner");
  106.  
  107.         /// <summary>
  108.         ///     Initialize the class
  109.         /// </summary>
  110.         /// <param name="vehicle"></param>
  111.         public PlayerVehicle(Vehicle vehicle) : base(vehicle.Handle)
  112.         {
  113.             Vehicle = vehicle;
  114.         }
  115.  
  116.         public Vehicle Vehicle { get; }
  117.  
  118.         /// <summary>
  119.         ///     Initialize afterburners on entitys exhaust dummies
  120.         /// </summary>
  121.         public async Task InitializeAfterburner()
  122.         {
  123.             if (!m_afterburnerL.IsLoaded)
  124.             {
  125.                 await m_afterburnerL.Load();
  126.             }
  127.  
  128.             m_afterburnerL.Start(Vehicle, Afterburners.Scale, Afterburners.LeftOffset, Vector3.Zero, (Bone)Function.Call<int>(Hash.GET_ENTITY_BONE_INDEX_BY_NAME, Vehicle, "exhaust"));
  129.             m_afterburnerR.Start(Vehicle, Afterburners.Scale, Afterburners.RightOffset, Vector3.Zero, (Bone)Function.Call<int>(Hash.GET_ENTITY_BONE_INDEX_BY_NAME, Vehicle, "exhaust_2"));
  130.             Function.Call((Hash)0xDCB194B85EF7B541, m_afterburnerL.Handle, 3000.0f);
  131.             Function.Call((Hash)0xDCB194B85EF7B541, m_afterburnerR.Handle, 3000.0f);
  132.         }
  133.  
  134.         /// <summary>
  135.         ///     Kill the afterburner FX
  136.         /// </summary>
  137.         public void KillAfterburner()
  138.         {
  139.             m_afterburnerL.Remove();
  140.             m_afterburnerR.Remove();
  141.         }
  142.  
  143.         /// <summary>
  144.         ///     Update FX based on acceleration
  145.         /// </summary>
  146.         public void Update()
  147.         {
  148.             Function.Call(Hash.SET_PARTICLE_FX_LOOPED_EVOLUTION, m_afterburnerL.Handle, "throttle", Vehicle.Acceleration, 0);
  149.             Function.Call(Hash.SET_PARTICLE_FX_LOOPED_EVOLUTION, m_afterburnerR.Handle, "throttle", Vehicle.Acceleration, 0);
  150.         }
  151.     }
  152.  
  153.     public class LoopedPtfx
  154.     {
  155.         /// <summary>
  156.         ///     Initialize the class
  157.         /// </summary>
  158.         /// <param name="assetName"></param>
  159.         /// <param name="fxName"></param>
  160.         public LoopedPtfx(string assetName, string fxName)
  161.         {
  162.             Handle = -1;
  163.             AssetName = assetName;
  164.             FxName = fxName;
  165.         }
  166.  
  167.         public int Handle { get; private set; }
  168.         public string AssetName { get; }
  169.         public string FxName { get; }
  170.  
  171.         /// <summary>
  172.         ///     If the particle FX is spawned.
  173.         /// </summary>
  174.         public bool Exists
  175.         {
  176.             get
  177.             {
  178.                 if (Handle == -1)
  179.                 {
  180.                     return false;
  181.                 }
  182.  
  183.                 return Function.Call<bool>(Hash.DOES_PARTICLE_FX_LOOPED_EXIST, Handle);
  184.             }
  185.         }
  186.  
  187.         /// <summary>
  188.         ///     If the particle FX asset is loaded.
  189.         /// </summary>
  190.         public bool IsLoaded => Function.Call<bool>(Hash.HAS_NAMED_PTFX_ASSET_LOADED, AssetName);
  191.  
  192.         /// <summary>
  193.         ///     Load the particle FX asset
  194.         /// </summary>
  195.         public async Task Load()
  196.         {
  197.             Function.Call(Hash.REQUEST_NAMED_PTFX_ASSET, AssetName);
  198.             while (!Function.Call<bool>(Hash.HAS_NAMED_PTFX_ASSET_LOADED))
  199.             {
  200.                 await BaseScript.Delay(0);
  201.             }
  202.         }
  203.  
  204.         /// <summary>
  205.         ///     Start particle FX on the specified entity.
  206.         /// </summary>
  207.         /// <param name="entity">Entity to attach to.</param>
  208.         /// <param name="scale">Scale of the fx.</param>
  209.         /// <param name="offset">Optional offset.</param>
  210.         /// <param name="rotation">Optional rotation.</param>
  211.         /// <param name="bone">Entity bone.</param>
  212.         public void Start(Entity entity, float scale, Vector3 offset, Vector3 rotation, Bone? bone)
  213.         {
  214.             if (Handle != -1)
  215.             {
  216.                 return;
  217.             }
  218.  
  219.             Function.Call(Hash._SET_PTFX_ASSET_NEXT_CALL, AssetName);
  220.  
  221.             Handle = bone == null
  222.                          ? Function.Call<int>(
  223.                                               Hash.START_PARTICLE_FX_LOOPED_ON_ENTITY,
  224.                                               FxName,
  225.                                               entity,
  226.                                               offset.X,
  227.                                               offset.Y,
  228.                                               offset.Z,
  229.                                               rotation.X,
  230.                                               rotation.Y,
  231.                                               rotation.Z,
  232.                                               scale,
  233.                                               0,
  234.                                               0,
  235.                                               1)
  236.                          : Function.Call<int>(
  237.                                               Hash._START_PARTICLE_FX_LOOPED_ON_ENTITY_BONE,
  238.                                               FxName,
  239.                                               entity,
  240.                                               offset.X,
  241.                                               offset.Y,
  242.                                               offset.Z,
  243.                                               rotation.X,
  244.                                               rotation.Y,
  245.                                               rotation.Z,
  246.                                               (int)bone,
  247.                                               scale,
  248.                                               0,
  249.                                               0,
  250.                                               0);
  251.         }
  252.  
  253.         /// <summary>
  254.         ///     Start particle FX on the specified entity.
  255.         /// </summary>
  256.         /// <param name="entity">Entity to attach to.</param>
  257.         /// <param name="scale">Scale of the fx.</param>
  258.         public void Start(Entity entity, float scale)
  259.         {
  260.             Start(entity, scale, Vector3.Zero, Vector3.Zero, null);
  261.         }
  262.  
  263.         /// <summary>
  264.         ///     Start particle FX at the specified position.
  265.         /// </summary>
  266.         /// <param name="position">Position in world space.</param>
  267.         /// <param name="scale">Scale of the fx.</param>
  268.         /// <param name="rotation">Optional rotation.</param>
  269.         public void Start(Vector3 position, float scale, Vector3 rotation)
  270.         {
  271.             if (Handle != -1)
  272.             {
  273.                 return;
  274.             }
  275.  
  276.             Function.Call(Hash._SET_PTFX_ASSET_NEXT_CALL, AssetName);
  277.  
  278.             Handle = Function.Call<int>(
  279.                                         Hash.START_PARTICLE_FX_LOOPED_AT_COORD,
  280.                                         FxName,
  281.                                         position.X,
  282.                                         position.Y,
  283.                                         position.Z,
  284.                                         rotation.X,
  285.                                         rotation.Y,
  286.                                         rotation.Z,
  287.                                         scale,
  288.                                         0,
  289.                                         0,
  290.                                         0,
  291.                                         0);
  292.         }
  293.  
  294.         /// <summary>
  295.         ///     Start particle FX at the specified position.
  296.         /// </summary>
  297.         /// <param name="position">Position in world space.</param>
  298.         /// <param name="scale">Scale of the fx.</param>
  299.         public void Start(Vector3 position, float scale)
  300.         {
  301.             Start(position, scale, Vector3.Zero);
  302.         }
  303.  
  304.         /// <summary>
  305.         ///     Remove the particle FX
  306.         /// </summary>
  307.         public void Remove()
  308.         {
  309.             if (Handle == -1)
  310.             {
  311.                 return;
  312.             }
  313.  
  314.             Function.Call(Hash.REMOVE_PARTICLE_FX, Handle, 0);
  315.             Handle = -1;
  316.         }
  317.  
  318.         /// <summary>
  319.         ///     Remove the particle FX in range
  320.         /// </summary>
  321.         public void Remove(Vector3 position, float radius)
  322.         {
  323.             if (Handle == -1)
  324.             {
  325.                 return;
  326.             }
  327.  
  328.             Function.Call(Hash.REMOVE_PARTICLE_FX_IN_RANGE, position.X, position.Y, position.Z, radius);
  329.             Handle = -1;
  330.         }
  331.  
  332.         /// <summary>
  333.         ///     Unload the loaded particle FX asset
  334.         /// </summary>
  335.         public void Unload()
  336.         {
  337.             if (IsLoaded)
  338.             {
  339.                 Function.Call((Hash)0x5F61EBBE1A00F96D, AssetName);
  340.             }
  341.         }
  342.     }
  343. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement