C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;
using System.Linq;
using System.IO;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Newtonsoft.Json;
namespace Oxide.Plugins
{
[Info("Fancy Grenades", "PaiN", "0.1.3")]
[Description("Adds different types of grenades to the game.")]
class FancyGrenades : RustPlugin
{
[PluginReference]
private Plugin Economics, ServerRewards;
const int GrenadeId = 143803535;
private Configuration config;
private ItemDefinition item;
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["PURCHASE_SUCCESS"] = "You have successfully purchased a {0} for {1} {2}",
["GIVE_FREE"] = "You have been given a {0}",
["NO_PERMISSION"] = "You do not have permission to use this command!",
["PURCHASE_FAILED"] = "You do not have enough {0}! You are missing {1} {2}",
["INVENTORY_FULL"] = "Your inventory is full!"
}, this);
}
private class Configuration
{
[JsonProperty("General Settings")]
public GeneralSettings settings = new GeneralSettings();
[JsonProperty("Flashbang Settings")]
public FlashSettings flash = new FlashSettings();
[JsonProperty("Molotov Settings")]
public MollySettings molly = new MollySettings();
[JsonProperty("Pay Settings")]
public PaySettings pay = new PaySettings();
}
public class GeneralSettings
{
[JsonProperty("Purchase Flashbang Command")]
public string flashCmd = "flash";
[JsonProperty("Purchase Molotov Command")]
public string mollyCmd = "molly";
[JsonProperty("Message SteamID icon")]
public ulong chatId = 0;
}
public class PaySettings
{
[JsonProperty("Cost Item (Scrap, ServerRewards, Economics)")]
public string costItem = "Scrap";
[JsonProperty("Cost Amount (Disable Cost = 0)")]
public int costAmount = 100;
}
public class MollySettings
{
[JsonProperty("Molotov Grenade Name")]
public string Name = "Incendiary Grenade";
[JsonProperty("Molotov SkinId")]
public ulong SkinId = 856483901;
}
public class FlashSettings
{
[JsonProperty("Flashbang Grenade Name")]
public string Name = "Stun Grenade";
[JsonProperty("Flashbang SkinId")]
public ulong SkinId = 815540662;
[JsonProperty("Flashbang Range")]
public int Range = 20;
[JsonProperty("Flashbang Duration")]
public float Duration = 2f;
[JsonProperty("Disable flashing players who are not facing the grenade")]
public bool NoFlashRule = true;
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<Configuration>();
if (config == null)
{
LoadDefaultConfig();
}
}
catch
{
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig()
{
string configPath = $"{Interface.Oxide.ConfigDirectory}{Path.DirectorySeparatorChar}{Name}.json";
PrintWarning($"Could not load a valid configuration file, creating a new configuration file at {configPath}");
config = new Configuration();
}
protected override void SaveConfig() => Config.WriteObject(config);
void Loaded()
{
permission.RegisterPermission("fancygrenades.useflash", this);
permission.RegisterPermission("fancygrenades.ignoreflash", this);
permission.RegisterPermission("fancygrenades.usemolly", this);
cmd.AddChatCommand(config.settings.flashCmd, this, cmdFlash);
cmd.AddChatCommand(config.settings.mollyCmd, this, cmdMolly);
}
void OnServerInitialized()
{
if (config.pay.costItem.Equals("serverrewards", StringComparison.OrdinalIgnoreCase) && !ServerRewards)
{
PrintWarning("Selected payment type is set to ServerRewards but ServerRewards plugin is not loaded! Unloading the plugin...");
Interface.Oxide.UnloadPlugin("FancyGrenades");
return;
}
if (config.pay.costItem.Equals("economics", StringComparison.OrdinalIgnoreCase) && !Economics)
{
PrintWarning("Selected payment type is set to Economics but Economics plugin is not loaded! Unloading the plugin...");
Interface.Oxide.UnloadPlugin("FancyGrenades");
return;
}
if (!config.pay.costItem.Equals("serverrewards", StringComparison.OrdinalIgnoreCase) &&
!config.pay.costItem.Equals("economics", StringComparison.OrdinalIgnoreCase))
{
item = ItemManager.FindItemDefinition(config.pay.costItem);
if (item == null)
{
PrintWarning($"Item set in config '{config.pay.costItem}' is not correct! Unloading the plugin...");
Interface.Oxide.UnloadPlugin("FancyGrenades");
return;
}
}
}
private void OnExplosiveThrown(BasePlayer player, BaseEntity entity, ThrownWeapon wep)
{
if (player.IsNpc || entity == null || wep == null) return;
Item nade = wep?.GetItem();
if (string.IsNullOrWhiteSpace(nade.name)) return;
if (permission.UserHasPermission(player.UserIDString, "fancygrenades.useflash"))
{
if (nade.name.Equals(config.flash.Name, StringComparison.OrdinalIgnoreCase))
{
timer.Once(2.9f, () =>
{
entity.Kill();
Effect.server.Run("assets/bundled/prefabs/fx/weapons/landmine/landmine_explosion.prefab", entity.transform.position);
foreach (var closePlayer in GetPlayersInRadius(entity.transform.position, config.flash.Range))
{
if (permission.UserHasPermission(closePlayer.UserIDString, "fancygrenades.ignoreflash")) continue;
if (config.flash.NoFlashRule && !InNadeAngle(player, entity)) continue;
FlashEffect(closePlayer);
}
});
return;
}
}
if (permission.UserHasPermission(player.UserIDString, "fancygrenades.usemolly"))
{
if (nade.name.Equals(config.molly.Name, StringComparison.OrdinalIgnoreCase))
{
timer.Once(2.5f, () =>
{
entity.Kill();
FireEffect(entity.transform.position);
});
}
}
}
private void OnExplosiveDropped(BasePlayer player, BaseEntity entity, ThrownWeapon item) => OnExplosiveThrown(player, entity, item);
[ConsoleCommand("fg.give")]
void cmdGive(ConsoleSystem.Arg arg)
{
if (arg.IsClientside || !arg.IsRcon) return;
if (arg.Args == null || arg.Args.Length == 0)
{
arg.ReplyWith("fg.give <flash/molly> <nameOrIdOrIP>");
return;
}
if (arg.Args[0] != "flash" && arg.Args[0] != "molly")
{
arg.ReplyWith("Wrong grenade type specified!");
return;
}
BasePlayer target = Player.Find(arg.Args[1]);
if (target == null)
{
arg.ReplyWith("Target not found!");
return;
}
string nade = arg.Args[0] == "flash" ? config.flash.Name : config.molly.Name;
DoPayAndGive(target, nade);
arg.ReplyWith($"Ran command fg.give on {target.displayName}");
}
[ConsoleCommand("fg.givefree")]
void cmdGiveFree(ConsoleSystem.Arg arg)
{
if (arg.IsClientside || !arg.IsRcon) return;
if (arg.Args == null || arg.Args.Length == 0)
{
arg.ReplyWith("fg.givefree <flash/molly> <nameOrIdOrIP>");
return;
}
if (arg.Args[0] != "flash" && arg.Args[0] != "molly")
{
arg.ReplyWith("Wrong grenade type specified!");
return;
}
BasePlayer target = Player.Find(arg.Args[1]);
if(target == null)
{
arg.ReplyWith("Target not found!");
return;
}
string nade = arg.Args[0] == "flash" ? config.flash.Name : config.molly.Name;
DoPayAndGive(target, nade, true);
arg.ReplyWith($"You gave {target.displayName} a {nade}");
}
private void cmdFlash(BasePlayer player, string cmd, string[] args)
{
if (!permission.UserHasPermission(player.UserIDString, "fancygrenades.useflash"))
{
Player.Reply(player, lang.GetMessage("NO_PERMISSION", this, player.UserIDString), config.settings.chatId);
return;
}
DoPayAndGive(player, config.flash.Name, config.pay.costAmount == 0 ? true : false);
}
private void cmdMolly(BasePlayer player, string cmd, string[] args)
{
if (!permission.UserHasPermission(player.UserIDString, "fancygrenades.usemolly"))
{
Player.Reply(player, lang.GetMessage("NO_PERMISSION", this, player.UserIDString), config.settings.chatId);
return;
}
DoPayAndGive(player, config.molly.Name, config.pay.costAmount == 0 ? true : false);
}
private void DoPayAndGive(BasePlayer player, string nadeType, bool free = false)
{
string paymentType = config.pay.costItem;
if (config.pay.costItem.Equals("serverrewards", StringComparison.OrdinalIgnoreCase))
paymentType = "RP";
else if (config.pay.costItem.Equals("economics", StringComparison.OrdinalIgnoreCase))
paymentType = "Economics";
ulong skinId = nadeType == config.flash.Name ? config.flash.SkinId : config.molly.SkinId;
Item nade = ItemManager.CreateByItemID(GrenadeId, 1, skinId);
nade.name = nadeType == config.flash.Name ? config.flash.Name : config.molly.Name;
string symbol = paymentType == "RP" ? "RP" : paymentType == "Economics" ? "$" : config.pay.costItem;
if (!(HasFunds(player, paymentType) is bool) && !free)
{
int amount = (int)HasFunds(player, paymentType);
Player.Message(player, string.Format(lang.GetMessage("PURCHASE_FAILED", this, player.UserIDString), symbol, (config.pay.costAmount - amount), symbol));
return;
}
if(!GiveItem(player, nade))
{
Player.Message(player, string.Format(lang.GetMessage("INVENTORY_FULL", this, player.UserIDString)));
return;
}
else
{
if (!free)
{
switch (paymentType)
{
case "RP":
ServerRewards?.CallHook("TakePoints", player.userID, config.pay.costAmount);
break;
case "Economics":
Economics?.CallHook("Withdraw", player.userID, (double)config.pay.costAmount);
break;
default:
player.inventory.Take(null, item.itemid, config.pay.costAmount);
break;
}
Player.Message(player, string.Format(lang.GetMessage("PURCHASE_SUCCESS", this, player.UserIDString), nade.name, config.pay.costAmount, symbol));
return;
}
Player.Message(player, string.Format(lang.GetMessage("GIVE_FREE", this, player.UserIDString), nade.name));
}
}
object HasFunds(BasePlayer player, string paymentType)
{
if (paymentType == "RP")
{
int playerRP = (int)ServerRewards?.CallHook("CheckPoints", player.userID);
if (playerRP >= config.pay.costAmount)
return true;
return playerRP;
}
else if (paymentType == "Economics")
{
double playerEcon = (double)Economics?.CallHook("Balance", player.userID);
if (playerEcon >= config.pay.costAmount)
return true;
return playerEcon;
}
else
{
if (GetItemAmount(player, item.shortname) >= config.pay.costAmount)
return true;
return GetItemAmount(player, item.shortname);
}
}
private bool GiveItem(BasePlayer player, Item i)
{
if (!player.inventory.GiveItem(i))
{
i.Remove();
return false;
}
return true;
}
private bool InNadeAngle(BasePlayer player, BaseEntity ent)
{
float angle = Vector3.Angle((ent.transform.position - player.transform.position), player.eyes.HeadForward());
if (angle < 99) return true;
return false;
}
private int GetItemAmount(BasePlayer player, string shortname)
{
ItemDefinition item = ItemManager.FindItemDefinition(shortname);
Item[] playerItems = player.inventory.AllItems();
return playerItems.FirstOrDefault(x => x.info == item) == null ? 0 : playerItems.FirstOrDefault(x => x.info == item).amount;
}
private List<BasePlayer> GetPlayersInRadius(Vector3 pos, int radius)
{
var list = new List<BasePlayer>();
foreach (var player in BasePlayer.activePlayerList)
{
if (!player.userID.IsSteamId()) continue;
if (Vector3.Distance(pos, player.transform.position) < radius)
list.Add(player);
}
return list;
}
private void FlashEffect(BasePlayer player)
{
CuiHelper.DestroyUi(player, "Flash");
var Element = new CuiElementContainer()
{
{
new CuiPanel
{
Image = {Color = "1 1 1 1", FadeIn = 0.1f},
RectTransform = {AnchorMin = "0 0 ", AnchorMax = "1 1" },
CursorEnabled = false,
FadeOut = 2.5f
},
new CuiElement().Parent = "Overlay", "Flash"
}
};
CuiHelper.AddUi(player, Element);
timer.Once(config.flash.Duration, () => CuiHelper.DestroyUi(player, "Flash"));
}
private void FireEffect(Vector3 pos)
{
var flame = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_fire.prefab", pos);
flame?.Spawn();
}
}
}