Guest User

Untitled

a guest
Jul 2nd, 2017
4,225
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Windows.Forms;
  5. using GTA;
  6. using GTA.Native;
  7. using GTA.Math;
  8. using Font = GTA.Font;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Threading.Tasks;
  12.  
  13.  
  14. public partial class SafeCrack : Script
  15. {
  16.  
  17.     private ScriptSettings KeysData;
  18.  
  19.     List<SafeCracker> Safe_Cracker = new List<SafeCracker>();
  20.  
  21.     List<Vector3> Safe_Locations = new List<Vector3>();
  22.  
  23.     List<float> Safe_Rotations = new List<float>();
  24.  
  25.     int Safe_Cracker_Intervel = 0;
  26.  
  27.     int Safe_Cracker_Time_of_Success = 0;
  28.  
  29.     int Safe_Cracker_Cooldown = 30000;
  30.  
  31.     int MinCash = 0;
  32.  
  33.     int MaxCash = 0;
  34.  
  35.     bool LoadOptionalSafes = true;
  36.  
  37.     bool LoadSafes = true;
  38.  
  39.     bool PadShake = true;
  40.  
  41.     int WantedLevel = 0;
  42.  
  43.     public SafeCrack()
  44.     {
  45.         Safe_Locations.Add(new Vector3(1735.22f, 6420.86f, 34.80502f));   // coords for safes
  46.         Safe_Locations.Add(new Vector3(1959.45f, 3749.25f, 32.10276f));
  47.         Safe_Locations.Add(new Vector3(2672.7f, 3287.05f, 55.00016f));
  48.         Safe_Locations.Add(new Vector3(546.1f, 2662.55f, 41.9243f));
  49.         Safe_Locations.Add(new Vector3(-3250.259f, 1004.763f, 12.59851f));
  50.         Safe_Locations.Add(new Vector3(-3048.12f, 585.9f, 7.6724f));
  51.         Safe_Locations.Add(new Vector3(378.55f, 333.4986f, 103.3342f));
  52.         Safe_Locations.Add(new Vector3(2549.05f, 385.23f, 108.3908f));
  53.         Safe_Locations.Add(new Vector3(28.54f, -1338.98f, 29.26483f));
  54.  
  55.         Safe_Locations.Add(new Vector3(1708.3f, 4920.4f, 41.83146f));
  56.         Safe_Locations.Add(new Vector3(-1829.558f, 798.8604f, 137.945f));
  57.         Safe_Locations.Add(new Vector3(1159.254f, -313.7326f, 68.97286f));
  58.         Safe_Locations.Add(new Vector3(-710.0f, -903.8f, 18.98339f));
  59.         Safe_Locations.Add(new Vector3(-43.4f, -1747.95f, 29.18881f));
  60.  
  61.         Safe_Rotations.Add(334.6f);   // safe heading
  62.         Safe_Rotations.Add(30.0f);
  63.         Safe_Rotations.Add(59.0f);
  64.         Safe_Rotations.Add(187.0f);
  65.         Safe_Rotations.Add(84.81945f);
  66.         Safe_Rotations.Add(108.5598f);
  67.         Safe_Rotations.Add(346.2444f);
  68.         Safe_Rotations.Add(88.7537f);
  69.         Safe_Rotations.Add(0.0f);
  70.  
  71.         Safe_Rotations.Add(324.9322f);
  72.         Safe_Rotations.Add(131.5848f);
  73.         Safe_Rotations.Add(98.38525f);
  74.         Safe_Rotations.Add(90.58581f);
  75.         Safe_Rotations.Add(50.60119f);
  76.  
  77.         KeysData = ScriptSettings.Load("scripts//SafeCracker.ini");
  78.  
  79.         Safe_Cracker_Cooldown = KeysData.GetValue<int>("settings", "CoolDown", 30000);
  80.  
  81.         MinCash = KeysData.GetValue<int>("settings", "MinCash", 500);
  82.  
  83.         MaxCash = KeysData.GetValue<int>("settings", "MaxCash", 5000);
  84.  
  85.         LoadOptionalSafes = KeysData.GetValue<bool>("settings", "LoadOptionalSafes", true);
  86.  
  87.         PadShake = KeysData.GetValue<bool>("settings", "PadShake", true);
  88.  
  89.         WantedLevel = KeysData.GetValue<int>("settings", "WantedLevel", 0);
  90.  
  91.         Tick += OnTick;
  92.  
  93.         KeyUp += OnKeyUp;
  94.  
  95.         Safe_Cracker_Intervel = (int)Game.GameTime;
  96.  
  97.     }
  98.  
  99.  
  100.     public void OnTick(object o, EventArgs e)
  101.     {
  102.         if (LoadSafes)
  103.         {
  104.             Startup();
  105.             LoadSafes = false;
  106.         }
  107.      
  108.             if (Function.Call<bool>(Hash.IS_CONTROL_JUST_PRESSED, 2, 174)) // start if dpad left
  109.             {
  110.                 if (Safe_Cracker_Time_of_Success < (int)Game.GameTime - Safe_Cracker_Cooldown) // cool down time before player can start after death
  111.                 {
  112.                     if (Safe_Cracker.Count < 1)
  113.                     {
  114.                         Prop[] tmp = World.GetNearbyProps(Game.Player.Character.Position, 2.9f); // get props
  115.  
  116.                         if (tmp.Count() > 0)
  117.                         {
  118.                             for (int i = 0; i < tmp.Count(); i++)
  119.                             {
  120.                                 if (tmp[i].Model.Hash == Function.Call<int>(Hash.GET_HASH_KEY, "v_ilev_gangsafedoor") || tmp[i].Model.Hash == -1346995970)  // if safe door
  121.                                 {
  122.                                     SafeCracker safe = new SafeCracker(); // create new safecracker
  123.  
  124.                                     Safe_Cracker.Add(safe); // add to list
  125.                                 }
  126.                             }
  127.                         }
  128.                     }
  129.                 }
  130.             }
  131.  
  132.         if (Function.Call<int>(Hash.GET_TIME_SINCE_LAST_DEATH) < Safe_Cracker_Cooldown & Function.Call<int>(Hash.GET_TIME_SINCE_LAST_DEATH) != -1)// if player dies
  133.         {
  134.             if (Safe_Cracker.Count > 0)   // check if safecracker is present
  135.             {
  136.                 if (Safe_Cracker[0].CashPickup != null)  // if cash prop exists then door is open
  137.                 {
  138.                     Prop[] tmp = World.GetNearbyProps(Safe_Cracker[0].CashPickup.Position, 2.0f);
  139.  
  140.                     for (int i = 0; i < tmp.Count(); i++)
  141.                     {
  142.                         tmp[i].Rotation = new Vector3(tmp[i].Rotation.X, tmp[i].Rotation.Y, tmp[i].Rotation.Z - 90.0f); // close door
  143.                     }
  144.  
  145.                     Safe_Cracker[0].CashPickup.Delete();   // delete cash prop
  146.                 }
  147.                 Safe_Cracker[0].RemoveSafeCracker();  // delete safecracker
  148.                 Safe_Cracker.RemoveAt(0);
  149.             }
  150.         }
  151.  
  152.        
  153.         if (Safe_Cracker.Count > 0)
  154.         {
  155.             float sclX = .3f;
  156.             float sclY = sclX;
  157.             float pozX = .5f;
  158.             float pozY = .5f;
  159.  
  160.             float aspect = Function.Call<float>(Hash._GET_SCREEN_ASPECT_RATIO, true);
  161.  
  162.             sclY = sclY * aspect;   // set x and y scale to reflect the screen aspect ratio
  163.  
  164.             if (!Safe_Cracker[0].Running) // if not running it has finnished dislay all locks open
  165.             {
  166.                 if (Safe_Cracker[0].Pin_one == true && Safe_Cracker[0].Pin_two == true && Safe_Cracker[0].Pin_three == true)
  167.                 {
  168.                     Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_open", .4f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  169.                     Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_open", .5f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  170.                     Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_open", .6f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  171.                 }
  172.             }
  173.  
  174.             if (Safe_Cracker[0].Running)
  175.             {
  176.  
  177.                 if (Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 2, 9) && Safe_Cracker[0].DirectionRight == true) // if rotating wrong way reset wheel
  178.                 {
  179.                     Function.Call(Hash._PLAY_AMBIENT_SPEECH1, Game.Player.Character, "GENERIC_CURSE_MED", "SPEECH_PARAMS_FORCE", 1);
  180.  
  181.                     Safe_Cracker[0].ResetSafe();
  182.                 }
  183.                 if (Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 2, 34) && Safe_Cracker[0].DirectionRight == false) // if rotating wrong way reset wheel
  184.                 {
  185.                     Function.Call(Hash._PLAY_AMBIENT_SPEECH1, Game.Player.Character, "GENERIC_CURSE_MED", "SPEECH_PARAMS_FORCE", 1);
  186.  
  187.                     Safe_Cracker[0].ResetSafe();
  188.                 }
  189.  
  190.                 if (!Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 2, 9) || !Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 2, 34)) // if not terning wheel play idle animation
  191.                 {
  192.                     if (!Function.Call<bool>(Hash.IS_ENTITY_PLAYING_ANIM, Game.Player.Character, "mini@safe_cracking", "idle_look_around", 3))
  193.                     {
  194.                         Game.Player.Character.Task.ClearAnimation("mini@safe_cracking", "dial_turn_clock_fast");
  195.  
  196.                         Game.Player.Character.Task.ClearAnimation("mini@safe_cracking", "dial_turn_anti_fast");
  197.  
  198.                         Function.Call(Hash.TASK_PLAY_ANIM, Game.Player.Character, "mini@safe_cracking", "idle_look_around", 1.0f, .1f, 2000, 0, .0f, 1, 1, 1);
  199.                     }
  200.                 }
  201.  
  202.                 if (Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 2, 9)) // if left input play dial_turn_anti_fast animation
  203.                 {
  204.                     Game.Player.Character.Task.ClearAnimation("mini@safe_cracking", "idle_look_around");
  205.  
  206.                     Game.Player.Character.Task.ClearAnimation("mini@safe_cracking", "dial_turn_clock_fast");
  207.                  
  208.                     if (!Function.Call<bool>(Hash.IS_ENTITY_PLAYING_ANIM, Game.Player.Character, "mini@safe_cracking", "dial_turn_anti_fast", 3))
  209.                     {
  210.  
  211.                         Function.Call(Hash.TASK_PLAY_ANIM, Game.Player.Character, "mini@safe_cracking", "dial_turn_anti_fast", 1.0f, .1f, 1000, 0, .0f, 1, 1, 1); // 64
  212.                     }
  213.                 }
  214.                 if (Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 2, 34))  // if right input play dial_turn_clock_fast animation
  215.                 {
  216.                     Game.Player.Character.Task.ClearAnimation("mini@safe_cracking", "idle_look_around");
  217.  
  218.                     Game.Player.Character.Task.ClearAnimation("mini@safe_cracking", "dial_turn_anti_fast");
  219.  
  220.                     if (!Function.Call<bool>(Hash.IS_ENTITY_PLAYING_ANIM, Game.Player.Character, "mini@safe_cracking", "dial_turn_clock_fast", 3))
  221.                     {
  222.                         Function.Call(Hash.TASK_PLAY_ANIM, Game.Player.Character, "mini@safe_cracking", "dial_turn_clock_fast", 1.0f, .1f, 1000, 0, .0f, 1, 1, 1); // 64
  223.                     }
  224.                 }
  225.  
  226.                 if (!Safe_Cracker[0].Pin_one)  // if pin one not set
  227.                 {
  228.                     Function.Call(Hash.DRAW_SPRITE, "GolfPutting", "PuttingMarker", .48f, .3f, sclX * .2f, sclY * .1f, 90.0f, 0, 255, 0, 255); // display help arrow left
  229.  
  230.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_One - 5).ToString("F2") && Safe_Cracker[0].DirectionRight == true)  // if wheel posiyion 5 away
  231.                     {
  232.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4995, .5005);   // set wheel position random position (shake)
  233.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4995, .5005);
  234.                         if (PadShake)
  235.                         {
  236.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 90);
  237.                         }
  238.                     }
  239.  
  240.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_One - 4).ToString("F2") && Safe_Cracker[0].DirectionRight == true)   // if wheel posiyion 4 away
  241.                     {
  242.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .499, .501);
  243.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .499, .501);
  244.                         if (PadShake)
  245.                         {
  246.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 100);
  247.                         }
  248.                     }
  249.  
  250.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_One - 3).ToString("F2") && Safe_Cracker[0].DirectionRight == true)  // if wheel posiyion 3 away
  251.                     {
  252.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4985, .5015);
  253.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4985, .5015);
  254.                         if (PadShake)
  255.                         {
  256.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 112);
  257.                         }
  258.                     }
  259.  
  260.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_One - 2).ToString("F2") && Safe_Cracker[0].DirectionRight == true)  // if wheel posiyion 2 away
  261.                     {
  262.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .498, .502);
  263.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .498, .502);
  264.                         if (PadShake)
  265.                         {
  266.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 130);
  267.                         }
  268.                     }
  269.  
  270.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_One - 1).ToString("F2") && Safe_Cracker[0].DirectionRight == true)  // if wheel posiyion 1 away
  271.                     {
  272.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4975, .5025);
  273.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4975, .5025);
  274.                         if (PadShake)
  275.                         {
  276.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 180);
  277.                         }
  278.                     }
  279.  
  280.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_One).ToString("F2"))  // if pin one and rotation / 3.6 are same we are at the correct position
  281.                     {
  282.  
  283.                         Wait(80);  // added this or it wont detect can change this to make harder to crack
  284.  
  285.                         if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_One).ToString("F2"))  // if pin one and rotation / 3.6 are same we are still at the correct position
  286.                         {
  287.                             Safe_Cracker[0].Pin_one = true; // set first pin to true
  288.  
  289.                             Function.Call(Hash.PLAY_SOUND_FRONTEND, 0, "TUMBLER_PIN_FALL", "SAFE_CRACK_SOUNDSET", 1);
  290.  
  291.                             Safe_Cracker[0].DirectionRight = false;  // set direction to set the next pin. If continue turning now its wrong direction and will reset dial to 0.
  292.                         }
  293.                         else
  294.                         {
  295.                             Safe_Cracker[0].ResetSafe();
  296.                         }
  297.                     }
  298.  
  299.                 }
  300.                 if (Safe_Cracker[0].Pin_one && !Safe_Cracker[0].Pin_two)  // if pin one set and pin two not set
  301.                 {
  302.  
  303.                     Function.Call(Hash.DRAW_SPRITE, "GolfPutting", "PuttingMarker", .52f, .3f, sclX * .2f, sclY * .1f, 270.0f, 0, 255, 0, 255); // display help arrow right
  304.  
  305.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Two + 5).ToString("F2") && Safe_Cracker[0].DirectionRight == false)
  306.                     {
  307.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4995, .5005);
  308.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4995, .5005);
  309.                         if (PadShake)
  310.                         {
  311.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 90);
  312.                         }
  313.                     }
  314.  
  315.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Two + 4).ToString("F2") && Safe_Cracker[0].DirectionRight == false)
  316.                     {
  317.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .499, .501);
  318.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .499, .501);
  319.                         if (PadShake)
  320.                         {
  321.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 100);
  322.                         }
  323.                     }
  324.  
  325.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Two + 3).ToString("F2") && Safe_Cracker[0].DirectionRight == false)
  326.                     {
  327.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4985, .5015);
  328.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4985, .5015);
  329.                         if (PadShake)
  330.                         {
  331.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 112);
  332.                         }
  333.                     }
  334.  
  335.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Two + 2).ToString("F2") && Safe_Cracker[0].DirectionRight == false)
  336.                     {
  337.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .498, .502);
  338.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .498, .502);
  339.                         if (PadShake)
  340.                         {
  341.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 130);
  342.                         }
  343.                     }
  344.  
  345.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Two + 1).ToString("F2") && Safe_Cracker[0].DirectionRight == false)
  346.                     {
  347.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4975, .5025);
  348.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4975, .5025);
  349.                         if (PadShake)
  350.                         {
  351.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 180);
  352.                         }
  353.                     }
  354.  
  355.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Two).ToString("F2"))
  356.                     {
  357.  
  358.                         Wait(80);
  359.  
  360.                         if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Two).ToString("F2"))
  361.                         {
  362.  
  363.                             Safe_Cracker[0].Pin_two = true;
  364.  
  365.                             Function.Call(Hash.PLAY_SOUND_FRONTEND, 0, "TUMBLER_PIN_FALL", "SAFE_CRACK_SOUNDSET", 1);
  366.  
  367.                             Safe_Cracker[0].DirectionRight = true;
  368.  
  369.                         }
  370.                         else
  371.                         {
  372.                             Safe_Cracker[0].ResetSafe();
  373.                         }
  374.                     }
  375.                 }
  376.  
  377.                 if (Safe_Cracker[0].Pin_one && Safe_Cracker[0].Pin_two && !Safe_Cracker[0].Pin_three)  // if pin one and two are set and three is not
  378.                 {
  379.  
  380.                     Function.Call(Hash.DRAW_SPRITE, "GolfPutting", "PuttingMarker", .48f, .3f, sclX * .2f, sclY * .1f, 90.0f, 0, 255, 0, 255);   // display help arrow left
  381.  
  382.  
  383.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Three - 5).ToString("F2") && Safe_Cracker[0].DirectionRight == true)
  384.                     {
  385.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4995, .5005);
  386.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4995, .5005);
  387.                         if (PadShake)
  388.                         {
  389.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 90);
  390.                         }
  391.                     }
  392.  
  393.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Three - 4).ToString("F2") && Safe_Cracker[0].DirectionRight == true)
  394.                     {
  395.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .499, .501);
  396.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .499, .501);
  397.                         if (PadShake)
  398.                         {
  399.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 100);
  400.                         }
  401.                     }
  402.  
  403.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Three - 3).ToString("F2") && Safe_Cracker[0].DirectionRight == true)
  404.                     {
  405.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4985, .5015);
  406.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4985, .5015);
  407.                         if (PadShake)
  408.                         {
  409.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 112);
  410.                         }
  411.                     }
  412.  
  413.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Three - 2).ToString("F2") && Safe_Cracker[0].DirectionRight == true)
  414.                     {
  415.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .498, .502);
  416.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .498, .502);
  417.                         if (PadShake)
  418.                         {
  419.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 130);
  420.                         }
  421.                     }
  422.  
  423.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Three - 1).ToString("F2") && Safe_Cracker[0].DirectionRight == true)
  424.                     {
  425.                         pozX = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4975, .5025);
  426.                         pozY = Function.Call<float>(Hash.GET_RANDOM_FLOAT_IN_RANGE, .4975, .5025);
  427.                         if (PadShake)
  428.                         {
  429.                             Function.Call(Hash.SET_PAD_SHAKE, 0, 300, 180);
  430.                         }
  431.                     }
  432.  
  433.                     if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Three).ToString("F2"))  // if last pin done
  434.                     {
  435.  
  436.                         Wait(80);
  437.  
  438.                         if (Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 2, 34))  // if still turning dial reset to 0.
  439.                         {
  440.                             Safe_Cracker[0].ResetSafe();
  441.                         }
  442.  
  443.                         if ((Safe_Cracker[0].Rotation / 3.6).ToString("F2") == (Safe_Cracker[0].Number_Three).ToString("F2")) // if still dial and pin are same
  444.                         {
  445.                             Safe_Cracker[0].Pin_three = true;
  446.  
  447.                             Function.Call(Hash.PLAY_SOUND_FRONTEND, 0, "TUMBLER_PIN_FALL_FINAL", "SAFE_CRACK_SOUNDSET", 1);
  448.  
  449.                             Safe_Cracker[0].DirectionRight = false;
  450.  
  451.                             Function.Call(Hash.TASK_PLAY_ANIM, Game.Player.Character, "mini@safe_cracking", "door_open_succeed_stand", 1.0f, .1f, 1000, 0, .0f, 1, 1, 1); // 64
  452.  
  453.                             Wait(2400);  // wait for task so it looks like door is opening by player
  454.  
  455.                             Prop[] tmp = World.GetNearbyProps(Game.Player.Character.Position, 2.0f);    // get near props
  456.  
  457.                             if (tmp.Count() > 0)
  458.                             {
  459.                                 for (int i = 0; i < tmp.Count(); i++)
  460.                                 {
  461.                                     if (tmp[i].Model.Hash == Function.Call<int>(Hash.GET_HASH_KEY, "v_ilev_gangsafedoor") || tmp[i].Model.Hash == -1346995970) // check if is safe door
  462.                                     {
  463.  
  464.                                         Game.Player.Character.FreezePosition = false; // Unfreeze player
  465.  
  466.                                         tmp[i].Rotation = new Vector3(tmp[i].Rotation.X, tmp[i].Rotation.Y, tmp[i].Rotation.Z + 90.0f); // set door open
  467.  
  468.                                         Function.Call(Hash.PLAY_SOUND_FRONTEND, 0, "SAFE_DOOR_OPEN", "SAFE_CRACK_SOUNDSET", 1);
  469.  
  470.                                         Game.Player.Character.Position = Game.Player.Character.Position + Game.Player.Character.ForwardVector * -.05f + Game.Player.Character.UpVector * -.7f; // move player back
  471.  
  472.                                         //Wait(1000);
  473.  
  474.                                         var model = new Model("prop_money_bag_01");
  475.                                         model.Request(250);
  476.  
  477.                                         if (model.IsInCdImage && model.IsValid)
  478.                                         {
  479.  
  480.                                             while (!model.IsLoaded) Script.Wait(50);
  481.  
  482.                                             Prop pickup = World.CreateProp(model, Game.Player.Character.Position + Game.Player.Character.ForwardVector * .8f + Game.Player.Character.RightVector * .15f + Game.Player.Character.UpVector * -.4f, new Vector3(0.0f, 0.0f, 0.0f), false, false); // create money prop
  483.                                             Wait(1000);
  484.                                             Safe_Cracker[0].CashPickup = pickup; // set to safecracker cash pickup (prop)
  485.  
  486.                                         }
  487.  
  488.                                         model.MarkAsNoLongerNeeded();
  489.  
  490.                                         Game.Player.Character.FreezePosition = false;   // give back control to player
  491.  
  492.                                         Function.Call(Hash.SET_PED_CAN_SWITCH_WEAPON, true);
  493.  
  494.                                     }
  495.                                 }
  496.                             }
  497.  
  498.                             Safe_Cracker[0].Running = false;  // now all locks open can be displayed
  499.  
  500.                         }
  501.                     }
  502.  
  503.                 }
  504.  
  505.                 if (Safe_Cracker[0].Running == true) // displays dial and locks when running
  506.                 {
  507.                     Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "Dial_BG", pozX, pozY, sclX, sclY, 0.0f, 255, 255, 255, 255);
  508.                     Function.Call(Hash._SET_2D_LAYER, 4);
  509.  
  510.                     Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "Dial", pozX, pozY, sclX * .5f, sclY * .5f, 0 - Safe_Cracker[0].Rotation, 255, 255, 255, 255);
  511.  
  512.                     //     lock_closed   lock_closed_dark  lock_open   lock_open_dark
  513.                     if (Safe_Cracker[0].Pin_one == false && Safe_Cracker[0].Pin_two == false && Safe_Cracker[0].Pin_three == false)
  514.                     {
  515.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_closed", .4f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  516.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_closed", .5f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  517.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_closed", .6f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  518.                     }
  519.  
  520.                     if (Safe_Cracker[0].Pin_one == true && Safe_Cracker[0].Pin_two == false && Safe_Cracker[0].Pin_three == false)
  521.                     {
  522.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_open", .4f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  523.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_closed", .5f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  524.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_closed", .6f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  525.                     }
  526.  
  527.                     if (Safe_Cracker[0].Pin_one == true && Safe_Cracker[0].Pin_two == true && Safe_Cracker[0].Pin_three == false)
  528.                     {
  529.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_open", .4f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  530.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_open", .5f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  531.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_closed", .6f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  532.                     }
  533.                     if (Safe_Cracker[0].Pin_one == true && Safe_Cracker[0].Pin_two == true && Safe_Cracker[0].Pin_three == true)
  534.                     {
  535.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_open", .4f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  536.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_open", .5f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  537.                         Function.Call(Hash.DRAW_SPRITE, "MPSafeCracking", "lock_open", .6f, .8f, sclX * .2f, sclY * .2f, 0.0f, 255, 255, 255, 255);
  538.                     }
  539.  
  540.                 }
  541.  
  542.                 if (Function.Call<bool>(Hash.IS_CONTROL_JUST_PRESSED, 2, 34))  // sets speed that wheel can turn
  543.                 {
  544.                     Safe_Cracker[0].RotateAntiClock();
  545.                     Safe_Cracker_Intervel = (int)Game.GameTime;
  546.                 }
  547.                 if (Function.Call<bool>(Hash.IS_CONTROL_JUST_PRESSED, 2, 9))
  548.                 {
  549.                     Safe_Cracker[0].RotateClock();
  550.                     Safe_Cracker_Intervel = (int)Game.GameTime;
  551.                 }
  552.  
  553.                 if (Safe_Cracker_Intervel < (int)Game.GameTime - 250)   // sets speed that wheel can turn
  554.                 {
  555.                     if (Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 2, 34))
  556.                     {
  557.                         Safe_Cracker[0].RotateAntiClock();
  558.                     }
  559.                     if (Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 2, 9))
  560.                     {
  561.                         Safe_Cracker[0].RotateClock();
  562.                     }
  563.                 }
  564.  
  565.             }
  566.  
  567.             if (Safe_Cracker.Count > 0)  // check if player collected moneybag
  568.             {
  569.                 if (Safe_Cracker[0].Running == false) // all pins are true cracking done
  570.                 {
  571.                     if (Safe_Cracker[0].CashPickup != null) // if cash pickup exists
  572.                     {
  573.                         float dis = World.GetDistance(Game.Player.Character.Position, Safe_Cracker[0].CashPickup.Position);
  574.                         Prop[] tmp = World.GetNearbyProps(Game.Player.Character.Position, 2.0f);
  575.  
  576.                         if (dis < 1.2f) // check distance from pickup
  577.                         {
  578.                             Function.Call(Hash.PLAY_SOUND_FRONTEND, 2, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", 1);
  579.  
  580.                             Game.Player.Money += Function.Call<int>(Hash.GET_RANDOM_INT_IN_RANGE, MinCash, MaxCash); // give player cash
  581.  
  582.                             Safe_Cracker[0].CashPickup.Delete();
  583.                             Safe_Cracker[0].RemoveSafeCracker();
  584.                             Safe_Cracker.RemoveAt(0);
  585.  
  586.                             Wait(1500);
  587.  
  588.                             for (int i = 0; i < tmp.Count(); i++)
  589.                             {
  590.                                 if (tmp[i].Model.Hash == Function.Call<int>(Hash.GET_HASH_KEY, "v_ilev_gangsafedoor") || tmp[i].Model.Hash == -1346995970)
  591.                                 {
  592.                                     tmp[i].Rotation = new Vector3(tmp[i].Rotation.X, tmp[i].Rotation.Y, tmp[i].Rotation.Z - 90.0f);// close door
  593.                                 }
  594.                             }
  595.  
  596.                             if ( WantedLevel > 0)
  597.                             {
  598.                                 if (Game.Player.WantedLevel <= WantedLevel)
  599.                                 {
  600.                                     Game.Player.WantedLevel = WantedLevel;
  601.                                 }
  602.                             }
  603.  
  604.                             Safe_Cracker_Time_of_Success = (int)Game.GameTime;
  605.                         }
  606.                     }
  607.                 }
  608.             }
  609.  
  610.             if (Safe_Cracker.Count > 0) //  check if user wants to quit
  611.             {
  612.                 if (Safe_Cracker[0].Pin_three == false)
  613.                 {
  614.                     bool D_Pad_Right = Function.Call<bool>(Hash.IS_DISABLED_CONTROL_PRESSED, 2, 74);
  615.                     bool key_Right = Function.Call<bool>(Hash.IS_DISABLED_CONTROL_PRESSED, 2, 175);
  616.  
  617.                     DisplayHelpTextThisFrame("select ~INPUT_FRONTEND_RIGHT~ to quit");
  618.  
  619.                     if (D_Pad_Right || key_Right && !Safe_Cracker[0].Pin_three)
  620.                     {
  621.                         if (Safe_Cracker.Count > 0)
  622.                         {
  623.  
  624.                             if (Safe_Cracker[0].CashPickup != null)
  625.                             {
  626.                                 Safe_Cracker[0].CashPickup.Delete();
  627.                             }
  628.  
  629.                             Safe_Cracker[0].RemoveSafeCracker();
  630.                             Safe_Cracker.RemoveAt(0);
  631.  
  632.                         }
  633.                     }
  634.                 }
  635.             }
  636.  
  637.         }
  638.         //Game.Player.WantedLevel = 0; // used during testing
  639.     }
  640.    
  641.  
  642.     public void OnKeyUp(object o, KeyEventArgs e)
  643.     {
  644.  
  645.         KeysData = ScriptSettings.Load("scripts//SafeCracker.ini");
  646.  
  647.         Keys StartKey = KeysData.GetValue<Keys>("settings", "StartKey", Keys.U);
  648.  
  649.         //if (e.KeyCode == Keys.Y)   // used during testing
  650.         //{
  651.         //    if (Safe_Cracker.Count > 0)
  652.         //    {
  653.         //        if (Safe_Cracker[0].CashPickup != null)
  654.         //        {
  655.         //            Prop[] tmp = World.GetNearbyProps(Safe_Cracker[0].CashPickup.Position, 2.0f);  
  656.  
  657.         //            for (int i = 0; i < tmp.Count(); i++)
  658.         //            {
  659.         //                tmp[i].Rotation = new Vector3(tmp[i].Rotation.X, tmp[i].Rotation.Y, tmp[i].Rotation.Z - 90.0f);
  660.         //            }
  661.  
  662.         //            Safe_Cracker[0].CashPickup.Delete();
  663.         //        }
  664.  
  665.         //        Safe_Cracker[0].RemoveSafeCracker();
  666.         //        Safe_Cracker.RemoveAt(0);
  667.         //    }
  668.         //}
  669.  
  670.         if (e.KeyCode == StartKey)
  671.         {
  672.             if (Safe_Cracker_Time_of_Success < (int)Game.GameTime - Safe_Cracker_Cooldown) // cool down time before player can start after death
  673.             {
  674.                 if (Safe_Cracker.Count < 1)
  675.                 {
  676.                     Prop[] tmp = World.GetNearbyProps(Game.Player.Character.Position, 2.9f); // get props
  677.  
  678.                     if (tmp.Count() > 0)
  679.                     {
  680.                         for (int i = 0; i < tmp.Count(); i++)
  681.                         {
  682.                             if (tmp[i].Model.Hash == Function.Call<int>(Hash.GET_HASH_KEY, "v_ilev_gangsafedoor") || tmp[i].Model.Hash == -1346995970)  // if safe door
  683.                             {
  684.                                 SafeCracker safe = new SafeCracker(); // create new safecracker
  685.  
  686.                                 Safe_Cracker.Add(safe); // add to list
  687.                             }
  688.                         }
  689.                     }
  690.                 }
  691.             }
  692.         }
  693.  
  694.         //if (e.KeyCode == Keys.O)  // used during testing
  695.         //{
  696.         //    Prop[] tmp = World.GetNearbyProps(Game.Player.Character.Position, 2.0f);  
  697.  
  698.         //    if (tmp.Count() > 0)
  699.         //    {
  700.         //        for (int i = 0; i < tmp.Count(); i++)
  701.         //        {
  702.         //            if (tmp[i].Model.Hash == Function.Call<int>(Hash.GET_HASH_KEY, "v_ilev_gangsafedoor") || tmp[i].Model.Hash == -1346995970)
  703.         //            {
  704.         //                tmp[i].Rotation = new Vector3(tmp[i].Rotation.X, tmp[i].Rotation.Y, tmp[i].Rotation.Z - 90.0f);
  705.         //            }
  706.         //        }
  707.         //    }
  708.         //}
  709.  
  710.     }
  711.    
  712.     public class SafeCracker
  713.     {
  714.  
  715.         public SafeCracker()
  716.         {
  717.          
  718.             Function.Call(Hash.REQUEST_STREAMED_TEXTURE_DICT, "GolfPutting", 0);   // request images and animations
  719.  
  720.             Function.Call(Hash.REQUEST_STREAMED_TEXTURE_DICT, "MPSafeCracking", false);
  721.  
  722.             Function.Call(Hash.REQUEST_ANIM_DICT, "mini@safe_cracking");
  723.  
  724.             while (!Function.Call<bool>(Hash.HAS_ANIM_DICT_LOADED, "mini@safe_cracking") &&   // wait for all to load
  725.                 !Function.Call<bool>(Hash.REQUEST_AMBIENT_AUDIO_BANK, "SAFE_CRACK", 0, 0) &&
  726.                 !Function.Call<bool>(Hash.REQUEST_AMBIENT_AUDIO_BANK, "DLC_Biker_Cracked_Sounds", 0, 1) &&
  727.                 !Function.Call<bool>(Hash.HAS_STREAMED_TEXTURE_DICT_LOADED, "mini@safe_cracking") &&
  728.                 !Function.Call<bool>(Hash.HAS_STREAMED_TEXTURE_DICT_LOADED, "GolfPutting"))
  729.             {
  730.                 Wait(0);  
  731.             }
  732.  
  733.  
  734.             this.Running = true;  // sets to check pin positions
  735.  
  736.             this.DirectionRight = true;  // used so can only turn right for first number
  737.  
  738.             this.Rotation = 0.0f;   // used to set dial position to zero
  739.  
  740.             this.Pin_one = false; // set all three pins to false
  741.  
  742.             this.Pin_two = false;
  743.  
  744.             this.Pin_three = false;
  745.  
  746.             this.Number_One = Function.Call<int>(Hash.GET_RANDOM_INT_IN_RANGE, 10, 90); // set all three pin numbers to random 10 - 90
  747.  
  748.             this.Number_Two = Function.Call<int>(Hash.GET_RANDOM_INT_IN_RANGE, 10, 90);
  749.  
  750.             this.Number_Three = Function.Call<int>(Hash.GET_RANDOM_INT_IN_RANGE, 10, 90);
  751.             //this.Number_One = 10;  // for testing
  752.  
  753.             //this.Number_Two = 90;
  754.  
  755.             //this.Number_Three = 10;
  756.  
  757.             Game.Player.Character.Weapons.Give(WeaponHash.Unarmed, 0, true, true);
  758.  
  759.             //Function.Call(Hash.SET_FOLLOW_PED_CAM_VIEW_MODE, 1);
  760.  
  761.             Function.Call(Hash.SET_PED_CAN_SWITCH_WEAPON, false);
  762.  
  763.  
  764.             Prop[] tmp = World.GetNearbyProps(Game.Player.Character.Position, 3.0f);  // get nerby props to get the door to set player position in front and facing safe
  765.  
  766.             if (tmp.Count() > 0)
  767.             {
  768.                 for (int i = 0; i < tmp.Count(); i++)
  769.                 {
  770.  
  771.                     if (tmp[i].Model.Hash == Function.Call<int>(Hash.GET_HASH_KEY, "v_ilev_gangsafedoor") || tmp[i].Model.Hash == -1346995970)
  772.                     {
  773.                         Game.Player.Character.FreezePosition = true;
  774.                             // optional points the camara at safe not used anymore
  775.                         //var cam = World.CreateCamera(tmp[i].Position + tmp[i].ForwardVector * -2.0f + tmp[i].RightVector * -.22f + tmp[i].UpVector * +.5f, new Vector3(0.0f, 0.0f, 0.0f), 60f);
  776.                         //cam.Shake(CameraShake.Hand, 1.0f);
  777.                         //cam.PointAt(tmp[i].Position + tmp[i].UpVector * .1f);
  778.  
  779.                         //Camera camcur = Function.Call<Camera>(Hash.GET_RENDERING_CAM);
  780.                         //Function.Call(Hash.SET_CAM_ACTIVE_WITH_INTERP, cam, camcur, 1500, false, false);
  781.                         //Function.Call(Hash.RENDER_SCRIPT_CAMS, 1, 1, cam, 1, 1);
  782.  
  783.                         Game.Player.Character.Position = tmp[i].Position + tmp[i].ForwardVector * -.5f + tmp[i].RightVector * -.66f + tmp[i].UpVector * -.8f; // set player position in front of safe
  784.                         Game.Player.Character.Heading = tmp[i].Heading - 10.0f;
  785.  
  786.                         //Wait(1000);
  787.  
  788.                     }
  789.                 }
  790.                 for (int i = 0; i < tmp.Count(); i++)
  791.                 {
  792.                     if (tmp[i].Model.Hash == 1785922871 || tmp[i].Model.Hash == -170500011)  // remove props phone an coffee from inside safe
  793.                     {
  794.                         tmp[i].Delete();
  795.  
  796.                     }
  797.                 }
  798.             }
  799.         }
  800.  
  801.         public Prop CashPickup; // veriable to hold moneybag prop
  802.  
  803.         public bool Running;
  804.  
  805.         public bool DirectionRight;
  806.  
  807.         public bool Pin_one;
  808.  
  809.         public bool Pin_two;
  810.  
  811.         public bool Pin_three;
  812.  
  813.         public int Number_One;
  814.  
  815.         public int Number_Two;
  816.  
  817.         public int Number_Three;
  818.  
  819.         public float Rotation;
  820.  
  821.         public void RotateClock()  // funtion to rotate wheel
  822.         {
  823.             if (Rotation > 0.0f)
  824.             {
  825.                 Rotation -= 3.6f;
  826.             }
  827.             else
  828.             {
  829.                 Rotation = 356.4f;
  830.             }
  831.  
  832.             Function.Call(Hash.PLAY_SOUND_FRONTEND, 0, "TUMBLER_TURN", "SAFE_CRACK_SOUNDSET", 1);
  833.  
  834.         }
  835.  
  836.         public void RotateAntiClock()  // funtion to rotate wheel cc
  837.         {
  838.  
  839.             if (Rotation < 356.4f)
  840.             {
  841.                 Rotation += 3.6f;
  842.             }
  843.             else
  844.             {
  845.                 Rotation = 0.0f;
  846.             }
  847.  
  848.             Function.Call(Hash.PLAY_SOUND_FRONTEND, 0, "TUMBLER_TURN", "SAFE_CRACK_SOUNDSET", 1);
  849.  
  850.         }
  851.  
  852.         public void RemoveSafeCracker() // funtion to remove when canciling or complete
  853.         {
  854.  
  855.             Function.Call(Hash.SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED, "GolfPutting");
  856.  
  857.             Function.Call(Hash.SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED, "MPSafeCracking");
  858.  
  859.             Function.Call(Hash.REMOVE_ANIM_DICT, "mini@safe_cracking");
  860.  
  861.             Function.Call(Hash.RELEASE_NAMED_SCRIPT_AUDIO_BANK, "SAFE_CRACK");
  862.  
  863.             Function.Call(Hash.RELEASE_NAMED_SCRIPT_AUDIO_BANK, "DLC_Biker_Cracked_Sounds");
  864.  
  865.             Function.Call(Hash.STOP_SOUND, -1);
  866.  
  867.             Function.Call(Hash.RELEASE_SOUND_ID, -1);
  868.  
  869.             Game.Player.Character.FreezePosition = false;
  870.  
  871.             Function.Call(Hash.SET_PED_CAN_SWITCH_WEAPON, true);
  872.  
  873.             Game.Player.Character.Task.ClearAllImmediately();
  874.  
  875.             //World.DestroyAllCameras(); // not needed anymore
  876.  
  877.             World.RenderingCamera = null;
  878.  
  879.         }
  880.  
  881.         public void ResetSafe() // resets safe called when turning wrong way
  882.         {
  883.             this.Rotation = 0.0f;
  884.  
  885.             this.DirectionRight = true;
  886.  
  887.             this.Pin_one = false;
  888.  
  889.             this.Pin_two = false;
  890.  
  891.             this.Pin_three = false;
  892.  
  893.             Function.Call(Hash.PLAY_SOUND_FRONTEND, -1, "TUMBLER_RESET", "SAFE_CRACK_SOUNDSET", 1);
  894.  
  895.         }
  896.  
  897.     }
  898.  
  899.      void Startup()
  900.     {
  901.         for (int i = 0; i < Safe_Locations.Count; i++)// check at each location if a safe or door exists delete them so we dont spawn more than we need if scripts are reloaded
  902.         {
  903.             Prop[] tmp = World.GetNearbyProps(Safe_Locations[i], 2.0f);
  904.  
  905.             for (int i2 = 0; i2 < tmp.Count(); i2++)
  906.             {
  907.                 if (tmp[i2].Model.Hash == Function.Call<int>(Hash.GET_HASH_KEY, "v_ilev_gangsafedoor") || tmp[i2].Model.Hash == Function.Call<int>(Hash.GET_HASH_KEY, "v_ilev_gangsafe"))
  908.                 {
  909.                     tmp[i2].Delete();
  910.                 }
  911.             }
  912.         }
  913.  
  914.         if (LoadOptionalSafes)
  915.         {
  916.             for (int i = 0; i < Safe_Locations.Count; i++) // spawn a safe and door at each location
  917.             {
  918.                 var model = new Model("v_ilev_gangsafe");
  919.                 model.Request(250);
  920.  
  921.                 if (model.IsInCdImage && model.IsValid)
  922.                 {
  923.                     while (!model.IsLoaded) Script.Wait(50);
  924.  
  925.                     Prop myprop = World.CreateProp(model, new Vector3(Safe_Locations[i].X, Safe_Locations[i].Y, Safe_Locations[i].Z - .8f), new Vector3(0.0f, 0.0f, Safe_Rotations[i]), false, false);
  926.                    
  927.                     Function.Call(Hash.SET_ENTITY_LOAD_COLLISION_FLAG, myprop.Handle, true);
  928.                     myprop.LodDistance = 10;
  929.                     myprop.IsPersistent = true;
  930.                     model.MarkAsNoLongerNeeded();
  931.  
  932.                     var model2 = new Model("v_ilev_gangsafedoor");
  933.                     model2.Request(250);
  934.  
  935.                     if (model2.IsInCdImage && model2.IsValid)
  936.                     {
  937.                         while (!model2.IsLoaded) Script.Wait(50);
  938.  
  939.                         Prop myprop2 = World.CreateProp(model2, new Vector3(myprop.Position.X, myprop.Position.Y, myprop.Position.Z - .68f), new Vector3(0.0f, 0.0f, myprop.Heading), false, false);
  940.  
  941.                         Function.Call(Hash.SET_ENTITY_LOAD_COLLISION_FLAG, myprop2.Handle, true);
  942.                         myprop.LodDistance = 10;
  943.  
  944.                         myprop.IsPersistent = true;
  945.                         myprop2.HasCollision = true;
  946.                         model2.MarkAsNoLongerNeeded();
  947.                     }
  948.                 }
  949.             }
  950.         }
  951.     }
  952.  
  953.     void DisplayHelpTextThisFrame(string text) // used to display quit message. credit jedijosh920 for this function
  954.     {
  955.         Function.Call(Hash._SET_TEXT_COMPONENT_FORMAT, "STRING");
  956.         Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, text);
  957.         Function.Call(Hash._0x238FFE5C7B0498A6, 0, 0, 1, -1);
  958.     }
  959.  
  960. }
RAW Paste Data