C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using System;
using System.Linq;
using UnityEngine;
using Oxide.Core.Plugins;
using Oxide.Core.Configuration;
using Oxide.Game.Rust.Cui;
using Oxide.Core;
using System.Reflection;
namespace Oxide.Plugins
{
[Info("Troll Tax", "Absolut", "1.1.1")]
[Description("Places a tax on players killed.Once the Taxer dies his/her tax payer list is cleared")]
public class TrollTax : RustPlugin
{
#region Fields
[PluginReference]
Plugin LustyMap;
string TitleColor = "<color=orange>";
string MsgColor = "<color=#A9A9A9>";
TrollTaxData ttData;
private DynamicConfigFile TTData;
private Dictionary<string, Timer> timers = new Dictionary<string, Timer>();
private Dictionary<ulong, Coords> BoxPrep = new Dictionary<ulong, Coords>();
private List<ulong> VoidSelection = new List<ulong>();
#endregion
#region Server Hooks
void Init()
{
TTData = Interface.Oxide.DataFileSystem.GetFile(Name + "_Data");
LoadVariables();
LoadData();
}
void InitializeTaxTimer(ulong taxer, ulong payer)
{
if (!ttData.VictimLimit.ContainsKey(payer))
ttData.VictimLimit.Add(payer, new Dictionary<ulong, Timer>());
if (ttData.VictimLimit[payer].ContainsKey(taxer))
ttData.VictimLimit[payer].Remove(taxer);
if (!ttData.TaxCollector.ContainsKey(taxer))
ttData.TaxCollector.Add(taxer, new List<ulong>());
ttData.TaxCollector[taxer].Add(payer);
ttData.VictimLimit[payer].Add(taxer, timer.Once(configData.TaxTimeLimit * 3600, () => RemoveTax(payer, taxer)));
}
void RemoveTax(ulong payer, ulong taxer)
{
if (ttData.VictimLimit.ContainsKey(payer))
if (ttData.VictimLimit[payer].ContainsKey(taxer))
ttData.VictimLimit[payer].Remove(taxer);
if (ttData.TaxCollector.ContainsKey(taxer))
if (ttData.TaxCollector[taxer].Contains(payer))
{
ttData.TaxCollector[taxer].Remove(payer);
GetSendMSG(BasePlayer.FindByID(payer), "TaxRemoved");
}
}
void Unload()
{
BoxPrep.Clear();
VoidSelection.Clear();
foreach (var entry in timers)
entry.Value.Destroy();
timers.Clear();
SaveData();
}
private void OnPlayerDisconnected(BasePlayer player)
{
if (VoidSelection.Contains(player.userID))
VoidSelection.Remove(player.userID);
if (BoxPrep.ContainsKey(player.userID))
BoxPrep.Remove(player.userID);
}
void OnServerInitialized()
{
timers.Add("info", timer.Once(900, () => InfoLoop()));
timers.Add("save", timer.Once(600, () => SaveLoop()));
SaveData();
}
#endregion
#region Player Hooks
void OnEntityBuilt(Planner planner, GameObject gameobject)
{
if (planner == null) return;
if (gameobject.GetComponent<BaseEntity>() != null)
{
BaseEntity container = gameobject.GetComponent<BaseEntity>();
var entityowner = gameobject.GetComponent<BaseEntity>().OwnerID;
if (container.PrefabName == "assets/prefabs/deployable/large wood storage/box.wooden.large.prefab" || container.PrefabName == "assets/prefabs/deployable/woodenbox/woodbox_deployed.prefab")
{
if (BoxPrep.ContainsKey(entityowner)) BoxPrep.Remove(entityowner);
BoxPrep.Add(entityowner, new Coords { x = gameobject.transform.position.x, y = gameobject.transform.position.y, z = gameobject.transform.position.z });
BasePlayer player = BasePlayer.FindByID(entityowner);
TaxBoxConfirmation(player);
}
}
}
private void OnEntityDeath(BaseEntity entity, HitInfo hitInfo)
{
if (entity is StorageContainer)
{
Vector3 ContPosition = entity.transform.position;
if (ttData.TaxBox.ContainsKey(entity.OwnerID))
{
if (ContPosition == new Vector3(ttData.TaxBox[entity.OwnerID].x, ttData.TaxBox[entity.OwnerID].y, ttData.TaxBox[entity.OwnerID].z))
{
ttData.TaxBox.Remove(entity.OwnerID);
BasePlayer owner = BasePlayer.FindByID(entity.OwnerID);
if (BasePlayer.activePlayerList.Contains(owner))
GetSendMSG(owner, "TaxBoxDestroyed");
}
SaveData();
}
return;
}
if (entity is BasePlayer)
{
var victim = entity.ToPlayer();
if (ttData.TaxCollector.ContainsKey(victim.userID))
{
foreach (var entry in ttData.TaxCollector[victim.userID])
RemoveTax(entry, victim.userID);
SaveData();
}
if (entity is BasePlayer && hitInfo.Initiator is BasePlayer)
{
var attacker = hitInfo.Initiator.ToPlayer() as BasePlayer;
if (entity as BasePlayer == null || hitInfo == null) return;
if (victim.userID != attacker.userID)
{
InitializeTaxTimer(attacker.userID, victim.userID);
SaveData();
}
}
}
}
void OnGrowableGathered(GrowableEntity growable, Item item, BasePlayer player)
{
if (!isPayor(player.userID)) return;
var taxrate = configData.TaxRate;
List<StorageContainer> TaxContainers = GetTaxContainer(player.userID);
if (TaxContainers == null) return;
int taxcollectors = 0;
foreach (var entry in ttData.TaxCollector.Where(kvp => kvp.Value.Contains(player.userID)))
taxcollectors++;
var maxtaxors = Math.Floor(100 / taxrate);
if (maxtaxors < taxcollectors)
taxrate = 90 / taxcollectors;
int Tax = Convert.ToInt32(Math.Ceiling((item.amount * taxrate) / 100));
item.amount = item.amount - (Tax * taxcollectors);
foreach (StorageContainer cont in TaxContainers)
{
if (!cont.inventory.IsFull())
{
ItemDefinition ToAdd = ItemManager.FindItemDefinition(item.info.itemid);
if (ToAdd != null)
{
cont.inventory.AddItem(ToAdd, Tax);
}
}
else if (BasePlayer.activePlayerList.Contains(BasePlayer.FindByID(cont.OwnerID)))
if (timers.ContainsKey(cont.OwnerID.ToString()))
{
GetSendMSG(player, "TaxBoxFull");
SetBoxFullNotification(cont.OwnerID.ToString());
return;
}
}
}
void OnCollectiblePickup(Item item, BasePlayer player)
{
if (!isPayor(player.userID)) return;
var taxrate = configData.TaxRate;
List<StorageContainer> TaxContainers = GetTaxContainer(player.userID);
if (TaxContainers == null) return;
int taxcollectors = 0;
foreach (var entry in ttData.TaxCollector.Where(kvp => kvp.Value.Contains(player.userID)))
taxcollectors++;
var maxtaxors = Math.Floor(100 / taxrate);
if (maxtaxors < taxcollectors)
taxrate = 90 / taxcollectors;
int Tax = Convert.ToInt32(Math.Ceiling((item.amount * taxrate) / 100));
item.amount = item.amount - (Tax * taxcollectors);
foreach (StorageContainer cont in TaxContainers)
{
if (!cont.inventory.IsFull())
{
ItemDefinition ToAdd = ItemManager.FindItemDefinition(item.info.itemid);
if (ToAdd != null)
{
cont.inventory.AddItem(ToAdd, Tax);
}
}
else if (BasePlayer.activePlayerList.Contains(BasePlayer.FindByID(cont.OwnerID)))
if (timers.ContainsKey(cont.OwnerID.ToString()))
{
GetSendMSG(player, "TaxBoxFull");
SetBoxFullNotification(cont.OwnerID.ToString());
return;
}
}
}
void OnDispenserGather(ResourceDispenser Dispenser, BaseEntity entity, Item item)
{
BasePlayer player = entity.ToPlayer();
if (!isPayor(entity.ToPlayer().userID)) return;
var taxrate = configData.TaxRate;
List<StorageContainer> TaxContainers = GetTaxContainer(player.userID);
if (TaxContainers == null) return;
int taxcollectors = 0;
foreach (var entry in ttData.TaxCollector.Where(kvp => kvp.Value.Contains(player.userID)))
taxcollectors++;
var maxtaxors = Math.Floor(100 / taxrate);
if (maxtaxors < taxcollectors)
taxrate = 90 / taxcollectors;
int Tax = Convert.ToInt32(Math.Ceiling((item.amount * taxrate) / 100));
item.amount = item.amount - (Tax * taxcollectors);
foreach (StorageContainer cont in TaxContainers)
{
if (!cont.inventory.IsFull())
{
ItemDefinition ToAdd = ItemManager.FindItemDefinition(item.info.itemid);
if (ToAdd != null)
{
cont.inventory.AddItem(ToAdd, Tax);
}
}
else if (BasePlayer.activePlayerList.Contains(BasePlayer.FindByID(cont.OwnerID)))
{
if (timers.ContainsKey(cont.OwnerID.ToString()))
{
GetSendMSG(player, "TaxBoxFull");
SetBoxFullNotification(cont.OwnerID.ToString());
return;
}
}
}
}
#endregion
#region Functions
public bool isPayor(ulong ID)
{
foreach (var entry in ttData.TaxCollector)
{
if (entry.Value.Contains(ID))
{
return true;
}
else continue;
}
return false;
}
private List<StorageContainer> GetTaxContainer(ulong Payor)
{
List<StorageContainer> Containers = new List<StorageContainer>();
foreach (var entry in ttData.TaxCollector.Where(kvp => kvp.Value.Contains(Payor)))
{
if (ttData.TaxBox.ContainsKey(entry.Key))
{
Vector3 containerPos = new Vector3 (ttData.TaxBox[entry.Key].x, ttData.TaxBox[entry.Key].y, ttData.TaxBox[entry.Key].z );
foreach (StorageContainer Cont in StorageContainer.FindObjectsOfType<StorageContainer>())
{
Vector3 ContPosition = Cont.transform.position;
if (ContPosition == containerPos)
Containers.Add(Cont);
}
}
}
if (Containers.Count > 0)
return Containers;
else return null;
}
private void GetSendMSG(BasePlayer player, string message, string arg1 = "", string arg2 = "", string arg3 = "")
{
if (!player.IsConnected) return;
string msg = string.Format(lang.GetMessage(message, this, player.UserIDString), arg1, arg2, arg3);
SendReply(player, TitleColor + lang.GetMessage("title", this, player.UserIDString) + "</color>" + MsgColor + msg + "</color>");
}
public void DestroyTaxPanel(BasePlayer player)
{
CuiHelper.DestroyUi(player, PanelTax);
}
#endregion
#region UI Creation
private string PanelTax = "Tax";
public class UI
{
static public CuiElementContainer CreateElementContainer(string panelName, string color, string aMin, string aMax, bool cursor = false)
{
var NewElement = new CuiElementContainer()
{
{
new CuiPanel
{
Image = {Color = color},
RectTransform = {AnchorMin = aMin, AnchorMax = aMax},
CursorEnabled = cursor
},
new CuiElement().Parent,
panelName
}
};
return NewElement;
}
static public void CreatePanel(ref CuiElementContainer container, string panel, string color, string aMin, string aMax, bool cursor = false)
{
container.Add(new CuiPanel
{
Image = { Color = color },
RectTransform = { AnchorMin = aMin, AnchorMax = aMax },
CursorEnabled = cursor
},
panel);
}
static public void CreateLabel(ref CuiElementContainer container, string panel, string color, string text, int size, string aMin, string aMax, TextAnchor align = TextAnchor.MiddleCenter)
{
container.Add(new CuiLabel
{
Text = { Color = color, FontSize = size, Align = align, FadeIn = 1.0f, Text = text },
RectTransform = { AnchorMin = aMin, AnchorMax = aMax }
},
panel);
}
static public void CreateButton(ref CuiElementContainer container, string panel, string color, string text, int size, string aMin, string aMax, string command, TextAnchor align = TextAnchor.MiddleCenter)
{
container.Add(new CuiButton
{
Button = { Color = color, Command = command, FadeIn = 1.0f },
RectTransform = { AnchorMin = aMin, AnchorMax = aMax },
Text = { Text = text, FontSize = size, Align = align }
},
panel);
}
static public void LoadImage(ref CuiElementContainer container, string panel, string png, string aMin, string aMax)
{
container.Add(new CuiElement
{
Parent = panel,
Components =
{
new CuiRawImageComponent {Png = png },
new CuiRectTransformComponent {AnchorMin = aMin, AnchorMax = aMax }
}
});
}
static public void CreateTextOverlay(ref CuiElementContainer container, string panel, string text, string color, int size, string aMin, string aMax, TextAnchor align = TextAnchor.MiddleCenter, float fadein = 1.0f)
{
//if (configdata.DisableUI_FadeIn)
// fadein = 0;
container.Add(new CuiLabel
{
Text = { Color = color, FontSize = size, Align = align, FadeIn = fadein, Text = text },
RectTransform = { AnchorMin = aMin, AnchorMax = aMax }
},
panel);
}
}
private Dictionary<string, string> UIColors = new Dictionary<string, string>
{
{"black", "0 0 0 1.0" },
{"dark", "0.1 0.1 0.1 0.98" },
{"header", "1 1 1 0.3" },
{"light", ".564.564.564 1.0" },
{"grey1", "0.6 0.6 0.6 1.0" },
{"brown", "0.3 0.16 0.0 1.0" },
{"yellow", "0.9 0.9 0.0 1.0" },
{"orange", "1.0 0.65 0.0 1.0" },
{"blue", "0.2 0.6 1.0 1.0" },
{"red", "1.0 0.1 0.1 1.0" },
{"white", "1 1 1 1" },
{"green", "0.28 0.82 0.28 1.0" },
{"grey", "0.85 0.85 0.85 1.0" },
{"lightblue", "0.6 0.86 1.0 1.0" },
{"buttonbg", "0.2 0.2 0.2 0.7" },
{"buttongreen", "0.133 0.965 0.133 0.9" },
{"buttonred", "0.964 0.133 0.133 0.9" },
{"buttongrey", "0.8 0.8 0.8 0.9" },
{"CSorange", "1.0 0.64 0.10 1.0" }
};
#endregion
#region UI Panels
private void TaxBoxConfirmation(BasePlayer player)
{
CuiHelper.DestroyUi(player, PanelTax);
var element = UI.CreateElementContainer(PanelTax, UIColors["dark"], "0.425 0.45", "0.575 0.55", true);
UI.CreatePanel(ref element, PanelTax, UIColors["light"], "0.01 0.02", "0.99 0.98");
UI.CreateLabel(ref element, PanelTax, MsgColor, lang.GetMessage("TaxBoxCreation", this, player.UserIDString), 14, "0.05 0.56", "0.95 0.9");
UI.CreateButton(ref element, PanelTax, UIColors["buttongreen"], lang.GetMessage("Yes", this, player.UserIDString), 14, "0.05 0.25", "0.475 0.55", $"UI_SaveTaxBox");
UI.CreateButton(ref element, PanelTax, UIColors["buttonred"], lang.GetMessage("No", this, player.UserIDString), 14, "0.525 0.25", "0.95 0.55", $"UI_DestroyTaxPanel");
UI.CreateButton(ref element, PanelTax, UIColors["CSorange"], lang.GetMessage("VOID", this, player.UserIDString), 14, "0.25 0.05", "0.75 0.24", $"UI_DontAsk");
CuiHelper.AddUi(player, element);
}
#endregion
#region UI Commands
[ConsoleCommand("UI_SaveTaxBox")]
private void cmdUI_SaveTaxBox(ConsoleSystem.Arg arg)
{
var player = arg.Connection.player as BasePlayer;
if (player == null)
return;
DestroyTaxPanel(player);
if (BoxPrep.ContainsKey(player.userID))
{
if (ttData.TaxBox.ContainsKey(player.userID)) ttData.TaxBox.Remove(player.userID);
ttData.TaxBox.Add(player.userID, new Coords { x = BoxPrep[player.userID].x, y = BoxPrep[player.userID].y, z = BoxPrep[player.userID].z });
}
else GetSendMSG(player, "NoBoxPrepped");
SaveData();
}
[ConsoleCommand("UI_DestroyTaxPanel")]
private void cmdUI_DestroyTaxPanel(ConsoleSystem.Arg arg)
{
var player = arg.Connection.player as BasePlayer;
if (player == null)
return;
DestroyTaxPanel(player);
}
[ConsoleCommand("UI_DontAsk")]
private void cmdUI_DontAsk(ConsoleSystem.Arg arg)
{
var player = arg.Connection.player as BasePlayer;
if (player == null)
return;
DestroyTaxPanel(player);
if (VoidSelection.Contains(player.userID)) return;
VoidSelection.Add(player.userID);
}
#endregion
#region Timers
private void SaveLoop()
{
if (timers.ContainsKey("save"))
{
timers["save"].Destroy();
timers.Remove("save");
}
SaveData();
timers.Add("save", timer.Once(600, () => SaveLoop()));
}
private void InfoLoop()
{
if (timers.ContainsKey("info"))
{
timers["info"].Destroy();
timers.Remove("info");
}
if (configData.InfoInterval == 0) return;
foreach (BasePlayer p in BasePlayer.activePlayerList)
{
GetSendMSG(p, "TrollTaxInfo");
}
timers.Add("info", timer.Once(configData.InfoInterval * 60, () => InfoLoop()));
}
private void SetBoxFullNotification(string ID)
{
timers.Add(ID, timer.Once(5 * 60, () => timers.Remove(ID)));
}
#endregion
#region Classes
class TrollTaxData
{
public Dictionary<ulong, List<ulong>> TaxCollector = new Dictionary<ulong, List<ulong>>();
public Dictionary<ulong, Coords> TaxBox = new Dictionary<ulong, Coords>();
public Dictionary<ulong, Dictionary<ulong, Timer>> VictimLimit = new Dictionary<ulong, Dictionary<ulong, Timer>>();
}
class Coords
{
public float x;
public float y;
public float z;
}
#endregion
#region Data Management
void SaveData()
{
TTData.WriteObject(ttData);
}
void LoadData()
{
try
{
ttData = TTData.ReadObject<TrollTaxData>();
}
catch
{
Puts("Couldn't load TrollTax data, creating new datafile");
ttData = new TrollTaxData();
}
}
#endregion
#region Config
private ConfigData configData;
class ConfigData
{
public double TaxRate { get; set; }
public int TaxTimeLimit { get; set; }
public int InfoInterval { get; set; }
}
private void LoadVariables()
{
LoadConfigVariables();
SaveConfig();
}
protected override void LoadDefaultConfig()
{
var config = new ConfigData
{
TaxRate = 5,
TaxTimeLimit = 8,
};
SaveConfig(config);
}
private void LoadConfigVariables() => configData = Config.ReadObject<ConfigData>();
void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
#endregion
#region Messages
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>()
{
{"title", "TrollTax: " },
{"TrollTaxInfo", "This server is running TrollTax.You will become a tax collector for each player you kill until you die.To create a tax box simply place a box on the ground."},
{"NoBoxPrepped", "Error finding target tax box!" },
{"TaxBoxDestroyed", "Your tax box has been destroyed!" },
{"TaxBoxFull", "Your tax box is full! Clear room to generate taxes." },
{"TaxBoxCreation", "Would like to make this your tax box?" },
{"Yes", "Yes?" },
{"No", "No?" },
{"TaxRemoved", "You are no longering being taxed by one of your taxers!" }
}, this);
}
#endregion
}
}