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

FREE PoliticalSurvival : 0.7.5 0.7.5

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Core;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("PoliticalSurvival", "Pho3niX90", "0.7.5")]
    [Description("Political Survival - Become the ruler, tax your subjects and keep them in line!")]
    class PoliticalSurvival : RustPlugin {
        bool firstRun = false;
        public bool DebugMode = false;
        Ruler ruler;
        PSConfig config;
        private Core.Libraries.Time _time = GetLibrary<Core.Libraries.Time>();
        static PoliticalSurvival _instance;
        private List<Ruler> rulerList = new List<Ruler>();
        string ConfigVersion = "0.0.4";
#region Settings Class
        public class TaxSource {
            public bool DispenserGather;
            public bool CropGather;
            public bool DispenserBonus;
            public bool QuarryGather;
            public bool ExcavatorGather;
            public bool CollectiblePickup;
            public bool SurveyGather;
            public TaxSource createDefault() {
                DispenserGather = true;
                CropGather = true;
                DispenserBonus = true;
                QuarryGather = true;
                ExcavatorGather = true;
                CollectiblePickup = true;
                SurveyGather = true;
                return this;
            }
        }
        public class PSConfig {
            public string Version;
            public bool showWelcomeMsg;
            public int maxHelis;
            public int heliItemCost;
            public int heliItemCostQty;
            public bool broadcastRulerPosition;
            public int broadcastRulerPositionAfter;
            public int broadcastRulerPositionAfterPercentage;
            public int taxMin;
            public int taxMax;
            public TaxSource taxSource;
            public int worldSize;
            public bool chooseNewRulerOnDisconnect;
            public int chooseNewRulerOnDisconnectMinutes;
            public bool rulerCanChooseAnotherRuler = true;
        }
        public class Ruler {
            public Vector3 taxContainerVector3;
            public uint taxContainerID;
            public double tax;
            public ulong ruler;
            public string rulerName;
            public ulong rulerId;
            public uint rulerSince;
            public int resourcesGot;
            public string realm;
            public Ruler(Vector3 tcv4, uint txId, double tx, ulong rlr, string rlrname, string rlm, ulong rid) {
                taxContainerVector3 = tcv4;
                taxContainerID = txId;
                tax = tx;
                ruler = rlr;
                rulerName = rlrname;
                realm = rlm;
                rulerId = rid;
            }
            public Ruler() {
            }
            public int GetResourceCount() {
                return resourcesGot;
            }
            public Ruler SetRulerSince(uint since) {
                rulerSince = since;
                return this;
            }
            public Ruler SetResourcesGot(int amnt) {
                resourcesGot = amnt;
                return this;
            }
            public long GetRulerSince() {
                return rulerSince;
            }
            public Ruler SetTaxContainerVector3(Vector3 vec) {
                taxContainerVector3 = vec;
                return this;
            }
            public Vector3 GetTaxContainerVector3() {
                return taxContainerVector3;
            }
            public Ruler SetTaxContainerID(uint storage) {
                taxContainerID = storage;
                return this;
            }
            public uint GetTaxContainerID() {
                return taxContainerID;
            }
            public Ruler SetTaxLevel(double tx) {
                tax = tx;
                return this;
            }
            public double GetTaxLevel() {
                return tax;
            }
            public Ruler SetRuler(ulong rlr) {
                ruler = rlr;
                rulerId = rlr;
                rulerSince = (new Core.Libraries.Time()).GetUnixTimestamp();
                return this;
            }
            public ulong GetRuler() {
                return ruler;
            }
            public double GetRuleLengthInMinutes() {
                return (new Core.Libraries.Time().GetUnixTimestamp() - rulerSince) / 60.0;
            }
            public double GetRulerOfflineMinutes() {
                return _instance.rulerOfflineAt == 0 ? 0.0 : ((new Core.Libraries.Time().GetUnixTimestamp() - _instance.rulerOfflineAt) / 60.0);
            }
            public Ruler SetRulerName(string name) {
                rulerName = name;
                return this;
            }
            public string GetRulerName() {
                return rulerName;
            }
            public Ruler SetRealmName(string rlm) {
                realm = rlm;
                return this;
            }
            public string GetRealmName() {
                return realm;
            }
        }
#endregion
#region Components
#region Heli Vars
        public int HeliLifeTimeMinutes = 5;
        public float HeliBaseHealth = 50000.0f;
        public float HeliSpeed = 50f;
        public float HeliSpeedMax = 200f;
        public int NumRockets = 50;
        public float ScanFrequencySeconds = 5;
        public float TargetVisible = 1000;
        public float MaxTargetRange = 300;
        public bool NotifyPlayers = true;
        public BasePlayer target;
#endregion
        class HeliComponent : FacepunchBehaviour {
            private BaseHelicopter heli;
            private PatrolHelicopterAI AI;
            private bool isFlying = true;
            private bool isRetiring = false;
            float timer;
            float timerAdd;
            void Awake() {
                heli = GetComponent<BaseHelicopter>();
                AI = heli.GetComponent<PatrolHelicopterAI>();
                heli.startHealth = _instance.HeliBaseHealth;
                AI.maxSpeed = Mathf.Clamp(_instance.HeliSpeed, 0.1f, _instance.HeliSpeedMax);
                AI.numRocketsLeft = _instance.NumRockets;
                attachGuns(AI);
                timerAdd = (Time.realtimeSinceStartup + Convert.ToSingle(_instance.HeliLifeTimeMinutes * 60));
                InvokeRepeating("ScanForTargets", _instance.ScanFrequencySeconds, _instance.ScanFrequencySeconds);
            }
            void FixedUpdate() {
                timer = Time.realtimeSinceStartup;
                if (timer >= timerAdd && !isRetiring) {
                    isRetiring = true;
                }
                if (isRetiring && isFlying) {
                    CancelInvoke("ScanForTargets");
                    isFlying = false;
                    heliRetire();
                }
            }
            internal void ScanForTargets() {
                foreach (ulong targetSteamId in _instance.target.Team.members) {
                    BasePlayer teamMemberToAttack = BasePlayer.Find(targetSteamId.ToString());
                    if (teamMemberToAttack.IsConnected) {
                        UpdateTargets(teamMemberToAttack);
                        _instance.DebugLog("Heli target found " + teamMemberToAttack);
                    }
                    UpdateAi();
                }
            }
            void UpdateAi() {
                _instance.DebugLog("Heli updating AI");
                AI.UpdateTargetList();
                AI.MoveToDestination();
                AI.UpdateRotation();
                AI.UpdateSpotlight();
                AI.AIThink();
                AI.DoMachineGuns();
            }
            void UpdateTargets(BasePlayer Player) {
                AI._targetList.Add(new PatrolHelicopterAI.targetinfo((BaseEntity)Player, Player));
            }
            internal void attachGuns(PatrolHelicopterAI helicopter) {
                if (helicopter == null) return;
                var guns = new List<HelicopterTurret>();
                guns.Add(helicopter.leftGun);
                guns.Add(helicopter.rightGun);
                for (int i = 0; i < guns.Count; i++) {
                    // Leave these as hardcoded for now
                    var turret = guns[i];
                    turret.fireRate = 0.125f;
                    turret.timeBetweenBursts = 3f;
                    turret.burstLength = 3f;
                    turret.maxTargetRange = _instance.MaxTargetRange;
                }
            }
            internal void heliRetire() {
                AI.Retire();
            }
            public void UnloadComponent() {
                Destroy(this);
            }
            void OnDestroy() {
                CancelInvoke("ScanForTargets");
            }
        }
#endregion
#region Variables
        Dictionary<string, string> serverMessages;
        int worldSize = 3500;
        BasePlayer currentRuler;
        uint rulerOfflineAt = 0;
        private ILocator liveLocator = null;
        private ILocator locator = null;
        private bool Changed = false;
        protected Dictionary<string, Timer> Timers {
            get;
        }
        = new Dictionary<string, Timer>();
#endregion
        private void Init() {
            config = Config.ReadObject<PSConfig>();
            LoadServerMessages();
            if (config != null && !config.Version.Equals(ConfigVersion)) {
                Puts("Config outdated, will update to new version.");
                config = UpgradeConfig(config.Version, ConfigVersion);
                SaveConfig();
            }
        }
        private void Loaded() {
            LoadRuler();
            _instance = this;
            Puts("Political Survival is starting...");
            if (ConVar.Server.worldsize == 0) Puts("WARNING: worldsize is reporting as 0, this is not possible and will default to config size.Please make sure the config has the correct size.");
            if (ConVar.Server.worldsize > 0) worldSize = ConVar.Server.worldsize;
            liveLocator = new RustIOLocator(worldSize);
            locator = new LocatorWithDelay(liveLocator, 60);
            if (ruler.GetRulerSince() == 0) {
                ruler.SetRulerSince(_time.GetUnixTimestamp());
                SaverRuler();
            }
            Puts("Realm name is " + ruler.GetRealmName());
            Puts("Tax level is " + ruler.GetTaxLevel());
            Puts("TaxChest is set " + !ruler.GetTaxContainerVector3().Equals(Vector3.negativeInfinity));
            Puts("Political Survival: Started");
            currentRuler = GetPlayer(ruler.GetRuler().ToString());
            Puts("Current ruler " + (currentRuler != null ? "is set" : "is null"));
            if (currentRuler != null) Puts("Ruler is " + ruler.GetRuler() + " (" + currentRuler.displayName + ")");
            Timers.Add("AdviseRulerPosition", timer.Repeat(Math.Max(config.broadcastRulerPositionAfter, 60), 0, () => AdviseRulerPosition()));
            SaverRuler();
            Puts($"Ruler offline at {rulerOfflineAt}");
            if (rulerOfflineAt != 0 || currentRuler == null || currentRuler.IsConnected) {
                if (config.chooseNewRulerOnDisconnect && (ruler.GetRulerOfflineMinutes() >= (1 * config.chooseNewRulerOnDisconnectMinutes) || (rulerOfflineAt == 0 && (currentRuler == null || !currentRuler.IsConnected)))) {
                    TryForceNewRuler(true);
                }
            }
        }
        void OnServerShutdown() {
            SaveConfig();
            SaverRuler();
        }
        void Unload() {
            Puts("Unload called");
            SaverRuler();
            foreach (Timer t in Timers.Values) t.Destroy();
            Timers.Clear();
        }
        void OnPlayerInit(BasePlayer player) {
            if (config.showWelcomeMsg) PrintToChat(player.displayName + " " + lang.GetMessage("PlayerConnected", this, player.UserIDString) + " " + ruler.GetRealmName());
            if (currentRuler != null && ruler.ruler == currentRuler.userID) {
                rulerOfflineAt = 0;
            }
        }
        void OnPlayerDisconnected(BasePlayer player, string reason) {
            if (config.showWelcomeMsg) PrintToChat(player.displayName + " " + lang.GetMessage("PlayerDisconnected", this, player.UserIDString) + " " + ruler.GetRealmName());
            if (currentRuler != null && player.userID == currentRuler.userID) {
                rulerOfflineAt = _time.GetUnixTimestamp();
                timer.Once(60 * config.chooseNewRulerOnDisconnectMinutes, () => {
                    if (rulerOfflineAt != 0) TryForceNewRuler(true);
                }
                );
            }
        }
#region GatheringHooks
        void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item) {
            DebugLog("OnDispenserGather start");
            if (!config.taxSource.DispenserGather || dispenser == null || entity == null || Item == null || ruler.GetTaxContainerID() == 0) return;
            BasePlayer player = entity as BasePlayer;
            DebugLog("OnDispenserGather stage 2 " + item.flags.ToString() + " " + item.amount + " " + player.displayName);
            int netAmount = AddToTaxContainer(item, player.displayName);
            item.amount = (netAmount > 0) ? netAmount : item.amount;
        }
        private void OnDispenserBonus(ResourceDispenser dispenser, BaseEntity entity, Item item) {
            if (!config.taxSource.DispenserBonus) return;
            BasePlayer player = entity as BasePlayer;
            DebugLog("OnDispenserBonus start");
            int netAmount = AddToTaxContainer(item, player.displayName);
            item.amount = (netAmount > 0) ? netAmount : item.amount;
        }
        void OnGrowableGather(GrowableEntity plant, Item item, BasePlayer player) {
            if (!config.taxSource.CropGather) return;
            DebugLog("OnPlantGather start");
            int netAmount = AddToTaxContainer(item, player.displayName);
            item.amount = (netAmount > 0) ? netAmount : item.amount;
        }
        private void OnQuarryGather(MiningQuarry quarry, Item item) {
            DebugLog("OnQuarryGather start");
            if (!config.taxSource.QuarryGather) return;
            int netAmount = AddToTaxContainer(item, quarry.name);
            item.amount = (netAmount > 0) ? netAmount : item.amount;
        }
        private void OnExcavatorGather(ExcavatorArm excavator, Item item) {
            DebugLog("OnExcavatorGather start");
            if (!config.taxSource.ExcavatorGather) return;
            int netAmount = AddToTaxContainer(item, excavator.name);
            item.amount = (netAmount > 0) ? netAmount : item.amount;
        }
        private void OnCollectiblePickup(Item item, BasePlayer player) {
            DebugLog("OnCollectiblePickup start");
            if (!config.taxSource.CollectiblePickup) return;
            int netAmount = AddToTaxContainer(item, player.displayName);
            item.amount = (netAmount > 0) ? netAmount : item.amount;
        }
        private void OnSurveyGather(SurveyCharge surveyCharge, Item item) {
            DebugLog("OnSurveyGather start");
            if (!config.taxSource.SurveyGather) return;
            int netAmount = AddToTaxContainer(item, surveyCharge.name);
            item.amount = (netAmount > 0) ? netAmount : item.amount;
        }
#endregion
        int AddToTaxContainer(Item item, string displayName) {
            if (!IsChestSet()) return -1;
            DebugLog("AddToTaxContainer start");
            if (item == null || ruler.GetTaxContainerID() == 0 || ruler.GetRuler() == 0 || ruler.GetTaxLevel() == 0 || ruler.GetTaxContainerVector3() == Vector3.negativeInfinity) return -1;
            ItemDefinition ToAdd = ItemManager.FindItemDefinition(item.info.itemid);
            int Tax = Convert.ToInt32(Math.Ceiling((item.amount * ruler.GetTaxLevel()) / 100));
            ItemContainer container = FindStorageContainer(ruler.GetTaxContainerID()).inventory;
            if (ToAdd != null && container != null) {
                if (item.CanMoveTo(container)) {
                    container.AddItem(ToAdd, Tax);
                    ruler.resourcesGot += Tax;
                }
            }
            DebugLog("User " + displayName + " gathered " + item.amount + " x " + item.info.shortname + ", and " + Tax + " was taxed");
            DebugLog("items added to tax container");
            return item.amount - Tax;
        }
        void OnEntityDeath(BaseCombatEntity entity, HitInfo info) {
            if (entity == null) return;
            BasePlayer player = entity as BasePlayer;
            /* if (entity != null) { //tax oil
                 if (entity.ShortPrefabName == "oil_barrel") {
                     List<DroppedItem> ItemsDropped = new List<DroppedItem>();
                     Vis.Entities<DroppedItem>(entity.transform.position, 1, ItemsDropped);
                     foreach (DroppedItem ditem in ItemsDropped) {
                         if (ditem == null) return;
                         Item item = ditem?.item;
                         Puts($"Player {player.displayName} - {item.info.displayName} x {item.amount}");
                         item.amount = AddToTaxContainer(item, player.displayName);
                     }
                 }
             }*/
            if (player != null) {
                if (IsRuler(player.userID)) {
                    BasePlayer killer = null;
                    if (info != null) killer = info.Initiator as BasePlayer;
                    if (killer != null && killer.userID != player.userID && !(killer is NPCPlayer)) {
                        SetRuler(killer);
                        PrintToChat(string.Format(lang.GetMessage("RulerMurdered", this), killer.displayName));
                    }
                    else {
                        ruler.SetRuler(0).SetRulerName(null);
                        currentRuler = null;
                        PrintToChat(string.Format(lang.GetMessage("RulerDied", this)));
                    }
                    SaverRuler();
                }
            }
        }
        public void TryForceRuler() {
            if (currentRuler == null && TryForceNewRuler(false)) PrintToChat("<color=#008080ff>{0}</color> has been made the new Ruler.Kill him!", currentRuler.displayName);
        }
#region Commands
        [ConsoleCommand("ps.fnr")]
        private void SuicideHandler(ConsoleSystem.Arg arg) {
            TryForceRulerCmd(arg.Connection.player as BasePlayer, null, arg.Args);
        }
        [ChatCommand("fnr")]
        void TryForceRulerCmd(BasePlayer player, string command, string[] args) {
            if (!player.IsAdmin) {
                Puts($"Player {player.displayName} tried using fnr");
                return;
            }
            //if (player != null && !player.IsAdmin && !player.isServer && (!IsRuler(player.userID) || !config.rulerCanChooseAnotherRuler)) return;
            if (args.Length == 0) {
                if (TryForceNewRuler(true)) {
                    PrintToChat("<color=#008080ff>{0}</color> has been made the new Ruler.Kill him!", currentRuler.displayName);
                }
                else {
                    PrintToChat("Couldn't force a new ruler :(");
                }
            }
            else if (args.Length == 1) {
                BasePlayer ruler = null;
                try {
                    ruler = BasePlayer.Find(args[0]);
                }
                catch (Exception e) {
                    if (player != null) PrintToChat(player, "ERR: " + lang.GetMessage("PlayerNotFound", this), args[0]);
                    return;
                }
                if (ruler == null) {
                    PrintToChat(lang.GetMessage("PlayerNotFound", this), args[0]);
                    return;
                }
                SetRuler(ruler);
                PrintToChat("<color=#008080ff>{0}</color> has been made the new Ruler.Kill him!", currentRuler.displayName);
            }
        }
        [ChatCommand("heli")]
        void HeliCommmand(BasePlayer player, string command, string[] args) {
            if (!IsRuler(player.userID)) {
                PrintToChat(player, "You aren't the boss");
                return;
            }
            if (args.Length != 1) {
                PrintToChat(player, "Usage '/heli player' where player can also be partial name");
                return;
            }
            BasePlayer playerToAttack = GetPlayer(args[0]);
            if (playerToAttack == null) {
                PrintToChat(player, lang.GetMessage("PlayerNotFound", this), args[0]);
                return;
            }
            Puts("Can afford heli?");
            if (!CanAffordheliStrike(player)) {
                PrintToChat(player, "Ordering a heli strike costs {0} {1}", config.heliItemCostQty, ItemManager.FindItemDefinition(config.heliItemCost).displayName.english);
                return;
            }
            int heliCount = UnityEngine.Object.FindObjectsOfType<BaseHelicopter>().Count();
            if (heliCount >= config.maxHelis) {
                PrintToChat(player, "Insufficient airspace for more than {0} helicopters, please wait for existing patrols to complete", config.maxHelis);
                return;
            }
            Puts("OrderheliStrike");
            OrderheliStrike(playerToAttack);
            PrintToChat(player, "The heli is inbound");
        }
        [ChatCommand("taxrange")]
        void AdmSetTaxChestCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin && args.Length == 2) {
                int taxMin = 0;
                int taxMax = 10;
                int.TryParse(args[0], out taxMin);
                int.TryParse(args[1], out taxMax);
                config.taxMin = taxMin;
                config.taxMax = taxMax;
                PrintToChat(player, $"Tax range set to Min:{config.taxMin}% - Max:{config.taxMax}%");
                SaveConfig();
                SaverRuler();
            }
        }
        [ChatCommand("settaxchest")]
        void SetTaxChestCommand(BasePlayer player, string command, string[] arguments) {
            if (!IsRuler(player.userID)) {
                SendReply(player, lang.GetMessage("RulerError", this, player.UserIDString));
                return;
            }
            var layers = LayerMask.GetMask("Deployed");
            RaycastHit hit = new RaycastHit();
            DebugLog("Test 1");
            if (Player != null && Physics.Raycast(player.eyes.HeadRay(), out hit, 50, layers)) {
                DebugLog("Test 2");
                BaseEntity entity = hit.GetEntity();
                if (entity != null && (entity.ShortPrefabName.Contains("box.wooden") || entity.ShortPrefabName.Contains("cupboard.tool.deployed"))) {
                    DebugLog("Test 3");
                    Vector3 boxPosition = entity.transform.position;
                    StorageContainer boxStorage = FindStorageContainer(boxPosition);
                    if (boxStorage != null) {
                        DebugLog("Test 4");
                        ruler.SetTaxContainerVector3(boxPosition).SetTaxContainerID(entity.net.ID);
                        if (entity.ShortPrefabName.Contains("box.wooden")) {
                            entity.skinID = 1482844040;
                            //https://steamcommunity.com/sharedfiles/filedetails/?id=1482844040&searchtext=
                            entity.SendNetworkUpdate();
                        }
                        DebugLog("Chest set");
                        SaverRuler();
                        SendReply(player, lang.GetMessage("SetNewTaxChest", this, player.UserIDString));
                    }
                }
                else {
                    DebugLog("Looking at " + entity.ShortPrefabName);
                    SendReply(player, lang.GetMessage("SetNewTaxChestNotFound", this, player.UserIDString));
                    SendReply(player, lang.GetMessage("SettingNewTaxChest", this, player.UserIDString));
                }
            }
            else {
                SendReply(player, lang.GetMessage("SetNewTaxChestNotFound", this, player.UserIDString));
                SendReply(player, lang.GetMessage("SettingNewTaxChest", this, player.UserIDString));
            }
        }
        [ChatCommand("tax")]
        void InfoCommand2(BasePlayer player, string command, string[] arguments) {
            InfoCommand(player, command, arguments);
        }
        [ChatCommand("rinfo")]
        void InfoCommand(BasePlayer player, string command, string[] arguments) {
            string RulerName = string.Empty;
            if (ruler.GetRuler() > 0) {
                BasePlayer BaseRuler = BasePlayer.FindAwakeOrSleeping(ruler.GetRuler().ToString());
                RulerName = BaseRuler != null ? BaseRuler.displayName : lang.GetMessage("ClaimRuler", this, player.UserIDString);
            }
            else {
                RulerName = lang.GetMessage("ClaimRuler", this, player.UserIDString);
            }
            if (ruler.GetRuler() != 0) {
                SendReply(player, "<color=#008080ff>" + lang.GetMessage("InfoRuler", this, player.UserIDString) + ": </color>" + ruler.GetRulerName());
            }
            else {
                SendReply(player, lang.GetMessage("ClaimRuler", this, player.UserIDString) + ": " + ruler.GetRulerName());
            }
            SendReply(player, "<color=#008080ff>" + lang.GetMessage("InfoRealmName", this, player.UserIDString) + ": </color>" + ruler.GetRealmName());
            SendReply(player, "<color=#008080ff>" + lang.GetMessage("InfoTaxLevel", this, player.UserIDString) + ": </color>" + ruler.GetTaxLevel() + "%" + ((!IsChestSet()) ? " (0%, chest not set)" : ""));
            SendReply(player, "<color=#008080ff>" + lang.GetMessage("InfoRuleLength", this, player.UserIDString) + ": </color>" + Math.Round(ruler.GetRuleLengthInMinutes()) + " minutes");
            SendReply(player, "<color=#008080ff>" + lang.GetMessage("InfoResources", this, player.UserIDString) + ": </color>" + ruler.GetResourceCount());
            if (IsRuler(player.userID)) {
                SendReply(player, lang.GetMessage("SettingNewTaxChest", this, player.UserIDString));
                SendReply(player, string.Format(lang.GetMessage("InfoTaxCmd", this, player.UserIDString), config.taxMin, config.taxMax) + ": " + ruler.GetTaxLevel() + "%");
            }
        }
        [ChatCommand("claimruler")]
        void ClaimRuler(BasePlayer player, string command, string[] arguments) {
            if (currentRuler == null) {
                PrintToChat("<color=#008080ff><b>" + player.displayName + "</b></color> " + lang.GetMessage("IsNowRuler", this));
                SetRuler(player);
            }
        }
        [ChatCommand("settax")]
        void SetTaxCommand(BasePlayer player, string command, string[] args) {
            if (IsRuler(player.userID)) {
                double newTaxLevel = 0.0;
                if (double.TryParse(args[0], out newTaxLevel)) {
                    double oldTax = ruler.GetTaxLevel();
                    if (newTaxLevel == ruler.GetTaxLevel()) return;
                    Puts("Tax have been changed by " + player.displayName + " from " + ruler.GetTaxLevel() + " to " + newTaxLevel);
                    Puts($"Tax {config.taxMin} {config.taxMax}");
                    if (newTaxLevel > config.taxMax) newTaxLevel = config.taxMax;
                    else if (newTaxLevel < config.taxMin) newTaxLevel = config.taxMin;
                    SetTaxLevel(newTaxLevel);
                    PrintToChat(string.Format(lang.GetMessage("UpdateTaxMessage", this), oldTax, newTaxLevel));
                }
            }
            else SendReply(player, lang.GetMessage("RulerError", this, player.UserIDString));
        }
        //TODO ended here with case renaming to camelCase
        [ChatCommand("realmname")]
        void RealmNameCommand(BasePlayer player, string command, string[] arguments) {
            if (IsRuler(player.userID)) {
                string NewName = MergeParams(0, arguments);
                if (!String.IsNullOrEmpty(NewName)) {
                    SetRealmName(NewName);
                }
            }
            else SendReply(player, lang.GetMessage("RulerError", this, player.UserIDString));
        }
        [ChatCommand("rplayers")]
        void PlayersCommand(BasePlayer player, string command, string[] arguments) {
            StringBuilder builder = new StringBuilder();
            int playerCount = BasePlayer.activePlayerList.Count;
            builder.Append(string.Format(lang.GetMessage("OnlinePlayers", this), playerCount) + " ");
            List<string> players = new List<string>();
            foreach (BasePlayer pl in BasePlayer.activePlayerList) {
                players.Add("<color=#ff0000ff>" + pl.displayName + "</color>");
            }
            builder.Append(String.Join(", ", players));
            SendReply(player, builder.ToString());
        }
#endregion
        bool IsPlayerOnline(string partialNameOrID) {
            return GetPlayer(partialNameOrID).IsConnected;
        }
        bool IsChestSet() {
            return ruler.taxContainerID > 0;
        }
        BasePlayer GetPlayer(string partialNameOrID) {
            return BasePlayer.Find(partialNameOrID);
        }
        string MergeParams(int start, string[] paramz) {
            var merged = new StringBuilder();
            for (int i = start; i < paramz.Length; i++) {
                if (i > start) merged.Append(" ");
                merged.Append(paramz[i]);
            }
            return merged.ToString();
        }
        bool IsRuler(ulong steamId) {
            return currentRuler != null && currentRuler.userID == steamId;
        }
        public bool CanAffordheliStrike(BasePlayer player) {
            return player.inventory.GetAmount(config.heliItemCost) >= config.heliItemCostQty;
        }
        public void OrderheliStrike(BasePlayer playerToAttack) {
            // Deduct the cost
            if (currentRuler == null) currentRuler = GetPlayer(ruler.GetRuler().ToString());
            List<Item> collector = new List<Item>();
            currentRuler.inventory.Take(collector, config.heliItemCost, config.heliItemCostQty);
            Puts("Spawn the birdie");
            //spawn the birdie
            BaseHelicopter ent = GameManager.server.CreateEntity("assets/prefabs/npc/patrol helicopter/patrolhelicopter.prefab", new Vector3(), new Quaternion(), true) as BaseHelicopter;
            if (ent != null && playerToAttack != null) {
                target = playerToAttack;
                ent.GetComponent<PatrolHelicopterAI>().SetInitialDestination(playerToAttack.transform.position + new Vector3(0.0f, 10f, 0.0f), 0.25f);
                ent.Spawn();
                ent.gameObject.AddComponent<HeliComponent>();
                timer.Once(HeliLifeTimeMinutes * 60, () => ent.GetComponent<HeliComponent>().heliRetire());
            }
        }
        void SetRuler(BasePlayer bpruler) {
            Puts("New Ruler! " + bpruler.displayName);
            ruler.SetRuler(bpruler.userID).SetRulerName(bpruler.displayName).SetTaxContainerID(0).SetTaxLevel(config.broadcastRulerPositionAfterPercentage).SetTaxContainerVector3(Vector3.negativeInfinity).SetRealmName(GetMsg("DefaultRealm")).SetRulerSince(_time.GetUnixTimestamp()).SetResourcesGot(0);
            currentRuler = bpruler;
            SaverRuler();
        }
        void SetTaxLevel(double newTaxLevel) {
            ruler.SetTaxLevel(newTaxLevel);
            SaverRuler();
        }
        void SetRealmName(string newName) {
            if (newName.Length > 36) newName = newName.Substring(0, 36);
            PrintToChat(string.Format(lang.GetMessage("RealmRenamed", this), newName));
            ruler.SetRealmName(newName);
            SaverRuler();
        }
        StorageContainer FindStorageContainer(Vector3 position) {
            foreach (StorageContainer cont in StorageContainer.FindObjectsOfType<StorageContainer>()) {
                Vector3 ContPosition = cont.transform.position;
                if (ContPosition == position) {
                    Puts("Tax Container instance found: " + cont.GetEntity().GetInstanceID());
                    ruler.SetTaxContainerID(cont.net.ID);
                    return cont;
                }
            }
            return null;
        }
        StorageContainer FindStorageContainer(uint netid) {
            return (StorageContainer)BaseNetworkable.serverEntities.Find(netid);
        }
#region Player Grid Coordinates and Locators
        public interface ILocator {
            string GridReference(Vector3 component, out bool moved);
        }
        public class RustIOLocator : ILocator {
            public RustIOLocator(int worldSize) {
                worldSize = (worldSize != 0) ? worldSize : (ConVar.Server.worldsize > 0) ? ConVar.Server.worldsize : 3500;
                translate = worldSize / 2f;
                //offset
                gridWidth = (worldSize * 0.0066666666666667f);
                scale = worldSize / gridWidth;
            }
            private readonly float translate;
            private readonly float scale;
            private readonly float gridWidth;
            public string GridReference(Vector3 pos, out bool moved) {
                float x = pos.x + translate;
                float z = pos.z + translate;
                int lat = (int)Math.Floor(x / scale);
                //letter
                char latChar = (char)('A' + lat);
                int lon = (int)Math.Round(gridWidth) - (int)Math.Floor(z / scale);
                //number
                moved = false;
                // We dont know, so just return false
                return string.Format("{0}{1}", latChar, lon);
            }
        }
        public class LocatorWithDelay : ILocator {
            public LocatorWithDelay(ILocator liveLocator, int updateInterval) {
                this.liveLocator = liveLocator;
                this.updateInterval = updateInterval;
            }
            private readonly ILocator liveLocator;
            private readonly int updateInterval;
            private readonly Dictionary<Vector3, ExpiringCoordinates> locations = new Dictionary<Vector3, ExpiringCoordinates>();
            public string GridReference(Vector3 pos, out bool moved) {
                ExpiringCoordinates item = null;
                bool m;
                if (locations.ContainsKey(pos)) {
                    item = locations[pos];
                    if (item.Expires < DateTime.Now) {
                        string location = liveLocator.GridReference(pos, out m);
                        item.GridChanged = item.Location != location;
                        item.Location = location;
                        item.Expires = DateTime.Now.AddSeconds(updateInterval);
                    }
                }
                else {
                    item = new ExpiringCoordinates();
                    item.Location = liveLocator.GridReference(pos, out m);
                    item.GridChanged = true;
                    item.Expires = DateTime.Now.AddSeconds(updateInterval);
                    locations.Add(pos, item);
                }
                moved = item.GridChanged;
                return item.Location;
            }
            class ExpiringCoordinates {
                public string Location {
                    get;
                    set;
                }
                public bool GridChanged {
                    get;
                    set;
                }
                public DateTime Expires {
                    get;
                    set;
                }
            }
        }
#endregion
#region Misc
        private MonumentInfo FindMonument(Vector3 pos) {
            MonumentInfo monumentClosest;
            foreach (var monument in TerrainMeta.Path.Monuments) {
                if (monument.name.Contains("oil", CompareOptions.IgnoreCase) || monument.name.Contains("cargo", CompareOptions.IgnoreCase)) {
                    float dist = Vector3.Distance(monument.transform.position, pos);
                    if (dist <= 80) {
                        monumentClosest = monument;
                        return monumentClosest;
                    }
                }
                else {
                    continue;
                }
            }
            return null;
        }
#endregion
#region Timers and Events
        void AdviseRulerPosition() {
            if (currentRuler != null && (config.broadcastRulerPosition || (config.broadcastRulerPositionAfterPercentage > 0 && ruler.GetTaxLevel() > config.broadcastRulerPositionAfterPercentage))) {
                bool moved;
                if (currentRuler == null) return;
                string rulerMonument = FindMonument(currentRuler.transform.position)?.displayPhrase.english;
                string rulerGrid = locator.GridReference(currentRuler.transform.position, out moved);
                string rulerCoords = rulerMonument != null && rulerMonument.Length > 0 ? rulerMonument : rulerGrid;
                if (moved) PrintToChat(GetMsg("RulerLocation_Moved"), currentRuler.displayName, rulerCoords);
                else PrintToChat(GetMsg("RulerLocation_Static"), currentRuler.displayName, rulerCoords);
            }
            /*
            if (config.chooseNewRulerOnDisconnect && (currentRuler == null && BasePlayer.activePlayerList.Count > 0 || ruler.GetRulerOfflineMinutes() > 0 || !currentRuler.IsConnected)) {
                timer.Once(60 * config.chooseNewRulerOnDisconnectMinutes, () => TryForceRuler());
            }
            */
        }
        public bool TryForceNewRuler(bool force) {
            if (currentRuler != null && !force) return false;
            BasePlayer player = GetRandomPlayer();
            if (player != null) {
                SetRuler(player);
                return true;
            }
            return false;
        }
        BasePlayer GetRandomPlayer() {
            ListHashSet<BasePlayer> players = BasePlayer.activePlayerList;
            int activePlayers = players.Count;
            if (activePlayers > 1) {
                return players[Core.Random.Range(0, activePlayers - 1)];
            }
            return activePlayers == 1 ? players.First() : null;
        }
