Иконка ресурса

FREE FactionsTax : 1.0.0 1.0.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Requires: FactionsCore
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("FactionsTax", "Absolut", "1.0.0", ResourceId = 2424)]
    [Description("Applies a Tax to killed players.If the killing Faction has a Tax Box it will automatically collect a tax.Taxes expire after a period of time defined in the config.")]
    class FactionsTax : RustPlugin
    {
        #region Fields

        [PluginReference]
        FactionsCore FactionsCore;

        string TitleColor = "<color=orange>";
        string MsgColor = "<color=#A9A9A9>";

        FactionTaxData ftData;
        private DynamicConfigFile FTDATA;

        private Vector3 eyesAdjust;

        private Dictionary<string, Timer> timers = new Dictionary<string, Timer>();
        private Dictionary<ulong, XYZ> BoxPrep = new Dictionary<ulong, XYZ>();
        private List<ulong> VoidSelection = new List<ulong>();
        static FieldInfo buildingPrivlidges = typeof(BasePlayer).GetField("buildingPrivilege", BindingFlags.Instance | BindingFlags.NonPublic);

        #endregion

        #region Server Hooks

        void Loaded()
        {
            FTDATA = Interface.Oxide.DataFileSystem.GetFile("FactionTax_Data");
            lang.RegisterMessages(messages, this);
        }

        void AddTax(ushort TaxingFaction, ulong payer)
        {
            if (!ftData.TaxPayers.ContainsKey(TaxingFaction))
                ftData.TaxPayers.Add(TaxingFaction, new List<ulong>());
            if (!ftData.TaxPayers[TaxingFaction].Contains(payer))
                ftData.TaxPayers[TaxingFaction].Add(payer);
            int index = ftData.TaxTimers.Count() == 0 ? 0 : ftData.TaxTimers.Keys.Max() + 1;
            if (timers.ContainsKey(index.ToString()))
            {
                timers[index.ToString()].Destroy();
                timers.Remove(index.ToString());
            }
            ftData.TaxTimers.Add(index, new PlayerTimers { Faction = TaxingFaction, ResetTime = GrabCurrentTime() + (configData.TaxTimeLimit * 3600), TaxPayer = payer });
            timers.Add(index.ToString(), timer.Once((float)ftData.TaxTimers[index].ResetTime, () => RemoveTax(index)));
        }

        static double GrabCurrentTime() => DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;

        void RemoveTax(int index)
        {
            if (timers.ContainsKey(index.ToString()))
            {
                timers[index.ToString()].Destroy();
                timers.Remove(index.ToString());
            }
            if (ftData.TaxTimers.ContainsKey(index))
            {
                var data = ftData.TaxTimers[index];
                if (ftData.TaxPayers.ContainsKey(data.Faction) && ftData.TaxPayers[data.Faction].Contains(data.TaxPayer))
                    ftData.TaxPayers[data.Faction].Remove(data.TaxPayer);
                ftData.TaxTimers.Remove(index);
            }
        }

        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()
        {
            LoadVariables();
            LoadData();
            foreach (var entry in ftData.TaxTimers)
            {
                if (timers.ContainsKey(entry.Key.ToString()))
                {
                    timers[entry.Key.ToString()].Destroy();
                    timers.Remove(entry.Key.ToString());
                }
                if (GrabCurrentTime() > ftData.TaxTimers[entry.Key].ResetTime)
                    RemoveTax(entry.Key);
                else timers.Add(entry.Key.ToString(), timer.Once((float)ftData.TaxTimers[entry.Key].ResetTime, () => RemoveTax(entry.Key)));
            }
            eyesAdjust = new Vector3(0f, 1.5f, 0f);
            InfoLoop();
            SaveLoop();
        }

        #endregion

        #region Player Hooks

        private void OnEntityDeath(BaseEntity entity, HitInfo hitInfo)
        {
            if (hitInfo == null) return;
            if (entity is StorageContainer)
            {
                Vector3 ContPosition = entity.transform.position;
                if (ftData.TaxBox.ContainsValue(new XYZ { x = ContPosition.x, y = ContPosition.y, z = ContPosition.z }))
                {
                    List<ushort> boxOwners = ftData.TaxBox.Where(k => k.Value == new XYZ { x = ContPosition.x, y = ContPosition.y, z = ContPosition.z }).Select(k => k.Key).ToList();
                    ftData.TaxBox.Remove(boxOwners[0]);
                    FactionsCore.BroadcastFaction(null, "TaxBoxDestroyed", boxOwners[0]);
                    SaveData();
                }
                return;
            }
            var victim = entity.ToPlayer();
            var attacker = hitInfo.Initiator.ToPlayer() as BasePlayer;
            if (victim == null || attacker == null) return;
            if (GetFactionPlayer(attacker) == null || GetFactionPlayer(attacker).Faction == 0) return;
            if (victim.userID != attacker.userID)
            {
                AddTax(GetFactionPlayer(attacker).Faction, victim.userID);
                SaveData();
            }
        }

        void OnPlantGather(PlantEntity Plant, Item item, BasePlayer player)
        {
            List<StorageContainer> TaxContainers = GetTaxContainer(player.userID);
            if (TaxContainers == null) return;
            var taxrate = configData.TaxRate;
            int taxcollectors = TaxContainers.Count();
            var maxtaxors = Math.Floor(100 / taxrate);
            if (maxtaxors < taxcollectors)
                taxrate = 90 / taxcollectors;

            int Tax = Convert.ToInt32(Math.Floor((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
                {
                    item.amount += Tax;
                    List<ushort> boxOwners = ftData.TaxBox.Where(k => k.Value == new XYZ { x = cont.transform.localPosition.x, y = cont.transform.localPosition.y, z = cont.transform.localPosition.z }).Select(k => k.Key).ToList();
                    if (timers.ContainsKey(boxOwners[0].ToString()))
                    {
                        FactionsCore.BroadcastFaction(null, "TaxBoxFull", boxOwners[0]);
                        SetBoxFullNotification(boxOwners[0].ToString());
                        return;
                    }
                }
            }
        }


        void OnCollectiblePickup(Item item, BasePlayer player)
        {
            List<StorageContainer> TaxContainers = GetTaxContainer(player.userID);
            if (TaxContainers == null) return;
            var taxrate = configData.TaxRate;
            int taxcollectors = TaxContainers.Count();
            var maxtaxors = Math.Floor(100 / taxrate);
            if (maxtaxors < taxcollectors)
                taxrate = 90 / taxcollectors;

            int Tax = Convert.ToInt32(Math.Floor((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
                {
                    item.amount += Tax;
                    List<ushort> boxOwners = ftData.TaxBox.Where(k => k.Value == new XYZ { x = cont.transform.localPosition.x, y = cont.transform.localPosition.y, z = cont.transform.localPosition.z }).Select(k => k.Key).ToList();
                    if (timers.ContainsKey(boxOwners[0].ToString()))
                    {
                        FactionsCore.BroadcastFaction(null, "TaxBoxFull", boxOwners[0]);
                        SetBoxFullNotification(boxOwners[0].ToString());
                        return;
                    }
                }
            }
        }

        void OnDispenserGather(ResourceDispenser Dispenser, BaseEntity entity, Item item)
        {
            BasePlayer player = entity.ToPlayer();
            List<StorageContainer> TaxContainers = GetTaxContainer(player.userID);
            if (TaxContainers == null) return;
            var taxrate = configData.TaxRate;
            int taxcollectors = TaxContainers.Count();
            var maxtaxors = Math.Floor(100 / taxrate);
            if (maxtaxors < taxcollectors)
                taxrate = 90 / taxcollectors;
            int Tax = Convert.ToInt32(Math.Floor((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
                {
                    item.amount += Tax;
                    List<ushort> boxOwners = ftData.TaxBox.Where(k => k.Value == new XYZ { x = cont.transform.localPosition.x, y = cont.transform.localPosition.y, z = cont.transform.localPosition.z }).Select(k => k.Key).ToList();
                    if (timers.ContainsKey(boxOwners[0].ToString()))
                    {
                        FactionsCore.BroadcastFaction(null, "TaxBoxFull", boxOwners[0]);
                        SetBoxFullNotification(boxOwners[0].ToString());
                        return;
                    }
                }
            }
        }


        #endregion

        #region Functions
        public object isPayor(ulong ID)
        {
            if (ftData.TaxPayers == null || ftData.TaxPayers.Count == 0) return false;
            List<ushort> TaxingFactions = new List<ushort>();
            foreach (var entry in ftData.TaxPayers)
                    if (entry.Value.Contains(ID)) TaxingFactions.Add(entry.Key);
            if (TaxingFactions.Count > 0) return TaxingFactions;
            return false;
        }
        double GetTaxRate()
        {
            return configData.TaxRate;
        }

        List<StorageContainer> GetTaxContainers(ulong Payor)
        {
           return GetTaxContainer(Payor);
        }

        private List<StorageContainer> GetTaxContainer(ulong Payor)
        {
            if (isPayor(Payor) is bool) return null;
            List<StorageContainer> Containers = new List<StorageContainer>();
            foreach (var entry in (List<ushort>)isPayor(Payor))
                if (ftData.TaxBox.ContainsKey(entry))
                {
                    Vector3 containerPos = GetVector3(ftData.TaxBox[entry]);
                    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;
        }

        Vector3 GetVector3(XYZ xyz)
        {
            return new Vector3 { x = xyz.x, y = xyz.y, z = xyz.z };
        }

        private void GetSendMSG(BasePlayer player, string message, string arg1 = "", string arg2 = "", string arg3 = "", string arg4 = "")
        {
            string msg = string.Format(lang.GetMessage(message, this, player.UserIDString), arg1, arg2, arg3, arg4);
            SendReply(player, TitleColor + lang.GetMessage("title", this, player.UserIDString) + "</color>" + MsgColor + msg + "</color>");
        }

        private string GetMSG(string message, BasePlayer player = null, string arg1 = "", string arg2 = "", string arg3 = "", string arg4 = "")
        {
            string p = null;
            if (player != null)
                p = player.UserIDString;
            if (messages.ContainsKey(message))
                return string.Format(lang.GetMessage(message, this, p), arg1, arg2, arg3, arg4);
            else return message;
        }

        public void DestroyTaxPanel(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, PanelTax);
        }
        #endregion

        #region UI Creation

        private string PanelTax = "Tax";
        private string PanelOnScreen = "PanelOnScreen";

        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 CuiElementContainer CreateOverlayContainer(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 = "Overlay",
                    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);

            }
            static public void CreateTextOutline(ref CuiElementContainer element, string panel, string colorText, string colorOutline, string text, int size, string aMin, string aMax, TextAnchor align = TextAnchor.MiddleCenter)
            {
                element.Add(new CuiElement
                {
                    Parent = panel,
                    Components =
                    {
                        new CuiTextComponent{Color = colorText, FontSize = size, Align = align, Text = text },
                        new CuiOutlineComponent {Distance = "1 1", Color = colorOutline},
                        new CuiRectTransformComponent {AnchorMax = aMax, AnchorMin = aMin }
                    }
                });
            }
        }

        private Dictionary<string, string> UIColors = new Dictionary<string, string>
        {
            {"black", "0 0 0 1.0" },
            {"white", "1 1 1 1" },
        };
        #endregion

        #region UI Panels

        void OnScreen(BasePlayer player, string msg, string arg1 = "", string arg2 = "", string arg3 = "")
        {
            if (timers.ContainsKey(player.userID.ToString()))
            {
                timers[player.userID.ToString()].Destroy();
                timers.Remove(player.userID.ToString());
            }
            CuiHelper.DestroyUi(player, PanelOnScreen);
            var element = UI.CreateOverlayContainer(PanelOnScreen, "0.0 0.0 0.0 0.0", "0.15 0.85", "0.85.95", false);
            UI.CreateTextOutline(ref element, PanelOnScreen, UIColors["white"], UIColors["black"], GetMSG(msg, player, arg1, arg2, arg3), 24, "0.0 0.0", "1.0 1.0");
            CuiHelper.AddUi(player, element);
            timers.Add(player.userID.ToString(),timer.Once(4, () => CuiHelper.DestroyUi(player, PanelOnScreen)));
        }

        #endregion

        #region  External Functions
        public FactionsCore.FactionPlayer GetFactionPlayer(BasePlayer player)
        {
            if (!player.GetComponent<FactionsCore.FactionPlayer>()) return null;
            else return player.GetComponent<FactionsCore.FactionPlayer>();
        }

        public object GetFactionInfo(ushort ID, string request)
        {
            var result = FactionsCore.Call("GetFactionInfo", ID, request);
            if (result is bool || result == null) return false;
            if (result is IList<ulong> && result.GetType().IsGenericType && result.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>))) return (List<ulong>)result;
            if (result is ulong) return (ulong)result;
            if (result is string) return (string)result;
            return false;
        }

        [HookMethod("HasTaxBox")]
        bool HasTaxBox(ushort ID)
        {
            if (ftData.TaxBox.ContainsKey(ID)) return true;
            return false;
        }

        [HookMethod("TaxboxLocation")]
        object TaxboxLocation(ushort ID)
        {
            if (!HasTaxBox(ID)) return false;
            return (GetVector3(ftData.TaxBox[ID]));
        }
        #endregion

        #region UI Commands

        [ConsoleCommand("UI_SetTaxBox")] ///USED IN FACTIONS CORE
        private void cmdUI_SetTaxBox(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection.player as BasePlayer;
            if (player == null || GetFactionPlayer(player) == null || GetFactionPlayer(player).Faction == 0) return;
            ushort faction = GetFactionPlayer(player).Faction;
            ulong owner = 0L;
            List<ulong> moderators = new List<ulong>();
            var result1 = GetFactionInfo(faction, "owner");
            if (result1 is ulong)
                owner = (ulong)result1;
            var result2 = GetFactionInfo(faction, "moderators");
            if (result2 is IList<ulong> && result2.GetType().IsGenericType && result2.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>)))
                moderators = (List<ulong>)result2;
            if (!moderators.Contains(player.userID) && owner != player.userID) return;
            var hit = FindEntityFromRay(player);
            if (hit != null)
            {
                StorageContainer box = hit as StorageContainer;
                if (ftData.TaxBox.ContainsKey(faction))
                    ftData.TaxBox.Remove(faction);
                ftData.TaxBox.Add(faction, new XYZ { x = box.transform.localPosition.x, y = box.transform.localPosition.y, z = box.transform.localPosition.z });
                OnScreen(player, "NewTaxBox");
                SaveData();
            }
            else OnScreen(player, "NoBoxFound");

        }

        object FindEntityFromRay(BasePlayer player)
        {
            Ray ray = new Ray(player.eyes.position, Quaternion.Euler(player.input.state.current.aimAngles) * Vector3.forward);
            RaycastHit hit;
            if (!Physics.Raycast(ray, out hit, 20))
                return null;
            var hitEnt = hit.collider.GetComponentInParent<StorageContainer>();
            if (hitEnt != null)
                if (AllowedToBuild(player))
                    return hitEnt as StorageContainer;
                else OnScreen(player, "TaxBoxError");
            else OnScreen(player, "NoBox");
            return null;
        }

        static bool AllowedToBuild(BasePlayer player)
        {
            if (player == null) return false;
            List<BuildingPrivlidge> playerpriv = buildingPrivlidges.GetValue(player) as List<BuildingPrivlidge>;
            if (playerpriv == null || playerpriv.Count == 0)
            {
                return false;
            }
            foreach (BuildingPrivlidge priv in playerpriv.ToArray())
            {
                List<ProtoBuf.PlayerNameID> authorized = priv.authorizedPlayers;
                bool foundplayer = false;
                foreach (ProtoBuf.PlayerNameID pni in authorized.ToArray())
                    if (pni.userid == player.userID)
                        foundplayer = true;
                if (!foundplayer)
                    return false;
            }
            return true;
        }

        #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");
            }
            foreach (BasePlayer p in BasePlayer.activePlayerList)
            {
                GetSendMSG(p, "FactionTaxInfo", configData.TaxTimeLimit.ToString());
            }
            timers.Add("info",timer.Once(900, () => InfoLoop()));
        }

        private void SetBoxFullNotification(string ID)
        {
            timers.Add(ID, timer.Once(5 * 60, () => timers.Remove(ID)));
        }

        #endregion

        #region Classes
        class FactionTaxData
        {
            public Dictionary<ushort, List<ulong>> TaxPayers = new Dictionary<ushort, List<ulong>>();
            public Dictionary<int, PlayerTimers> TaxTimers = new Dictionary<int, PlayerTimers>();
            public Dictionary<ushort, XYZ> TaxBox = new Dictionary<ushort, XYZ>();
        }

        class PlayerTimers
        {
            public double ResetTime;
            public ushort Faction;
            public ulong TaxPayer;
        }

        class XYZ
        {
            public float x;
            public float y;
            public float z;
        }
        #endregion

        #region Data Management

        void SaveData()
        {
            FTDATA.WriteObject(ftData);
        }

        void LoadData()
        {
            try
            {
                ftData = FTDATA.ReadObject<FactionTaxData>();
                if(ftData == null)
                    ftData = new FactionTaxData();
            }
            catch
            {
                Puts("Couldn't load FactionsTax data, creating new datafile");
                ftData = new FactionTaxData();
            }
            if (ftData.TaxBox == null)
                ftData.TaxBox = new Dictionary<ushort, XYZ>();
            if (ftData.TaxPayers == null)
                ftData.TaxPayers = new Dictionary<ushort, List<ulong>>();
            if (ftData.TaxTimers == null)
                ftData.TaxTimers = new Dictionary<int, PlayerTimers>();
        }
        #endregion

        #region Config        
        private ConfigData configData;
        class ConfigData
        {
            public double TaxRate { get; set; }
            public int TaxTimeLimit { 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
        Dictionary<string, string> messages = new Dictionary<string, string>()
        {
            {"title", "FactionTax: " },
            {"FactionTaxInfo", "This server is running Factions Tax.Each player you kill will be required to pay a tax to your Faction Box for {0} hours."},
            {"NoBoxPrepped", "Error finding target tax box!" },
            {"TaxBoxDestroyed", "Your tax box has been destroyed!" },
            {"TaxBoxFull", "Your Faction tax box is full! Clear room to generate taxes." },
            {"NewTaxBox", "You have set a new Tax Box" },
            {"TaxRemoved", "You are no longering being taxed by {0}!" },
            {"NoBox", "You are not looking at a Storage Box!" },
            {"TaxBoxError", "You can only set a Tax Box in an authorized build zone." },
            {"NoBoxFound", "You are not looking at a box!" }
        };
        #endregion
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху