← Back to changelog
What changed
GambleAnything · v1.0.5 → v1.0.6 (current)
Diff
2 added · 2 removed · 426 → 426 total lines
1
1
/*▄▄▄ ███▄ ▄███▓ ▄████ ▄▄▄██▀▀▀▓█████▄▄▄█████▓
2
2
▓█████▄ ▓██▒▀█▀ ██▒ ██▒ ▀█▒ ▒██ ▓█ ▀▓ ██▒ ▓▒
3
3
▒██▒ ▄██▓██ ▓██░▒██░▄▄▄░ ░██ ▒███ ▒ ▓██░ ▒░
4
4
▒██░█▀ ▒██ ▒██ ░▓█ ██▓▓██▄██▓ ▒▓█ ▄░ ▓██▓ ░
5
5
░▓█ ▀█▓▒██▒ ░██▒░▒▓███▀▒ ▓███▒ ░▒████▒ ▒██▒ ░
6
6
░▒▓███▀▒░ ▒░ ░ ░ ░▒ ▒ ▒▓▒▒░ ░░ ▒░ ░ ▒ ░░
7
7
8
8
Perms:
9
9
GambleAnything.VIP1 - Win slot machines more often.
10
10
GambleAnything.VIP2 - Win slot machines most times.
11
11
GambleAnything.VIP3 - Win slot machines every time.
12
12
*/
13
13
using HarmonyLib;
14
14
using Newtonsoft.Json;
15
15
using Oxide.Core;
16
16
using Oxide.Core.Plugins;
17
17
using System;
18
18
using System.Collections.Generic;
19
19
using System.Linq;
20
20
using UnityEngine;
21
21
namespace Oxide.Plugins
22
22
{
23
-
[Info("GambleAnything", "bmgjet", "1.0.5")]
23
+
[Info("GambleAnything", "bmgjet", "1.0.6")]
24
24
class GambleAnything : RustPlugin
25
25
{
26
26
public static GambleAnything _instance;
27
27
private Dictionary<SlotMachine, SlotBetItem> SlotBets = new Dictionary<SlotMachine, SlotBetItem>();
28
28
private HashSet<string> BlackListItemsSet = new HashSet<string>();
29
29
30
30
private const string permVIP1 = "GambleAnything.VIP1";
31
31
private const string permVIP2 = "GambleAnything.VIP2";
32
32
private const string permVIP3 = "GambleAnything.VIP3";
33
33
34
34
35
35
private class SlotBetItem
36
36
{
37
37
public ItemDefinition Itemdef;
38
38
public ulong SkinId;
39
39
}
40
40
41
41
#region Confg
42
42
private Configuration config;
43
43
44
44
private class Configuration
45
45
{
46
46
[JsonProperty("Enable On SlotMachine")]
47
47
public bool Slots = true;
48
48
49
49
[JsonProperty("Slot Machine Max Multiplier")]
50
50
public int MaxMulti = 5;
51
51
52
52
[JsonProperty("Enable On BigWheel Game")]
53
53
public bool BigWheel = true;
54
54
55
55
[JsonProperty("Blacklist These Items")]
56
56
public string[] BlackListItems;
57
57
58
58
public string ToJson() => JsonConvert.SerializeObject(this);
59
59
60
60
public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
61
61
62
62
}
63
63
protected override void LoadDefaultConfig()
64
64
{
65
65
config = new Configuration(); config.BlackListItems = new string[] { "supply.signal", "grenade.beancan", "ammo.rifle.explosive", "explosives", "grenade.f1", "explosive.satchel", "explosive.timed", "ammo.rocket.hv", "ammo.rocket.fire", "ammo.rocket.mlrs", "ammo.rocket.basic", "ammo.rocket.sam", "ammo.grenadelauncher.he" };
66
66
}
67
67
68
68
protected override void LoadConfig()
69
69
{
70
70
base.LoadConfig();
71
71
try
72
72
{
73
73
config = Config.ReadObject<Configuration>();
74
74
if (config == null) { throw new JsonException(); }
75
75
if (!config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys))
76
76
{
77
77
PrintWarning("Configuration appears to be outdated; updating and saving");
78
78
SaveConfig();
79
79
}
80
80
}
81
81
catch
82
82
{
83
83
PrintWarning($"Configuration file {Name}.json is invalid; using defaults");
84
84
LoadDefaultConfig();
85
85
}
86
86
87
87
if (config.MaxMulti < 1)
88
88
{
89
89
PrintWarning("Slot Machine Max Multiplier must be at least 1; resetting to 1");
90
90
config.MaxMulti = 1;
91
91
}
92
92
93
93
RebuildBlackListSet();
94
94
}
95
95
96
96
protected override void SaveConfig()
97
97
{
98
98
PrintWarning($"Configuration changes saved to {Name}.json");
99
99
Config.WriteObject(config, true);
100
100
}
101
101
102
102
private void RebuildBlackListSet()
103
103
{
104
104
BlackListItemsSet = new HashSet<string>(config.BlackListItems ?? Array.Empty<string>());
105
105
}
106
106
#endregion
107
107
108
108
#region OxideHooks
109
109
private void Init()
110
110
{
111
111
_instance = this;
112
112
permission.RegisterPermission(permVIP1, this);
113
113
permission.RegisterPermission(permVIP2, this);
114
114
permission.RegisterPermission(permVIP3, this);
115
115
}
116
116
117
117
private void Unload()
118
118
{
119
119
SlotBets.Clear();
120
120
_instance = null;
121
121
}
122
122
123
123
private void OnEntityKill(SlotMachine slotmachine)
124
124
{
125
125
if (slotmachine != null) { SlotBets.Remove(slotmachine); }
126
126
}
127
127
#endregion
128
128
129
129
#region Methods
130
130
public ItemDefinition ScrapReplacement(SlotMachine slotmachine)
131
131
{
132
132
SlotBetItem bet;
133
133
if (SlotBets.TryGetValue(slotmachine, out bet)) { return bet.Itemdef; }
134
134
return ItemManager.FindItemDefinition("scrap");
135
135
}
136
136
137
137
public ulong SkinReplacement(SlotMachine slotmachine)
138
138
{
139
139
SlotBetItem bet;
140
140
if (SlotBets.TryGetValue(slotmachine, out bet)) { return bet.SkinId; }
141
141
return 0;
142
142
}
143
143
144
144
private int GetBettingAmount(SlotMachine slotmachine)
145
145
{
146
146
SlotMachineStorage slotMachineStorage = slotmachine.StorageInstance.Get(slotmachine.isServer) as SlotMachineStorage;
147
147
if (slotMachineStorage == null) { return 0; }
148
148
Item slot = slotMachineStorage.inventory.GetSlot(0);
149
149
if (slot != null) { return slot.amount; }
150
150
return 0;
151
151
}
152
152
153
153
public void RequestMultiplierChange(BaseEntity.RPCMessage msg, SlotMachine slotmachine)
154
154
{
155
155
if (msg.player != slotmachine.GetMounted()) { return; }
156
156
int num = msg.read.Int32();
157
157
if (num < 1) { num = config.MaxMulti; }
158
158
if (num > config.MaxMulti) { num = 1; }
159
159
slotmachine.CurrentMultiplier = Mathf.Clamp(num, 1, config.MaxMulti);
160
160
slotmachine.OnBettingScrapUpdated(GetBettingAmount(slotmachine));
161
161
slotmachine.SendNetworkUpdate(0);
162
162
}
163
163
164
164
public void Spin(SlotMachine slotmachine)
165
165
{
166
166
SlotMachineStorage slotMachineStorage = slotmachine.StorageInstance.Get(true) as SlotMachineStorage;
167
167
if (slotMachineStorage == null) { return; }
168
168
169
169
Item betSlot = slotMachineStorage.inventory.GetSlot(0);
170
170
if (betSlot == null) { return; } // Nothing staked - nothing to record as the bet item.
171
171
172
172
ulong skinId = betSlot.skin;
173
173
ItemDefinition itemDef = ItemManager.FindItemDefinition(betSlot.info.itemid);
174
174
175
175
SlotBetItem bet;
176
176
if (SlotBets.TryGetValue(slotmachine, out bet))
177
177
{
178
178
bet.Itemdef = itemDef;
179
179
bet.SkinId = skinId;
180
180
return;
181
181
}
182
182
SlotBets.Add(slotmachine, new SlotBetItem { Itemdef = itemDef, SkinId = skinId });
183
183
}
184
184
185
185
public void PayOutSlots(SlotMachine __instance)
186
186
{
187
187
bool flag = false;
188
188
SlotMachinePayoutSettings.PayoutInfo payoutInfo;
189
189
int num;
190
190
BasePlayer spinPlayer = __instance.CurrentSpinPlayer as BasePlayer;
191
191
if (__instance.PayoutSettings != null && BaseNetworkableEx.IsValid(spinPlayer) && spinPlayer == __instance.GetMounted() && CalculateBonus(out payoutInfo, out num, __instance))
192
192
{
193
193
ItemDefinition payoutItemDef = ScrapReplacement(__instance);
194
194
ulong itemskinid = SkinReplacement(__instance);
195
195
int num2 = ((int)payoutInfo.Item.amount + num) * __instance.CurrentMultiplier;
196
196
BaseEntity baseEntity = __instance.StorageInstance.Get(true);
197
197
SlotMachineStorage slotMachineStorage = baseEntity as SlotMachineStorage;
198
198
if (baseEntity != null && slotMachineStorage != null)
199
199
{
200
200
Item slot = slotMachineStorage.inventory.GetSlot(1);
201
201
if (slot != null && slot.info.itemid == payoutItemDef.itemid)
202
202
{
203
203
slot.skin = itemskinid;
204
204
slot.amount += num2;
205
205
slot.MarkDirty();
206
206
}
207
207
else
208
208
{
209
209
if (slot != null) { slot.DropAndTossUpwards(__instance.transform.position, 2f); }
210
210
ItemManager.Create(payoutItemDef, num2, itemskinid).MoveToContainer(slotMachineStorage.inventory, 1, true, false, null, true);
211
211
}
212
212
}
213
213
spinPlayer.ChatMessage(string.Format("You received {0}x {1} for slots payout!", num2, payoutItemDef.displayName.english));
214
214
if (payoutInfo.OverrideWinEffect != null && payoutInfo.OverrideWinEffect.isValid) { Effect.server.Run(payoutInfo.OverrideWinEffect.resourcePath, __instance, 0U, Vector3.zero, Vector3.zero, null, false); }
215
215
else if (__instance.PayoutSettings.DefaultWinEffect != null && __instance.PayoutSettings.DefaultWinEffect.isValid) { Effect.server.Run(__instance.PayoutSettings.DefaultWinEffect.resourcePath, __instance, 0U, Vector3.zero, Vector3.zero, null, false); }
216
216
if (payoutInfo.OverrideWinEffect == null || !payoutInfo.OverrideWinEffect.isValid) { flag = true; }
217
217
}
218
218
if (!flag) { __instance.SetFlagLocal((BaseEntity.Flags)256, false, false); __instance.SendNetworkUpdateImmediate(); }
219
219
else { __instance.Invoke(delegate { __instance.SetFlagLocal((BaseEntity.Flags)256, false, false); __instance.SendNetworkUpdateImmediate(); }, 4f); }
220
220
__instance.CurrentSpinPlayer = null;
221
221
}
222
222
223
223
private bool CalculateBonus(out SlotMachinePayoutSettings.PayoutInfo info, out int bonus, SlotMachine __instance)
224
224
{
225
225
info = default(SlotMachinePayoutSettings.PayoutInfo);
226
226
bonus = 0;
227
227
foreach (SlotMachinePayoutSettings.IndividualPayouts individualPayouts in __instance.PayoutSettings.FacePayouts)
228
228
{
229
229
__instance.CurrentSpinPlayer = null;
230
230
if (individualPayouts.Result == (int)__instance.SpinResult1)
231
231
{
232
232
bonus += (int)individualPayouts.Item.amount;
233
233
}
234
234
if (individualPayouts.Result == (int)__instance.SpinResult2)
235
235
{
236
236
bonus += (int)individualPayouts.Item.amount;
237
237
}
238
238
if (individualPayouts.Result == (int)__instance.SpinResult3)
239
239
{
240
240
bonus += (int)individualPayouts.Item.amount;
241
241
}
242
242
if (bonus > 0)
243
243
{
244
244
info.Item = new ItemAmount(individualPayouts.Item.itemDef, 0f);
245
245
}
246
246
}
247
247
foreach (SlotMachinePayoutSettings.PayoutInfo payoutInfo in __instance.PayoutSettings.Payouts)
248
248
{
249
249
if (payoutInfo.Result1 == __instance.SpinResult1 && payoutInfo.Result2 == __instance.SpinResult2 && payoutInfo.Result3 == __instance.SpinResult3)
250
250
{
251
251
info = payoutInfo;
252
252
return true;
253
253
}
254
254
}
255
255
return bonus > 0;
256
256
}
257
257
258
258
public void ModStorage(StorageContainer container, bool Allow)
259
259
{
260
260
if (Allow)
261
261
{
262
262
container.inventory.onlyAllowedItems = null;
263
263
return;
264
264
}
265
265
if (container.inventory.onlyAllowedItems == null)
266
266
{
267
267
container.inventory.SetOnlyAllowedItem(ItemManager.FindItemDefinition("scrap"));
268
268
}
269
269
}
270
270
#endregion
271
271
272
272
#region Harmony
273
273
[AutoPatch]
274
274
[HarmonyPatch(typeof(SlotMachine), "CalculateSpinResults")]
275
275
public static class SlotMachine_CalculateSpinResults
276
276
{
277
277
[HarmonyPostfix]
278
278
private static void Postfix(SlotMachine __instance)
279
279
{
280
280
BasePlayer player = __instance?._mounted;
281
281
if (player)
282
282
{
283
283
if (_instance.permission.UserHasPermission(player.UserIDString, permVIP3)) //Win every time
284
284
{
285
285
__instance.SpinResult2 = __instance.SpinResult1;
286
286
__instance.SpinResult3 = __instance.SpinResult1;
287
287
return;
288
288
}
289
289
if (_instance.permission.UserHasPermission(player.UserIDString, permVIP2))
290
290
{
291
291
if (__instance.SpinResult2 == __instance.SpinResult1 || __instance.SpinResult3 == __instance.SpinResult1) //Win most times
292
292
{
293
293
__instance.SpinResult2 = __instance.SpinResult1;
294
294
__instance.SpinResult3 = __instance.SpinResult1;
295
295
}
296
296
return;
297
297
}
298
298
if (_instance.permission.UserHasPermission(player.UserIDString, permVIP1)) //Win more
299
299
{
300
300
if (__instance.SpinResult2 == __instance.SpinResult1)
301
301
{
302
302
__instance.SpinResult3 = __instance.SpinResult1;
303
303
}
304
304
}
305
305
}
306
306
}
307
307
}
308
308
309
309
[AutoPatch]
310
310
[HarmonyPatch(typeof(SlotMachine), "Server_RequestMultiplierChange", new Type[] { typeof(BaseEntity.RPCMessage) })]
311
311
internal class SlotMachine_Server_RequestMultiplierChange
312
312
{
313
313
[HarmonyPrefix]
314
314
private static bool Prefix(BaseEntity.RPCMessage msg, SlotMachine __instance)
315
315
{
316
316
try
317
317
{
318
318
_instance.RequestMultiplierChange(msg, __instance);
319
319
return false;
320
320
}
321
321
catch { }
322
322
return true;
323
323
}
324
324
}
325
325
326
326
[AutoPatch]
327
327
[HarmonyPatch(typeof(SlotMachine), "RPC_Spin", new Type[] { typeof(BaseEntity.RPCMessage) })]
328
328
internal class SlotMachine_RPC_Spin
329
329
{
330
330
[HarmonyPrefix]
331
331
private static bool Prefix(SlotMachine __instance)
332
332
{
333
333
try
334
334
{
335
335
if (_instance.config.Slots) { _instance.Spin(__instance); }
336
336
}
337
337
catch { }
338
338
return true;
339
339
}
340
340
}
341
341
342
342
[AutoPatch]
343
343
[HarmonyPatch(typeof(SlotMachine), "CheckPayout")]
344
344
internal class SlotMachine_CheckPayout
345
345
{
346
346
[HarmonyPrefix]
347
347
private static bool Prefix(SlotMachine __instance)
348
348
{
349
349
try
350
350
{
351
351
if (_instance.config.Slots)
352
352
{
353
353
_instance.PayOutSlots(__instance);
354
354
return false;
355
355
}
356
356
}
357
357
catch { }
358
358
return true;
359
359
}
360
360
}
361
361
362
362
[AutoPatch]
363
363
[HarmonyPatch(typeof(SlotMachineStorage), "PlayerOpenLoot", new Type[] { typeof(BasePlayer), typeof(string), typeof(bool) })]
364
364
internal class SlotMachineStorage_PlayerOpenLoot
365
365
{
366
366
[HarmonyPrefix]
367
367
private static bool Prefix(BasePlayer player, SlotMachineStorage __instance)
368
368
{
369
369
try
370
370
{
371
371
if (_instance.config.Slots)
372
372
{
373
373
_instance.ModStorage(__instance, true);
374
374
}
375
375
else
376
376
{
377
377
_instance.ModStorage(__instance, false);
378
378
}
379
379
}
380
380
catch { }
381
381
return true;
382
382
}
383
383
}
384
384
385
385
[AutoPatch]
386
-
[HarmonyPatch(typeof(ItemContainer), "CanAcceptItem", new Type[] { typeof(Item), typeof(int) })]
386
+
[HarmonyPatch(typeof(ItemContainer), "CanAcceptItem", new Type[] {typeof(BasePlayer), typeof(Item), typeof(int) })]
387
387
internal class ItemContainer_CanAcceptItem
388
388
{
389
389
[HarmonyPrefix]
390
390
private static bool Prefix(Item item, int targetPos, ItemContainer __instance, ref ItemContainer.CanAcceptResult __result)
391
391
{
392
392
try
393
393
{
394
394
if (__instance.entityOwner != null && !__instance.HasFlag((ItemContainer.Flag)16) && ((__instance.entityOwner is SlotMachineStorage && _instance.config.Slots) || (__instance.entityOwner is BigWheelBettingTerminal && _instance.config.BigWheel)))
395
395
{
396
396
if (_instance.BlackListItemsSet.Contains(item.info.shortname))
397
397
{
398
398
__result = (ItemContainer.CanAcceptResult)1;
399
399
return false;
400
400
}
401
401
}
402
402
}
403
403
catch { }
404
404
return true;
405
405
}
406
406
}
407
407
408
408
[AutoPatch]
409
409
[HarmonyPatch(typeof(BigWheelBettingTerminal), "PlayerOpenLoot", new Type[] { typeof(BasePlayer), typeof(string), typeof(bool) })]
410
410
internal class BigWheelBettingTerminal_PlayerOpenLoot
411
411
{
412
412
[HarmonyPrefix]
413
413
private static bool Prefix(BasePlayer player, BigWheelBettingTerminal __instance)
414
414
{
415
415
try
416
416
{
417
417
if (_instance.config.BigWheel) { _instance.ModStorage(__instance, true); }
418
418
else { _instance.ModStorage(__instance, false); }
419
419
}
420
420
catch { }
421
421
return true;
422
422
}
423
423
}
424
424
#endregion
425
425
}
426
426
}