← 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 }