View difference between Paste ID: SffbY75y and 7vSKwG0M
SHOW: | | - or go back to the newest paste.
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
}