#endregion
        void SaverRuler() {
            Interface.Oxide.DataFileSystem.WriteObject<Ruler>("PoliticalSurvival", ruler, true);
        }
        void LoadRuler() {
            if (Interface.Oxide.DataFileSystem.ExistsDatafile("PoliticalSurvival")) {
                ruler = Interface.Oxide.DataFileSystem.ReadObject<Ruler>("PoliticalSurvival");
                Puts("ruler loaded");
            }
            else {
                Puts("Settings doesn't exist, creating default");
                ruler = new Ruler().SetRuler(0).SetRealmName(lang.GetMessage("DefaultRealm", this)).SetTaxLevel(0.0).SetTaxContainerID(0).SetResourcesGot(0).SetTaxContainerVector3(Vector3.negativeInfinity);
                SaverRuler();
            }
        }
        T GetConfig<T>(string name, T defaultValue) => Config[name] == null ? defaultValue : (T)Convert.ChangeType(Config[name], typeof(T));
        protected override void LoadDefaultConfig() {
            firstRun = true;
            Puts("Creating a new configuration file");
            Config.WriteObject(UpgradeConfig(), true);
            SaveConfig();
        }
        private PSConfig GetDefaultConfig() {
            return UpgradeConfig("", "");
        }
        PSConfig UpgradeConfig(string oldVersion = "", string newVersion = "") {
            if ((!oldVersion.Equals("") || !newVersion.Equals("")) && !oldVersion.Equals(newVersion)) {
                if (newVersion.Equals("0.0.2")) {
                    config.Version = ConfigVersion;
                    config.taxMin = 0;
                    config.taxMax = 35;
                    config.taxSource = new TaxSource().createDefault();
                    SaveConfig();
                    return config;
                }
                if (newVersion.Equals("0.0.4")) {
                    config.worldSize = 3500;
                    config.chooseNewRulerOnDisconnect = true;
                    config.chooseNewRulerOnDisconnectMinutes = 60;
                    config.rulerCanChooseAnotherRuler = true;
                    SaveConfig();
                    return config;
                }
            }
            return new PSConfig {
                Version = ConfigVersion, showWelcomeMsg = false, maxHelis = 2, heliItemCost = 13994, heliItemCostQty = 500, broadcastRulerPosition = false, broadcastRulerPositionAfter = 60, broadcastRulerPositionAfterPercentage = 10, taxMin = 0, taxMax = 35, taxSource = new TaxSource().createDefault(), worldSize = 3500, chooseNewRulerOnDisconnect = true, chooseNewRulerOnDisconnectMinutes = 60, rulerCanChooseAnotherRuler = true
            }
            ;
        }
        void DebugLog(string msg) {
            if (DebugMode) Puts(msg);
        }
        string GetMsg(string msg) => lang.GetMessage(msg, this);
        void LoadServerMessages() {
            serverMessages = new Dictionary<string, string>();
            serverMessages.Add("StartingInformation", "<color=yellow>Welcome to {0}</color>.If you are new, we run a custom plugin where you can become the server Ruler, tax players, and control the economy.Type <color=#008080ff>/rinfo</color> for more information.");
            serverMessages.Add("PlayerConnected", "has connected to");
            serverMessages.Add("PlayerDisconnected", "has disconnected from");
            serverMessages.Add("RulerDied", "<color=#ff0000ff>The Ruler has died!</color>");
            serverMessages.Add("RulerMurdered", "<color=#ff0000ff>The Ruler has been murdered by {0}, who is now the new Ruler.</color>");
            serverMessages.Add("RealmRenamed", "The realm has been renamed to <color=#008080ff>{0}</color>");
            serverMessages.Add("DefaultRealm", "Land of the cursed");
            serverMessages.Add("OnlinePlayers", "Online players ({0}):");
            serverMessages.Add("PrivateError", "is either offline or you typed the name wrong.");
            serverMessages.Add("PrivateFrom", "PM from");
            serverMessages.Add("PrivateTo", "PM sent to");
            serverMessages.Add("RulerError", "You need to be the Ruler to do that!");
            serverMessages.Add("SettingNewTaxChest", "Look at a Wooden box  or TC and type <color=#008080ff>/settaxchest</color>");
            serverMessages.Add("SetNewTaxChestNotFound", "You must look at a wooden box or TC to set tax chest");
            serverMessages.Add("SetNewTaxChest", "You have set the new tax chest.");
            serverMessages.Add("ClaimRuler", "There is no ruler! <color=#008080ff>/claimruler</color> to become the new Ruler!");
            serverMessages.Add("IsNowRuler", "is now the Ruler!");
            serverMessages.Add("InfoRuler", "Ruler");
            serverMessages.Add("InfoRealmName", "Realm Name");
            serverMessages.Add("InfoTaxLevel", "Tax level");
            serverMessages.Add("InfoRuleLength", "Rule Length");
            serverMessages.Add("InfoResources", "Resource received");
            serverMessages.Add("InfoTaxCmd", "Use <color=#008080ff>/settax {0}-{1}</color> to set tax level");
            serverMessages.Add("RulerLocation_Moved", "Ruler <color=#ff0000ff>{0}</color> is on the move, now at <color=#ff0000ff>{1}</color>.");
            serverMessages.Add("RulerLocation_Static", "Ruler <color=#ff0000ff>{0}</color> is camping out at <color=#ff0000ff>{1}</color>");
            serverMessages.Add("UpdateTaxMessage", "The ruler has changed the tax from <color=#ff0000ff>{0}%</color> to <color=#ff0000ff>{1}%</color>");
            serverMessages.Add("PlayerNotFound", "player \"{0}\" not found, or ambiguous");
            lang.RegisterMessages(serverMessages, this);
        }
    }
}

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