using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Oxide.Game.Rust.Cui; using UnityEngine; namespace Oxide.Plugins { [Info("Weight", "AhigaO#4485", "1.0.2")] internal class Weight : RustPlugin { #region Static private static Weight _; private const string Layer = "UI_Weight"; private static Configuration _config; private Dictionary _players = new Dictionary(); #endregion #region Config private class Configuration { [JsonProperty(PropertyName = "Carry Weight Settings for Players", ObjectCreationHandling = ObjectCreationHandling.Replace)] public Dictionary playerWeight = new Dictionary { ["weight.default"] = 500, ["weight.vip"] = 800, ["weight.premium"] = 1200, }; [JsonProperty(PropertyName = "Player item check interval(Influences optimization)")] public float checkInterval = 1f; [JsonProperty(PropertyName = "Weight for all items not listed below")] public float defaultWeight = 0.1f; [JsonProperty(PropertyName = "Weight setting for items(per 1 item)", ObjectCreationHandling = ObjectCreationHandling.Replace)] public Dictionary itemsWeight = new Dictionary { ["rifle.ak"] = 5, ["wood"] = 0.2f }; } protected override void LoadConfig() { base.LoadConfig(); try { _config = Config.ReadObject(); if (_config == null) throw new Exception(); SaveConfig(); } catch { PrintError("Your configuration file contains an error. Using default configuration values."); LoadDefaultConfig(); } } protected override void SaveConfig() => Config.WriteObject(_config); protected override void LoadDefaultConfig() => _config = new Configuration(); #endregion #region OxideHooks private void OnServerInitialized() { _ = this; foreach (var check in _config.playerWeight) if (!permission.PermissionExists(check.Key)) permission.RegisterPermission(check.Key, this); foreach (var check in BasePlayer.activePlayerList) OnPlayerConnected(check); } private void Unload() { foreach (var check in BasePlayer.activePlayerList) OnPlayerDisconnected(check); _ = null; _config = null; } private void OnPlayerConnected(BasePlayer player) { if (player == null) return; if (!permission.UserHasPermission(player.UserIDString,_config.playerWeight.First().Key)) permission.GrantUserPermission(player.UserIDString, _config.playerWeight.First().Key, this); _players.Add(player.userID, player.gameObject.AddComponent()); } private void OnPlayerDisconnected(BasePlayer player) { if (player == null) return; _players[player.userID]?.Kill(); _players.Remove(player.userID); } private void OnUserPermissionGranted(string id, string permName) { if (!_config.playerWeight.ContainsKey(permName)) return; WeightController controller; if (!_players.TryGetValue(ulong.Parse(id), out controller)) return; controller.maxWeight = GetMaxWeight(id); } private int GetMaxWeight(string id) { var maxWeight = 0; foreach (var check in _config.playerWeight) if (permission.UserHasPermission(id, check.Key)) maxWeight = check.Value; return maxWeight; } #endregion #region Functions private class WeightController : FacepunchBehaviour { private BasePlayer _player; public int maxWeight; private bool isFull = false; private void Awake() { _player = GetComponent(); maxWeight = _.GetMaxWeight(_player.UserIDString); ShowUIWeight(); InvokeRepeating(CheckWeight, 0f, _config.checkInterval); } private void CheckWeight() { var currentWeight = 0f; var items = Facepunch.Pool.Get>(); _player.inventory.GetAllItems(items); foreach (var check in items) { float weight; if (!_config.itemsWeight.TryGetValue(check.info.shortname, out weight)) weight = _config.defaultWeight; currentWeight += weight * check.amount; } isFull = currentWeight >= maxWeight; UpdateUIWight(currentWeight); Facepunch.Pool.FreeUnmanaged(ref items); } private void UpdateUIWight(float currentWeight) { var container = new CuiElementContainer(); container.Add(new CuiPanel { RectTransform = {AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "0 0", OffsetMax = isFull ? "60 60" : $"60 {60 * (currentWeight / maxWeight)}"}, Image = {Color = "0.1216 0.4196 0.6275 0.7843"} }, Layer + ".weightPanel", Layer + ".weightDisplay"); container.Add(new CuiLabel { RectTransform = {AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "0 0", OffsetMax = "60 60"}, Text = { Text = $"{currentWeight}\n-------\n{maxWeight}", Font = "robotocondensed-bold.ttf", FontSize = 16, Align = TextAnchor.MiddleCenter, Color = isFull ? "0.69 0.22 0.15 1.00" : "0.9853 0.5453 0.2246 1" } }, Layer, Layer + ".weightLabel"); CuiHelper.DestroyUi(_player, Layer + ".weightLabel"); CuiHelper.DestroyUi(_player, Layer + ".weightDisplay"); CuiHelper.AddUi(_player, container); } private void ShowUIWeight() { var container = new CuiElementContainer(); container.Add(new CuiPanel { RectTransform = {AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "185 -342", OffsetMax = "245 -282"}, Image = {Color = "0.9686 0.9216 0.8824 0.183"} }, "Overlay", Layer); container.Add(new CuiPanel { RectTransform = {AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "0 0", OffsetMax = "60 60"}, Image = {Color = "0 0 0 0"} }, Layer, Layer + ".weightPanel"); container.Add(new CuiPanel { RectTransform = {AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "10 10", OffsetMax = "50 50"}, Image = {Color = "1 1 1 0.7", Sprite = "assets/icons/player_carry.png"} }, Layer); CuiHelper.DestroyUi(_player, Layer); CuiHelper.AddUi(_player, container); } private void Update() { if (!isFull) return; _.ForcePlayerPosition(_player, _player.transform.position); } public void Kill() { CancelInvoke(CheckWeight); CuiHelper.DestroyUi(_player, Layer); Destroy(this); } } #endregion } }