C#:
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<ulong, WeightController> _players = new Dictionary<ulong, WeightController>();
#endregion
#region Config
private class Configuration
{
[JsonProperty(PropertyName = "Carry Weight Settings for Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, int> playerWeight = new Dictionary<string, int>
{
["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<string, float> itemsWeight = new Dictionary<string, float>
{
["rifle.ak"] = 5,
["wood"] = 0.2f
};
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_config = Config.ReadObject<Configuration>();
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<WeightController>());
}
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<BasePlayer>();
maxWeight = _.GetMaxWeight(_player.UserIDString);
ShowUIWeight();
InvokeRepeating(CheckWeight, 0f, _config.checkInterval);
}
private void CheckWeight()
{
var currentWeight = 0f;
var items = Facepunch.Pool.Get<List<Item>>();
_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
}
}