using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Oxide; using UnityEngine; namespace Oxide.Plugins { [Info("SimpleMagnets", "Zayasik", "0.1.0")] [Description("Allows players to attract items to them with a magnet")] class SimpleMagnets : RustPlugin { private Configuration config = Configuration.DefaultConfig(); private Dictionary _magnetTimers = new Dictionary(); private Dictionary Perms = new Dictionary(); private const string magnetShortName = "rf_pager"; private class Configuration { [JsonProperty(PropertyName = "Permissions Groups")] public Dictionary Perms = new Dictionary { {"default", new MagnetTypeInfo { Priority = 0, CoolDown = 5, MaxItemsInOnce = 5, MaxRadius = 5 } } }; [JsonProperty(PropertyName = "MagnetSkinID")] public uint magnetSkinID { get; set; } = 3366998024; public static Configuration DefaultConfig() { return new Configuration(); } } private class MagnetTypeInfo { public int Priority { get; set; } public float CoolDown { get; set; } public int MaxItemsInOnce { get; set; } public float MaxRadius { get; set; } } protected override void LoadDefaultConfig() { SaveConfig(); } protected override void LoadConfig() { base.LoadConfig(); config = Config.ReadObject(); Perms = config.Perms; } protected override void SaveConfig() { config.Perms = Perms; Config.WriteObject(config, true); } private void Init() { RegisterPerms(); SaveConfig(); } private void RegisterPerms() { foreach (var group in permission.GetGroups()) { if (group != "admin" && group != "default") { if (!Perms.ContainsKey(group)) { Perms[group] = new MagnetTypeInfo { Priority = 1, CoolDown = 5, MaxItemsInOnce = 5, MaxRadius = 5 }; } } } permission.RegisterPermission("simplemagnets.use", this); } private string GetPlayerPermsGroup(ulong _playerID) { var _groups = permission.GetUserGroups(_playerID.ToString()); var _priority = _groups .Where(x => x != "admin") .OrderByDescending(x => Perms[x].Priority) .FirstOrDefault(); return _priority ?? "default"; } private List GetItemsInRange(BasePlayer player) { var _playerGroup = GetPlayerPermsGroup(player.userID); var _magnet = Perms[_playerGroup]; var _colliders = UnityEngine.Physics.OverlapSphere(player.transform.position, _magnet.MaxRadius, layerMask: LayerMask.GetMask("Physics Debris")); List _items = new List(); foreach (var collider in _colliders) { DroppedItem? droppedItem = collider.ToBaseEntity() as DroppedItem; if (droppedItem != null && _items.Count < _magnet.MaxItemsInOnce) { if (ItemToPlayer(droppedItem, player) as bool? == true) { _items.Add(droppedItem); } } } return _items; } private bool IsPlayerHasMagnet(BasePlayer player) { List items = new List(); player.inventory.GetAllItems(items); foreach (var item in items) { if (item.info.shortname == magnetShortName && item.skin == config.magnetSkinID) { return true; } } return false; } private void StartMagnet(BasePlayer player) { if (player == null) return; if (player.IsDead()) return; if (permission.UserHasPermission(player.UserIDString, "simplemagnets.use")) { if (!IsPlayerHasMagnet(player)) { if (_magnetTimers.ContainsKey(player)) { _magnetTimers[player].Destroy(); _magnetTimers.Remove(player); } SendReply(player, "You don't have a magnet"); return; }; List _items = GetItemsInRange(player); foreach (var droppedItem in _items) { if (droppedItem != null) { Vector3 offset = new Vector3(0, 1, 0); droppedItem.transform.position = player.transform.position + offset; if (Vector3.Distance(droppedItem.transform.position, player.transform.position + offset) < 0.5) { timer.Once(0.25f, () => { if (droppedItem != null) { player.GiveItem(droppedItem.item); } }); } } } } } private object? ItemToPlayer(DroppedItem item, BasePlayer player) { Vector3 offset = new Vector3(0, 1, 0); Vector3 direction = (player.transform.position - item.transform.position).normalized; float distance = Vector3.Distance(player.transform.position, item.transform.position); LayerMask mask = LayerMask.GetMask("Construction", "Player (Server)", "Terrain", "World"); RaycastHit[] hits = Physics.RaycastAll(item.transform.position, direction, distance, mask); foreach (RaycastHit hit in hits) { if (hit.collider.gameObject == player.gameObject) { return true; } return false; } return null; } private object? OnItemAction(Item _pager, string action, BasePlayer player) { if (player != null && _pager != null && _pager.skin == config.magnetSkinID && permission.UserHasPermission(player.UserIDString, "simplemagnets.use")) { var _playerGroup = GetPlayerPermsGroup(player.userID); var _magnet = Perms[_playerGroup]; if (_pager.info.shortname == magnetShortName) { if (action == "silenton") { if (_magnetTimers.ContainsKey(player)) { _magnetTimers[player].Destroy(); _magnetTimers.Remove(player); SendReply(player, "Magnet is stopped"); } } else if (action == "silentoff") { if (!_magnetTimers.ContainsKey(player)) { SendReply(player, "Magnet is started"); _magnetTimers[player] = timer.Every(_magnet.CoolDown, () => { StartMagnet(player); }); } } } } return null; } private void OnPlayerDisconnected(BasePlayer player, string reason) { if (_magnetTimers.ContainsKey(player)) { _magnetTimers[player].Destroy(); _magnetTimers.Remove(player); } } [ChatCommand("m_give")] private void giveMagnet(BasePlayer player, string command, string[] args) { if (player.IsAdmin) { Item item = ItemManager.CreateByName(magnetShortName, 1, config.magnetSkinID); player.GiveItem(item); } } } }