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

FREE AbandonedBases : 2.1.9 2.1.9

Нет прав для скачивания
C#:
/*
*  <----- End-User License Agreement ----->
*  
*  You may not merge, publish, distribute, sublicense, or sell copies of This Software without the Developer’s consent.Copy or modify is allowed for personal use only.*  
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
*  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
*  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
*  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*
*  Developer: nivex (mswenson82@yahoo.com)
*
*  Copyright © nivex.All rights reserved.███▄    ██ ██▓ ██▒   ██▒▓█████ ██▓    ██▓
 ██ ▀█  ░█ ▓██▒▓██░   ██▒▓█  ▀   ▓██▒██▓
▓██  ▀█ ██▒▒██▒ ▓██  █▒░▒████     ▒██▒
▓██▒  ▐▌██▒░██░  ▒██ █░░▒▓█  ▄   ░██░██░
▒██░   ▓██░░██░   ▒▀█░  ░▒████▒░██░   ██▓
░ ▒░   ▒ ▒ ░▓     ░ ▐░  ░░ ▒░ ░░▓     ▓ ░
░ ░░   ░ ▒░ ▒ ░   ░ ░░   ░ ░  ░ ▒ ░   ▒ ░ 
   ░   ░ ░  ▒ ░     ░░     ░    ▒ ░   ▒
         ░  ░        ░     ░  ░ ░     ░
*/
using Facepunch;
using Facepunch.Math;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using Oxide.Game.Rust.Cui;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using static Oxide.Plugins.AbandonedBasesExtensionMethods.ExtensionMethods;
namespace Oxide.Plugins {
    [Info("Abandoned Bases", "nivex", "2.1.9")]
    [Description("Allows bases to become raidable when the owner becomes inactive")]
    public class AbandonedBases : RustPlugin {
#region Variables
        [PluginReference]
        Plugin Backpacks, Economics, ServerRewards, IQEconomic, RaidableBases, Clans, Friends, Notify, AdvancedAlerts, ZoneManager, SkillTree, LimitEntities, XLevels;
        private new const string Name = "Abandoned Bases";
        private List<string> ID_FLOORS = new() {
            "floor", "floor.frame", "floor.grill", "floor.ladder.hatch", "floor.triangle", "floor.triangle.frame", "floor.triangle.grill", "floor.triangle.ladder.hatch"
        }
        ;
        private List<string> ID_DQD = new() {
            "foundation", "foundation.triangle", "roof.triangle", "roof"
        }
        ;
        private List<string> TrueDamage = new() {
            "Barricade", "SimpleBuildingBlock", "IceFence", "TeslaCoil", "BaseTrap", "GunTrap", "FlameTurret", "FogMachine", "SamSite", "AutoTurret"
        }
        ;
        private List<string> ExcludedMounts = new() {
            "beachchair", "boogieboard", "cardtable", "chair", "chippyarcademachine", "computerstation", "drumkit", "microphonestand", "piano", "secretlabchair", "slotmachine", "sofa", "xylophone"
        }
        ;
        private Coroutine reportCoroutine;
        private bool isLoaded {
            get;
            set;
        }
        private bool DebugMode {
            get;
            set;
        }
        private bool newSave {
            get;
            set;
        }
        private bool IsPurgeEnabled {
            get;
            set;
        }
        private StoredData data {
            get;
            set;
        }
        = new();
        private StringBuilder _sb {
            get;
            set;
        }
        = new();
        private Coroutine abandonedCoroutine {
            get;
            set;
        }
        private List<string> _waitingList {
            get;
            set;
        }
        = new();
        private List<UserConversion> _conversions {
            get;
            set;
        }
        = new();
        private List<AbandonedBuilding> AbandonedBuildings {
            get;
            set;
        }
        = new();
        private Dictionary<ulong, DelaySettings> PvpDelay {
            get;
            set;
        }
        = new();
        private Dictionary<ulong, List<Notification>> _notifications {
            get;
            set;
        }
        = new();
        private Dictionary<ulong, AbandonedBuilding> AbandonedReferences {
            get;
            set;
        }
        = new();
        public enum SphereColor {
            None, Blue, Cyan, Green, Magenta, Purple, Red, Yellow
        }
        public class UserConversion {
            public string userid;
            public Coroutine co;
            public HashSet<ulong> owners;
            public UserConversion(string userid, HashSet<ulong> owners, Coroutine co) {
                this.owners = owners;
                this.userid = userid;
                this.co = co;
            }
            public bool Exists(IPlayer user, HashSet<ulong> owners) {
                if (co == null) {
                    return false;
                }
                return userid == user.Id || this.owners.Overlaps(owners);
            }
        }
        public class Notification {
            public BasePlayer player;
            public string messageEx;
        }
        private class StoredData {
            [JsonProperty("Last Seen", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, int> LastSeen {
                get;
                set;
            }
            = new();
            [JsonProperty("Cooldown Between Conversion", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, DateTime> CooldownBetweenConversion {
                get;
                set;
            }
            = new();
            [JsonProperty("Cooldown Between Cancel", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, DateTime> CooldownBetweenCancel {
                get;
                set;
            }
            = new();
            [JsonProperty("Cooldown Between Events", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, DateTime> CooldownBetweenEvents {
                get;
                set;
            }
            = new();
            [JsonProperty("Activities", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ActivityInfo> Activity {
                get;
                set;
            }
            = new();
            public DateTime LastRunTime {
                get;
                set;
            }
            = DateTime.MinValue;
            public int protocol;
            public StoredData() {
            }
        }
        public class Payment {
            public Payment(BasePlayer player, double cost = 0, List<CustomCostOptions> options = null) {
                userId = player.userID;
                this.options = options;
                this.player = player;
                this.cost = cost;
            }
            public double cost {
                get;
                set;
            }
            public ulong userId {
                get;
                set;
            }
            public List<CustomCostOptions> options {
                get;
                set;
            }
            public BasePlayer player {
                get;
                set;
            }
        }
        internal class ActivityInfo {
            [JsonProperty(PropertyName = "owners", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public HashSet<ulong> owners {
                get;
                set;
            }
            = new();
            [JsonProperty(PropertyName = "permission")]
            public string perm {
                get;
                set;
            }
            = string.Empty;
            [JsonProperty(PropertyName = "total")]
            public int total {
                get;
                set;
            }
            internal ActivityInfo() {
            }
            public bool SameOwners(HashSet<ulong> owners) => owners.All(this.owners.Contains);
            internal int GetLimit(Configuration config) {
                if (string.IsNullOrEmpty(perm) || !perm.PermissionExists() || !owners.Exists(owner => owner.HasPermission(perm))) {
                    CheckPermission(config);
                }
                foreach (var purge in config.Purges) {
                    if (perm == purge.Permission) {
                        return purge.NoPurge ? 0 : purge.Limit;
                    }
                }
                return 0;
            }
            internal void CheckPermission(Configuration config) {
                var limit = int.MinValue;
                foreach (var owner in this.owners) {
                    var purge = PurgeSettings.Find(config, owner);
                    if (purge == null || string.IsNullOrEmpty(purge.Permission)) {
                        continue;
                    }
                    if (purge.Limit > limit) {
                        perm = purge.Permission;
                        limit = purge.Limit;
                    }
                    if (purge.Limit <= 0) {
                        perm = purge.Permission;
                        break;
                    }
                }
            }
        }
        public class DelaySettings {
            internal AbandonedBuilding Building {
                get;
                set;
            }
            public Timer Timer {
                get;
                set;
            }
            public float time {
                get;
                set;
            }
            public bool valid => Building != null && !Building.isDestroyed;
            public void Destroy() {
                if (Timer != null && !Timer.Destroyed) {
                    Timer.Callback();
                    Timer.Destroy();
                }
            }
        }
        internal class AbandonedBuilding : FacepunchBehaviour {
            public bool Equals(AbandonedBuilding other) {
                if (ReferenceEquals(null, other)) return false;
                if (ReferenceEquals(this, other)) return true;
                return _guid.Equals(other._guid);
            }
            public override bool Equals(object obj) {
                return obj is AbandonedBuilding other && Equals(other);
            }
            public override int GetHashCode() {
                return _guid.GetHashCode();
            }
            public static bool operator ==(AbandonedBuilding left, AbandonedBuilding right) {
                if (ReferenceEquals(left, null)) return ReferenceEquals(right, null);
                return left.Equals(right);
            }
            public static bool operator !=(AbandonedBuilding left, AbandonedBuilding right) {
                return !(left == right);
            }
            internal class EntityOwner {
                public BaseEntity Entity;
                public ulong OwnerID;
                public EntityOwner(BaseEntity entity) {
                    Entity = entity;
                    OwnerID = entity.OwnerID;
                }
            }
            internal class Raider {
                public ulong userid;
                public string username;
                public bool IsParticipant;
                public bool HasEntered;
                public bool IsAdmin;
                public float activeDuration;
                public float lastActiveTime;
                public Vector3 lastPosition;
                public BasePlayer _player;
                public BasePlayer player {
                    get {
                        if (_player == null) {
                            _player = RustCore.FindPlayerById(userid);
                        }
                        return _player;
                    }
                }
                public Raider(BasePlayer target, float duration) {
                    activeDuration = duration * 60f;
                    _player = target;
                    IsAdmin = target.IsAdmin;
                    userid = target.userID;
                    username = target.displayName;
                }
                public float PlayerActivityTimeLeft() {
                    if (activeDuration <= 0f) {
                        return float.PositiveInfinity;
                    }
                    return activeDuration - (Time.time - lastActiveTime);
                }
            }
            internal List<ulong> IsAllowed {
                get;
                set;
            }
            = new();
            internal List<ulong> Messages {
                get;
                set;
            }
            = new();
            internal HashSet<uint> buildingIDs {
                get;
                set;
            }
            = new();
            internal List<BuildingPrivlidge> privs {
                get;
                set;
            }
            = new();
            internal HashSet<ulong> owners {
                get;
                set;
            }
            = new();
            internal HashSet<ulong> others {
                get;
                set;
            }
            = new();
            internal List<BaseEntity> entities {
                get;
                set;
            }
            = new();
            internal List<SphereEntity> spheres {
                get;
                set;
            }
            = new();
            internal List<Vector3> compound {
                get;
                set;
            }
            = new();
            internal List<Vector3> foundations {
                get;
                set;
            }
            = new();
            internal Dictionary<ulong, BasePlayer> intruders {
                get;
                set;
            }
            = new();
            internal Dictionary<ulong, Raider> raiders {
                get;
                set;
            }
            = new();
            internal List<StorageContainer> containers {
                get;
                set;
            }
            = new();
            internal Dictionary<ulong, EntityOwner> EntityOwners {
                get;
                set;
            }
            = new();
            internal MapMarkerGenericRadius genericMarker = null;
            internal VendingMachineMapMarker vendingMarker = null;
            internal bool IsOwnerLocked {
                get;
                set;
            }
            internal bool IsDamaged {
                get;
                set;
            }
            internal bool DisableEventCooldown {
                get;
                set;
            }
            internal PluginTimers timer {
                get;
                set;
            }
            internal BaseCombatEntity anchor {
                get;
                set;
            }
            internal SimplePrivilege simplePriv {
                get;
                set;
            }
            internal DateTime DespawnDateTime {
                get;
                set;
            }
            internal float radius {
                get;
                set;
            }
            internal bool AutomatedEvent {
                get;
                set;
            }
            internal bool markerCreated {
                get;
                set;
            }
            internal bool isDestroyed {
                get;
                set;
            }
            internal bool IsClaimed {
                get;
                set;
            }
            internal bool CanShowDiscordEnd {
                get;
                set;
            }
            = true;
            internal bool AllowPVP {
                get;
                set;
            }
            internal bool IsExpired {
                get;
                set;
            }
            internal SphereCollider _collider {
                get;
                set;
            }
            internal Payment payment {
                get;
                set;
            }
            internal List<string> groups {
                get;
                set;
            }
            = new();
            internal GameObject go {
                get;
                set;
            }
            internal float cancelCooldownTime {
                get;
                set;
            }
            internal bool isCanceled {
                get;
                set;
            }
            internal string raiderName {
                get;
                set;
            }
            internal ulong raiderId {
                get;
                set;
            }
            internal string currentName {
                get;
                set;
            }
            internal ulong currentId {
                get;
                set;
            }
            internal string previousName {
                get;
                set;
            }
            internal ulong previousId {
                get;
                set;
            }
            internal bool canReassign {
                get;
                set;
            }
            = true;
            internal ActivityInfo activity {
                get;
                set;
            }
            internal int lootAmount {
                get;
                set;
            }
            internal Coroutine _coroutine {
                get;
                set;
            }
            internal AbandonedBases Instance {
                get;
                set;
            }
            internal bool LockBaseToFirstAttacker => AllowPVP ? config.Abandoned.LockBaseToFirstAttackerPVP : config.Abandoned.LockBaseToFirstAttackerPVE;
            internal bool EjectFromLockedBase;
            internal string GetGrid() => PositionToGrid(center);
            internal Vector3 _center {
                get;
                set;
            }
            public EventType eventType;
            private Configuration config => Instance.config;
            private StoredData data => Instance.data;
            public bool HasEventCooldown(BasePlayer player) => Instance.HasEventCooldown(player, this);
            public bool HasCooldown(BasePlayer player, string perm) => Instance.HasCooldown(player, player.userID, perm, data.CooldownBetweenEvents);
            public void Message(BasePlayer player, string key, params object[] args) => Instance.Message(player, key, args);
            public void LogToFile(string filename, string text) => Instance.LogToFile(filename, text, Instance, false, true);
            internal Vector3 center {
                get {
                    if (!anchor.IsKilled()) {
                        _center = anchor.transform.position;
                    }
                    return _center;
                }
                set {
                    _center = value;
                }
            }
            public bool IsAbandonedSleeper(BasePlayer victim) => config.PlayersCanKillAbandonedSleepers && AutomatedEvent && !victim.IsConnected && owners.Contains(victim.userID);
            public bool InRange2D(Vector3 from, float x = 0f) => AbandonedBases.InRange2D(from, center, radius + x);
            public bool InRange3D(Vector3 from, float x = 0f) => AbandonedBases.InRange3D(from, center, radius + x);
            public bool NearCompound(Vector3 from) => compound.Exists(to => AbandonedBases.InRange3D(from, to, 3f));
            public bool NearFoundation(Vector3 from, float radius = 3f) => foundations.Exists(to => AbandonedBases.InRange3D(from, to, radius));
            public bool NearFoundation(BasePlayer player, float radius = 3f) {
                if (player.HasParent() && player.GetParentEntity() is Tugboat tugboat) {
                    return Instance.GetVehiclePrivilege(tugboat.children) == simplePriv;
                }
                return NearFoundation(player.transform.position, radius);
            }
            public Raider GetRaider(BasePlayer player) {
                if (!raiders.TryGetValue(player.userID, out var ri)) {
                    raiders[player.userID] = ri = new(player, InactivePlayerActivityTime);
                }
                return ri;
            }
            public List<Raider> GetRaiders() => raiders.Values.ToList();
            public List<BasePlayer> GetIntruders() => intruders.Values.Where(x => !x.IsKilled());
            public List<ulong> GetIntruderIds() => GetIntruders().Select(x => (ulong)x.userID).ToList();
            public List<ulong> GetParticipantIds() => GetEligibleParticipants().Select(x => x.userid).ToList();
            public List<Raider> GetEligibleParticipants() => GetRaiders().Where(raider => raider switch {
                {
                    IsParticipant : false
                }
                => false, {
                    IsAdmin : true
                }
                when config.Abandoned.RemoveAdminRaiders => false, {
                    player : null
                }
                => true, {
                    player : {
                        IsFlying : true, limitNetworking : true
                    }
                }
                => false, _ => true
            }
            );
            public bool IsParticipant(ulong userid) => raiders.TryGetValue(userid, out var raider) && raider.IsParticipant;
            public void AddEntity(BaseEntity entity) {
                Instance.AbandonedReferences[entity.net.ID.Value] = this;
                if (owners.Contains(entity.OwnerID)) {
                    entities.Add(entity);
                }
            }
            public static bool AddRange(AbandonedBases m, List<BaseEntity> entities, List<StorageContainer> containers, List<Vector3> foundations, List<Vector3> floors, List<Vector3> compound, List<Vector3> walls, IPlayer user, ulong userid, bool isAutomated) {
                foreach (var e in entities.ToList()) {
                    if (e.IsKilled()) {
                        entities.Remove(e);
                        continue;
                    }
                    if (e is BuildingBlock) {
                        compound.Add(e.transform.position);
                    }
                    if (e.ShortPrefabName == "foundation" || e.ShortPrefabName == "foundation.triangle") {
                        if (m.config.Abandoned.Twig || e is BuildingBlock block && block.grade != BuildingGrade.Enum.Twigs) {
                            foundations.Add(e.transform.position);
                        }
                    }
                    else if (e.skinID == 1337424001 && e is CollectibleEntity) {
                        compound.Add(e.transform.position);
                        foundations.Add(e.transform.position);
                    }
                    else if (e.ShortPrefabName.Contains("external.high")) {
                        compound.Add(e.transform.position);
                    }
                    else if (e.ShortPrefabName == "wall" || e.ShortPrefabName == "wall.half" || e.ShortPrefabName == "wall.window") {
                        if (m.config.Abandoned.Twig || e is BuildingBlock block && block.grade != BuildingGrade.Enum.Twigs) {
                            walls.Add(e.transform.position);
                        }
                    }
                    else if (m.ID_FLOORS.Contains(e.ShortPrefabName)) {
                        floors.Add(e.transform.position);
                    }
                }
                if (foundations.Count < m.config.Abandoned.FoundationLimit || walls.Count < m.config.Abandoned.WallLimit) {
                    return m.IsPurgeEnabled && m.config.Abandoned.GetDespawnSeconds(isAutomated) <= 0f && user == null && !m.CanPurge(userid, Epoch.Current);
                    // allow when auto converting bases that are built during purge
                }
                AddContainers(entities, containers, foundations);
                return true;
            }
            public static bool AddRange(List<BaseEntity> entities, List<StorageContainer> containers, List<Vector3> compound, int minLoot, ref int loot) {
                List<BaseEntity.Slot> _checkSlots = new() {
                    BaseEntity.Slot.Lock, BaseEntity.Slot.UpperModifier, BaseEntity.Slot.MiddleModifier, BaseEntity.Slot.LowerModifier
                }
                ;
                foreach (var e in entities.ToList()) {
                    if (e.IsKilled()) {
                        entities.Remove(e);
                        continue;
                    }
                    foreach (var checkSlot in _checkSlots) {
                        var slot = e.GetSlot(checkSlot);
                        if (slot == null) continue;
                        if (entities.Contains(slot)) continue;
                        entities.Add(slot);
                    }
                    var container = e as IItemContainerEntity;
                    if (container?.inventory?.itemList != null) {
                        loot += container.inventory.itemList.Count;
                    }
                    compound.Add(e.transform.position);
                }
                AddContainers(entities, containers, compound);
                return minLoot <= 0 || loot >= minLoot;
            }
            private static void AddContainers(List<BaseEntity> entities, List<StorageContainer> containers, List<Vector3> foundations) {
                if (foundations.Count > 0) {
                    Vector3 lowestFoundation = foundations[0];
                    foreach (var foundation in foundations) {
                        if (foundation.y < lowestFoundation.y) {
                            lowestFoundation = foundation;
                        }
                    }
                    foreach (var e in entities) {
                        if (!(e is StorageContainer container)) {
                            continue;
                        }
                        if (!IsBox(e) && !(e is BuildingPrivlidge)) {
                            continue;
                        }
                        if (e == null || e.IsDestroyed || !e.isSpawned || e.transform.position.y + 3f < lowestFoundation.y) {
                            continue;
                        }
                        containers.Add(container);
                    }
                }
            }
            public void TrySetOwner(IPlayer user) {
                if (user == null || user.IsServer) {
                    return;
                }
                var player = user.Object as BasePlayer;
                if (player == null || player.IsFlying || player.limitNetworking) {
                    return;
                }
                GetRaider(player).IsParticipant = true;
                SetOwner(player.userID, player.displayName, player.userID, player.displayName);
            }
            public void ResetOwner() {
                raiders.Remove(previousId);
                IsOwnerLocked = false;
                canReassign = true;
                raiderId = 0uL;
                raiderName = null;
                SetOwner(previousId, previousName, previousId, previousName);
                UpdateMarkers();
            }
            public void TrySetOwnerLock(BasePlayer attacker, bool canEarnParticipation) {
                if (IsOwnerLocked && !CanBypass(attacker) && !IsAlly(attacker)) {
                    TryEjectFromLockedBase(attacker);
                    return;
                }
                if (IsEventCompleted && IsParticipant(attacker.userID)) {
                    return;
                }
                if (!attacker.IsHuman() || HasEventCooldown(attacker)) {
                    return;
                }
                if (canEarnParticipation) {
                    GetRaider(attacker).IsParticipant = true;
                }
                if (owners.Contains(attacker.userID) || IsAlly(attacker)) {
                    return;
                }
                if (string.IsNullOrEmpty(raiderName)) {
                    raiderName = attacker.displayName;
                    raiderId = attacker.userID;
                    GetRaider(attacker).IsParticipant = true;
                }
                if (canReassign && LockBaseToFirstAttacker) {
                    IsOwnerLocked = true;
                    canReassign = false;
                    SetOwner(attacker.userID, attacker.displayName, currentId, currentName);
                    GetRaider(attacker).IsParticipant = true;
                }
                Invoke(UpdateMarkers, 0f);
            }
            public static bool CanBypass(BasePlayer player) {
                return !player.IsHuman() || player.IsFlying || player.limitNetworking || player.HasPermission("abandonedbases.canbypass");
            }
            public bool CanDamageBuilding(BasePlayer player) {
                return owners.Contains(player.userID) || IsEventCompleted && IsParticipant(player.userID);
            }
            public bool IsOwner(BasePlayer player) {
                return owners.Contains(player.userID) || CanBypass(player) || IsAlly(player);
            }
            public void SetOwner(ulong newid, string newname, ulong currid, string currname) {
                previousName = currname;
                previousId = currid;
                currentName = newname;
                currentId = newid;
            }
            public bool EnforceCooldownBetweenEvents(BasePlayer player) {
                return !IsParticipant(player.userID) && Instance.EnforceCooldownBetweenEvents(player);
            }
            public void TryEjectFromLockedBase(BasePlayer player) {
                if (!EjectFromLockedBase || !IsOwnerLocked || owners.Contains(player.userID) && !EnforceCooldownBetweenEvents(player)) {
                    return;
                }
                if (anchor is not Tugboat && !NearFoundation(player.transform.position)) {
                    return;
                }
                if (anchor is Tugboat && !(player.GetParentEntity() is Tugboat)) {
                    return;
                }
                RemovePlayer(player);
            }
            public void RemovePlayer(BasePlayer player) {
                var m = player.GetMounted();
                if (m != null) {
                    m.DismountPlayer(player, true);
                }
                if (player.HasParent()) {
                    player.SetParent(null);
                }
                var position = GetEjectLocation(player.transform.position, 10f, center, radius);
                player.Teleport(player.IsFlying ? position.WithY(player.transform.position.y) : position);
                player.SendNetworkUpdateImmediate();
                intruders.Remove(player.userID);
            }
            public static Vector3 GetEjectLocation(Vector3 a, float distance, Vector3 target, float radius) {
                var position = ((a.XZ3D() - target.XZ3D()).normalized * (radius + distance)) + target;
                // credits ZoneManager
                float y = TerrainMeta.HighestPoint.y + 250f;
                if (Physics.Raycast(position + new Vector3(0f, y), Vector3.down, out var hit, Mathf.Infinity, 10551313, QueryTriggerInteraction.Ignore)) {
                    position.y = hit.point.y + 0.75f;
                }
                else position.y = Mathf.Max(TerrainMeta.HeightMap.GetHeight(position), TerrainMeta.WaterMap.GetHeight(position)) + 0.75f;
                return position;
            }
            public void TryMessage(BasePlayer player, string key, params object[] args) {
                if (Messages.Contains(player.userID)) return;
                ulong userid = player.userID;
                Messages.Add(userid);
                timer.Once(10f, () => Messages.Remove(userid));
                Message(player, key, args);
            }
            private readonly Guid _guid;
            public AbandonedBuilding() {
                _guid = Guid.NewGuid();
            }
            public void Setup(AbandonedBases m, IPlayer user, PluginTimers timer, List<Vector3> compound, List<Vector3> foundations, List<BaseEntity> entities, List<StorageContainer> containers, HashSet<ulong> owners, HashSet<ulong> others, Vector3 center, Payment payment, float radius, bool allowPVP, bool isAutomated) {
                Instance = m;
                TrySetOwner(user);
                AutomatedEvent = isAutomated;
                markerCreated = user == null && !config.Abandoned.AutoMarkers || user != null && !config.Abandoned.ManualMarkers;
                canReassign = currentId == 0 || string.IsNullOrEmpty(currentName);
                EjectFromLockedBase = allowPVP ? config.Abandoned.EjectLockedPVP : config.Abandoned.EjectLockedPVE;
                this.Instance.AbandonedBuildings.Add(this);
                this.AllowPVP = allowPVP;
                this.compound = compound;
                this.foundations = foundations;
                this.containers = containers;
                this.entities = entities;
                this.payment = payment;
                this.owners = owners;
                this.others = others;
                this.radius = radius;
                this.timer = timer;
                this.center = center;
                others.RemoveWhere(owners.Contains);
                Interface.Oxide.NextTick(() => {
                    if (m.CanDebug(user)) {
                        user.Message($"Conversion finalizing event...");
                    }
                    TryInvokeMethod(SetupEntities);
                    TryInvokeMethod(SetupCollider);
                    TryInvokeMethod(CompleteConvertPayment);
                    TryInvokeMethod(Announce);
                    TryInvokeMethod(InvokeDespawnInactive);
                    TryInvokeMethod(SpawnNpcs);
                    TryInvokeMethod(SetupSleepers);
                    UpdateActivity(true);
                    if (m.CanDebug(user)) {
                        user.Message($"Conversion setup complete.Event has started");
                    }
                    cancelCooldownTime = Time.time + config.Abandoned.CancelCooldown;
                }
                );
                Interface.CallHook("OnAbandonedBaseStarted", center, radius, AllowPVP, GetIntruders(), GetIntruderIds(), entities);
            }
            private void Awake() {
                go = gameObject;
            }
            private float protectorDeltaTime;
            private void Update() {
                if (EjectFromLockedBase) {
                    protectorDeltaTime += Time.deltaTime;
                    if (protectorDeltaTime >= 1f) {
                        protectorDeltaTime = -300f;
                        Protector();
                        protectorDeltaTime = 0f;
                    }
                }
            }
            private void OnDestroy() {
                if (groups.Count > 0) {
                    Plugin BotReSpawn = Interface.Oxide.RootPluginManager.GetPlugin("BotReSpawn");
                    groups.ForEach(group => BotReSpawn?.Call("RemoveGroupSpawn", group));
                }
                if (!isDestroyed) {
                    DestroyMe();
                }
            }
            private bool IsAlly(BasePlayer player) => Instance.IsAlly(player.userID, currentId);
            private void Protector() {
                if (isDestroyed) {
                    return;
                }
                if (!IsPlayerActive(currentId)) {
                    ResetOwner();
                }
                if (intruders.Count == 0) {
                    return;
                }
                using var players = intruders.ToPooledList();
                foreach (var (userid, intruder) in players) {
                    if (intruder.IsKilled()) {
                        intruders.Remove(userid);
                        continue;
                    }
                    if (IsAllowed.Contains(userid)) {
                        UpdateIntruderActivity(intruder);
                        continue;
                    }
                    if (!IsParticipant(userid) && EnforceCooldownBetweenEvents(intruder)) {
                        TryEjectFromLockedBase(intruder);
                        continue;
                    }
                    if (!IsOwnerLocked) {
                        UpdateIntruderActivity(intruder);
                        continue;
                    }
                    if (IsOwner(intruder)) {
                        UpdateIntruderActivity(intruder);
                        IsAllowed.Add(userid);
                        continue;
                    }
                    TryEjectFromLockedBase(intruder);
                }
            }
            private void OnTriggerEnter(Collider collider) {
                if (collider == null) {
                    return;
                }
                var entity = collider.ToBaseEntity();
                if (entity is BasePlayer player) {
                    if (!intruders.ContainsKey(player.userID)) {
                        intruders[player.userID] = player;
                        var raider = GetRaider(player);
                        raider.HasEntered = true;
                        if (InactivePlayerActivityTime > 0f) {
                            raider.lastActiveTime = Time.time;
                        }
                        Message(player, AllowPVP ? "OnPlayerEntered" : "OnPlayerEnteredPVE");
                        if (config.Messages.HasEventCooldown) {
                            HasEventCooldown(player);
                        }
                        Interface.CallHook("OnPlayerEnteredAbandonedBase", player, center, radius, AllowPVP, GetIntruders(), GetIntruderIds(), entities);
                        OnPlayerEnter(player);
                        UpdateTime(player, true);
                    }
                }
                else if (entity is BaseMountable m) {
                    GetMountedPlayers(m).ForEach(player => {
                        if (!intruders.ContainsKey(player.userID)) {
                            intruders[player.userID] = player;
                            var raider = GetRaider(player);
                            raider.HasEntered = true;
                            if (LockBaseToFirstAttacker) {
                                raider.lastActiveTime = Time.time;
                            }
                            Message(player, AllowPVP ? "OnPlayerEntered" : "OnPlayerEnteredPVE");
                            Interface.CallHook("OnPlayerEnteredAbandonedBase", player, center, radius, AllowPVP, GetIntruders(), GetIntruderIds(), entities);
                            UpdateTime(player, true);
                        }
                    }
                    );
                }
            }
            private void OnTriggerExit(Collider collider) {
                if (collider == null) {
                    return;
                }
                var entity = collider.ToBaseEntity();
                if (entity is BasePlayer player) {
                    OnPlayerExit(player, player.IsDead());
                }
                else if (entity is BaseMountable m) {
                    GetMountedPlayers(m).ForEach(player => OnPlayerExit(player, player.IsDead()));
                }
            }
            public void DestroyMe() {
                isDestroyed = true;
                TryInvokeMethod(CancelEntitySetup);
                TryInvokeMethod(KillMarkers);
                TryInvokeMethod(DestroySpheres);
                TryInvokeMethod(RewardPlayers);
                TryInvokeMethod(PowerDownAutoTurrets);
                TryInvokeMethod(RestoreEntityOwners);
                TryInvokeMethod(RemoveReferences);
                TryInvokeMethod(CancelInvokes);
                if (eventType == EventType.Base) {
                    Destroy(go);
                }
                Destroy(this);
            }
            public void OnClaimed(BasePlayer player, string hook) {
                GetParticipants(out var participants, out var participantIds);
                Interface.CallHook(hook, player, center, radius, AllowPVP, participants, participantIds, entities);
            }
            private void SetupSleepers() {
                if (!config.MoveInventory) {
                    return;
                }
                var boxes = containers.Where(x => !x.IsKilled() && IsBox(x) && !x.inventory.IsFull());
                if (boxes.Count == 0) {
                    return;
                }
                foreach (var entity in entities) {
                    if (entity == null) continue;
                    var target = entity as BasePlayer;
                    if (target.IsKilled()) continue;
                    if (!target.IsSleeping() || target.IsConnected || target.inventory == null) continue;
                    using var items = target.GetPlayerItems();
                    while (items.Count > 0 && boxes.Count > 0) {
                        var box = boxes.GetRandom();
                        if (box.inventory.IsFull()) {
                            boxes.Remove(box);
                            continue;
                        }
                        Item item = items[0];
                        items.Remove(item);
                        if (item == null) {
                            continue;
                        }
                        if (config.MoveInventoryBlacklist.Contains(item.info.shortname) || !item.MoveToContainer(box.inventory)) {
                            item.RemoveFromContainer();
                            item.Remove(0f);
                        }
                    }
                }
            }
            public void RewardPlayers() {
                if (IsClaimed) {
                    return;
                }
                var raiders = GetEligibleParticipants();
                foreach (var raider in raiders) {
                    if (!isCanceled) {
                        Instance.GiveRewards(raider.player, raider.userid, raiders.Count, eventType);
                    }
                    if (!DisableEventCooldown) {
                        SetEventCooldown(raider.userid);
                    }
                }
                if (isCanceled || Instance.IsUnloading) {
                    return;
                }
                var activeId = raiderId == 0uL ? currentId : raiderId;
                var activeName = string.IsNullOrEmpty(raiderName) ? currentName : raiderName;
                var players = string.Join(", ", raiders.Select(x => x.username));
                string text;
                if (raiders.Count == 0) text = Instance.GetMessage("Output Uncontested", null).Replace("{activeName}", activeName ?? Instance.GetUserName(activeId) ?? "UNKNOWN").Replace("{activeId}", activeId.ToString()).Replace("{center}", center.ToString()).Replace("{grid}", GetGrid()).Replace("{previousName}", previousName ?? Instance.GetUserName(previousId) ?? "UNKNOWN").Replace("{previousId}", previousId.ToString());
                else text = Instance.GetMessage("Output Ended", null).Replace("{activeName}", activeName ?? Instance.GetUserName(activeId) ?? "UNKNOWN").Replace("{activeId}", activeId.ToString()).Replace("{players}", players).Replace("{center}", center.ToString()).Replace("{grid}", GetGrid()).Replace("{previousName}", previousName ?? Instance.GetUserName(previousId) ?? "UNKNOWN").Replace("{previousId}", previousId.ToString());
                if (CanShowDiscordEnd && config.Discord.End) {
                    Instance.SendDiscordMessage(center, text);
                }
                if (config.UseLogFile && activeName != previousName) {
                    LogToFile("sar", text);
                }
                Puts(text);
            }
            private void RestoreEntityOwners() {
                UpdateExpirationStatus();
                if (IsExpired || IsClaimed || EntityOwners.Count == 0) {
                    return;
                }
                foreach (var (userid, eo) in EntityOwners.ToList()) {
                    if (eo.Entity.IsKilled()) continue;
                    eo.Entity.OwnerID = eo.OwnerID;
                }
            }
            private void RemoveReferences() => Instance.RemoveReferences(this, entities);
            private void CancelInvokes() {
                try {
                    CancelInvoke(DestroyAll);
                }
                catch {
                }
            }
            public void KillMarkers() {
                vendingMarker.SafelyKill();
                genericMarker.SafelyKill();
            }
            public void DestroySpheres() {
                spheres.ForEach(SafelyKill);
            }
            public void KillCollider() {
                if (_collider != null) {
                    DestroyImmediate(_collider);
                }
            }
            private void CompleteConvertPayment() => CompletePayment(payment, false);
            public void CompleteCancelPayment(Payment payment) => CompletePayment(payment, true);
            public void SetConversionCooldown(ulong userid) {
                if (!Instance.IgnoreConversionCooldowns() && config.Abandoned.CooldownBetweenConversion > 0 && !userid.HasPermission("abandonedbases.convert.nocooldown")) {
                    data.CooldownBetweenConversion[userid] = DateTime.Now.AddSeconds(config.Abandoned.CooldownBetweenConversion);
                }
            }
            public void SetCancelCooldown(ulong userid) {
                if (!Instance.IgnoreCancelCooldowns() && config.Abandoned.CooldownBetweenCancel > 0 && !userid.HasPermission("abandonedbases.convert.cancel.nocooldown")) {
                    data.CooldownBetweenCancel[userid] = DateTime.Now.AddSeconds(config.Abandoned.CooldownBetweenCancel);
                }
            }
            public void SetEventCooldown(ulong userid) {
                if (!Instance.IgnoreEventCooldowns() && config.Abandoned.CooldownBetweenEvents > 0 && !userid.HasPermission("abandonedbases.noeventcooldown")) {
                    data.CooldownBetweenEvents[userid] = DateTime.Now.AddSeconds(config.Abandoned.CooldownBetweenEvents);
                }
            }
            public void SetEventCooldowns() {
                if (!DisableEventCooldown) {
                    GetEligibleParticipants().ForEach(raider => SetEventCooldown(raider.userid));
                }
            }
            private void CompletePayment(Payment payment, bool cancel) {
             
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху