using Newtonsoft.Json; using System; using Oxide.Core.Plugins; using Oxide.Core; using Oxide.Core.Configuration; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Threading.Tasks; using System; using System.IO; using System.Linq; using UnityEngine; namespace Oxide.Plugins { [Info("DeathPenalty", "mals", "2.0.3")] [Description("Die, lose money")] class DeathPenalty : RustPlugin { #region Oxide Hooks [PluginReference] Plugin Economics, ServerRewards, XPerience; // Scrap id static int ScrapID = -932201673; private void Init() { permission.RegisterPermission("deathpenalty.active", this); lang.RegisterMessages(messages, this); } //private void OnServerInitialized() //{ // LoadConfig(); //} private void OnEntityDeath(BaseEntity entity, HitInfo info) { BasePlayer bplayer = entity?.ToPlayer(); if (bplayer == null || String.IsNullOrWhiteSpace(bplayer.UserIDString)) return; if (String.Compare(bplayer.UserIDString, "75000000000000000") < 1) return; // catches sneaky NPCs if ((config.ActiveInactive == "active" && permission.UserHasPermission(bplayer.UserIDString, "deathpenalty.active")) || (config.ActiveInactive == "inactive" && !(permission.UserHasPermission(bplayer.UserIDString, "deathpenalty.active")))) DockPlayer(bplayer); } #endregion #region Functions string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args); void DockPlayer(BasePlayer bplayer) { double CurrentBalance = 0; double AmountTaken = 0; try { if (config.UseServerRewards) CurrentBalance = Convert.ToDouble(ServerRewards?.Call("CheckPoints", bplayer.UserIDString)); else if (config.UseEconomics) CurrentBalance = (double) Economics?.Call("Balance", bplayer.UserIDString); else // scrap CurrentBalance = (double) bplayer.inventory.GetAmount(ScrapID); } catch { CurrentBalance = 0; } // deal with null current balance if (CurrentBalance == null) CurrentBalance = 0; if (config.PenaltyType.ToLower() == "amount") AmountTaken = config.PenaltyAmount; else AmountTaken = CurrentBalance * (config.PenaltyAmount / 100); //Puts("CB : AT " + CurrentBalance.ToString() + " : " + AmountTaken.ToString() + " : " + config.MaxAmount.ToString()); if (Math.Abs(AmountTaken) > config.MaxAmount) { AmountTaken = Math.Sign(AmountTaken) * config.MaxAmount; //Puts("Capping at:" + AmountTaken.ToString()); } if (CurrentBalance < AmountTaken) AmountTaken = CurrentBalance; if (!config.UseEconomics) // round for scrap and server rewards AmountTaken = Math.Round(AmountTaken); if (CurrentBalance <= 0 && AmountTaken < 0) { SendReply(bplayer, Lang("YouBeDeadPoor", bplayer.UserIDString)); return; } else if (AmountTaken == 0) return; // nothing to process if (config.UseServerRewards) { if (AmountTaken < 0) ServerRewards?.Call("TakePoints", bplayer.UserIDString, -1*(int)(AmountTaken)); else if (AmountTaken > 0) ServerRewards?.Call("AddPoints", bplayer.UserIDString, (int)(AmountTaken)); } else if (config.UseEconomics) { if (AmountTaken < 0) Economics?.Call("Withdraw", bplayer.UserIDString, -1*AmountTaken); else if (AmountTaken > 0) Economics?.Call("Deposit", bplayer.UserIDString, AmountTaken); } else if (config.UseXPerience) { if (AmountTaken < 0) XPerience?.Call("TakeXP", bplayer, -1*(AmountTaken)); else if (AmountTaken > 0) XPerience?.Call("GiveXP", bplayer, (AmountTaken)); } else if (config.UseScrap) { if (AmountTaken <= 0) bplayer.inventory.Take(null, ScrapID, -1*(int)(AmountTaken)); else { Item payout = ItemManager.CreateByItemID(ScrapID, (int)AmountTaken); payout.MarkDirty(); bplayer.inventory.GiveItem(payout); } } SendReply(bplayer, Lang("YouBeDead", bplayer.UserIDString, AmountTaken)); } #endregion #region Config private Configuration config; public class Configuration { [JsonProperty(PropertyName = "Penalty Type (amount or percent)")] public string PenaltyType { get; set; } = "amount"; [JsonProperty(PropertyName = "Penalty Amount")] public double PenaltyAmount { get; set; } = -100; [JsonProperty(PropertyName = "Use Economics")] public bool UseEconomics { get; set; } = false; [JsonProperty(PropertyName = "Use ServerRewards")] public bool UseServerRewards { get; set; } = true; [JsonProperty(PropertyName = "Use XPerience")] public bool UseXPerience { get; set; } = false; [JsonProperty(PropertyName = "Use Scrap")] public bool UseScrap { get; set; } = false; [JsonProperty(PropertyName = "Maximum Amount")] public double MaxAmount { get; set; } = 1000; [JsonProperty(PropertyName = "Penalty on active or inactive")] public string ActiveInactive { get; set; } = "active"; public string ToJson() => JsonConvert.SerializeObject(this); public Dictionary ToDictionary() => JsonConvert.DeserializeObject>(ToJson()); } protected override void LoadDefaultConfig() => config = new Configuration(); protected override void LoadConfig() { try { base.LoadConfig(); config = Config.ReadObject(); if (config == null) { throw new JsonException(); } if (!config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys)) { Puts(Lang("Configuration appears to be outdated; updating and saving")); SaveConfig(); } } catch { Puts(Lang($"Configuration file {Name}.json is invalid; using defaults")); LoadDefaultConfig(); } CheckConfig(); } protected override void SaveConfig() { Puts($"Configuration changes saved to {Name}.json"); Config.WriteObject(config, true); } protected void CheckConfig() { bool config_changed = false; // check data is ok because people can make mistakes if (config.PenaltyType.ToLower() != "amount" && config.PenaltyType.ToLower() != "percent") { Puts(Lang("bad penalty type, please use amount or percent. ")); config.PenaltyType = "amount"; config_changed = true; } if (config.PenaltyAmount >= 0 ) { Puts(Lang("Warning: positive penalty amount, you are giving them a reward for dieing, we recommend using an amount less than zero. ")); //config.PenaltyAmount = -100; //config_changed = true; } if ((config.UseEconomics?1:0) + (config.UseServerRewards?1:0) + (config.UseScrap?1:0) + (config.UseXPerience?1:0) != 1 ) { Puts(Lang("Please select one and only one of Use Economics , Use ServerRewards or Use Scrap. Defaulting to Scrap. ")); config.UseScrap = true; config.UseServerRewards = false; config.UseEconomics = false; config_changed = true; } if (config.ActiveInactive != "active" && config.ActiveInactive != "inactive" ) { Puts(Lang("Penalty on Active or Inactive needs to be active or inactive. Defaulting to active. ")); config.ActiveInactive = "active"; config_changed = true; } if ((config.UseServerRewards || config.UseScrap) && config.PenaltyAmount != Math.Round(config.PenaltyAmount)) { Puts(Lang("ServerRewards/Scrap/XPerience requires an integer amount, rounding. ")); config.PenaltyAmount = Math.Round(config.PenaltyAmount); config_changed = true; } if (config_changed == true) SaveConfig(); } #endregion #region Localization private string msg(string key, string id = null) => lang.GetMessage(key, this, id); private Dictionary messages = new Dictionary() { {"YouBeDead", "You have lost {0} due to dieing" }, {"YouBeDeadPoor", "You are dead poor" } }; #endregion } }