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

FREE Arena : 0.1.133 0.1.133

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using UnityEngine;
using System.Linq;
using Newtonsoft.Json;
using Rust;
using Network;
namespace Oxide.Plugins {
    [Info("Arena", "k1lly0u", "0.1.133")]
    [Description("A multi arena plugin capable of running many instances of various events at one time")]
    class Arena : RustPlugin {
#region Fields
        [PluginReference]
        Plugin Spawns, ZoneManager, Kits, ImageLibrary, LustyMap, RotatingPickups, Economics, ServerRewards, NoEscape;
        public static ArenaUI UI;
        public static ArenaStatistics Statistics;
        public static ArenaEvents Events;
        public static ArenaLootSpawns Loot;
        private ArenaData arenaData;
        private RestoreData restoreData;
        private DynamicConfigFile eventData, restorationData;
        private static Arena ins;
        private Dictionary<ulong, Timer> killTimers;
        public Dictionary<ulong, Timer> respawnTimers;
        public Dictionary<string, EventManager> events;
        public Dictionary<string, List<AdditionalParamData>> additionalParameters;
        private Hash<ulong, Action> pendingTP = new Hash<ulong, Action>();
        private Hash<ulong, double> cooldownTP = new Hash<ulong, double>();
        public List<string> eventTypes;
        public bool isInitialized;
        public static bool isUnloading;
#endregion
#region Oxide Hooks
        private void Loaded() {
            eventData = Interface.Oxide.DataFileSystem.GetFile("Arena/event_data");
            restorationData = Interface.Oxide.DataFileSystem.GetFile("Arena/restoration_data");
            killTimers = new Dictionary<ulong, Timer>();
            respawnTimers = new Dictionary<ulong, Timer>();
            events = new Dictionary<string, EventManager>();
            additionalParameters = new Dictionary<string, List<AdditionalParamData>> ();
            eventTypes = new List<string>();
            permission.RegisterPermission("arena.admin", this);
            lang.RegisterMessages(Messages, this);
            isUnloading = false;
        }
        private void OnServerInitialized() {
            ins = this;
            LoadData();
            cmd.AddChatCommand(configData.ServerSettings.ChatCommand, this, cmdEventMenu);
            if (!configData.EventSettings.Continual) {
                Unsubscribe(nameof(OnPlayerInput));
                Unsubscribe(nameof(OnPlayerTick));
            }
            if (!configData.EventSettings.AddToTeams) {
                Unsubscribe(nameof(OnTeamDisband));
                Unsubscribe(nameof(OnTeamLeave));
                Unsubscribe(nameof(OnTeamInvite));
            }
            timer.In(2, InitializePluginReferences);
        }
        private void Unload() {
            isUnloading = true;
            SaveRestoreData();
            EventManager[] eventGames = UnityEngine.Object.FindObjectsOfType<EventManager>();
            if (eventGames != null) {
                foreach (EventManager eventGame in eventGames) UnityEngine.Object.Destroy(eventGame);
            }
            EventPlayer[] eventPlayers = UnityEngine.Object.FindObjectsOfType<EventPlayer>();
            if (eventPlayers != null) {
                foreach (EventPlayer eventPlayer in eventPlayers) {
                    UnityEngine.Object.DestroyImmediate(eventPlayer);
                }
            }
            events.Clear();
            ins = null;
            Events = null;
            Statistics = null;
            UI = null;
            Loot = null;
        }
        private void OnServerSave() => SaveRestoreData();
        private void OnPlayerConnected(BasePlayer player) {
            if (!isInitialized || player == null) return;
            if (player.IsDead() || player.IsSleeping() || player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot)) {
                timer.Once(1.5f, () => OnPlayerConnected(player));
                return;
            }
            UnlockInventory(player);
            if (configData.ServerSettings.EventOnly) {
                EventPlayer eventPlayer = GetUser(player);
                if (eventPlayer != null) UnityEngine.Object.DestroyImmediate(eventPlayer);
                if (!string.IsNullOrEmpty(configData.LobbySettings.LobbyZoneID)) {
                    if (!(bool)ZoneManager.Call("isPlayerInZone", configData.LobbySettings.LobbyZoneID, player)) SendToWaiting(player);
                }
                if (configData.ServerSettings.MenuOnJoin && events.Count > 0) UI.OpenMainMenu(player, events.First().Value.config.eventType);
            }
            else {
                if (restoreData.HasRestoreData(player.userID)) restoreData.RestorePlayer(player);
            }
        }
        private void OnPlayerRespawned(BasePlayer player) {
            if (configData.ServerSettings.EventOnly) {
                EventPlayer eventPlayer = GetUser(player);
                if (eventPlayer != null && eventPlayer.hasEnteredEvent) {
                    EventManager manager = GetEvent(eventPlayer.currentEvent);
                    if (manager != null && manager.eventPlayers.Contains(eventPlayer)) manager.LeaveEvent(eventPlayer);
                    UnityEngine.Object.DestroyImmediate(eventPlayer);
                }
                UnlockInventory(player);
                SendToWaiting(player);
            }
        }
        private void OnPlayerDisconnected(BasePlayer player) {
            EventPlayer eventPlayer = GetUser(player);
            if (eventPlayer != null) {
                EventManager manager = GetEvent(eventPlayer.currentEvent);
                if (manager != null) manager.LeaveEvent(eventPlayer);
                UnityEngine.Object.Destroy(eventPlayer);
                UnlockInventory(player);
                UI.DestroyAllUI(player);
                if (player.IsAlive()) player.DieInstantly();
            }
        }
        private void OnPlayerInput(BasePlayer player, InputState input) {
            if (player == null || input == null) return;
            EventPlayer eventPlayer = player.GetComponent<EventPlayer>();
            if (eventPlayer != null) {
                if (eventPlayer.player.IsSpectating()) {
                    if (input.WasJustPressed(BUTTON.JUMP)) eventPlayer.UpdateSpectateTarget(1);
                    else if (input.WasJustPressed(BUTTON.DUCK)) eventPlayer.UpdateSpectateTarget(-1);
                }
            }
        }
        private object OnPlayerTick(BasePlayer player, PlayerTick msg, bool wasPlayerStalled) {
            EventPlayer eventPlayer = player.GetComponent<EventPlayer>();
            if (eventPlayer != null) {
                if (eventPlayer.player.IsSpectating()) return false;
            }
            return null;
        }
        private void OnEntityTakeDamage(BaseEntity entity, HitInfo info) {
            if (isInitialized) {
                if (entity == null || info == null) return;
                BasePlayer player = entity.ToPlayer();
                if (player != null) {
                    EventPlayer eventPlayer = GetUser(player);
                    if (eventPlayer != null) {
                        if (!eventPlayer.hasEnteredEvent) return;
                        EventManager manager = GetEvent(eventPlayer.currentEvent);
                        if (manager == null) return;
                        manager.OnPlayerTakeDamage(eventPlayer, info);
                    }
                }
                else {
                    EventPlayer attacker = GetUser(info.InitiatorPlayer);
                    if (attacker != null) {
                        if (!attacker.hasEnteredEvent) return;
                        EventManager manager = GetEvent(attacker.currentEvent);
                        if (manager != null) {
                            manager.CanPlayerDealDamage(attacker, entity, info);
                            return;
                        }
                        NullifyDamage(info);
                    }
                }
            }
        }
        private object CanBeWounded(BasePlayer player, HitInfo info) {
            if (player != null) {
                EventPlayer eventPlayer = GetUser(player);
                if (eventPlayer != null) {
                    if (!eventPlayer.hasEnteredEvent) return null;
                    EventManager manager = GetEvent(eventPlayer.currentEvent);
                    if (manager != null) return false;
                }
            }
            return null;
        }
        private object OnPlayerDeath(BasePlayer player, HitInfo info) {
            if (player != null) {
                EventPlayer eventPlayer = GetUser(player);
                if (eventPlayer != null) {
                    if (!eventPlayer.hasEnteredEvent) return null;
                    EventManager manager = GetEvent(eventPlayer.currentEvent);
                    if (manager != null) {
                        if (!eventPlayer.isDead) manager.OnPlayerDeath(eventPlayer, info);
                        return false;
                    }
                }
            }
            return null;
        }
        private void OnRunPlayerMetabolism(PlayerMetabolism metabolism, BaseCombatEntity entity, float delta) {
            if (isInitialized) {
                EventPlayer eventPlayer = GetUser(entity?.ToPlayer());
                if (eventPlayer == null) return;
                if (eventPlayer.isDead) {
                    metabolism.bleeding.value = 0;
                    metabolism.poison.value = 0;
                    metabolism.radiation_level.value = 0;
                    metabolism.radiation_poison.value = 0;
                    metabolism.wetness.value = 0;
                }
            }
        }
        private void OnEntitySpawned(BaseNetworkable entity) {
            if (isInitialized) {
                if (entity == null) return;
                if (configData.ServerSettings.NoHelicopters && entity is BaseHelicopter) {
                    NextTick(() => {
                        if (entity != null) (entity as BaseHelicopter).DieInstantly();
                        return;
                    }
                    );
                }
                if (configData.ServerSettings.NoAirdrops && entity is CargoPlane) {
                    NextTick(() => {
                        if (entity != null) entity.Kill();
                        return;
                    }
                    );
                }
                if (configData.ServerSettings.NoAnimals && entity is BaseNpc) {
                    NextTick(() => {
                        if (entity != null) (entity as BaseNpc).DieInstantly();
                        return;
                    }
                    );
                }
            }
        }
        private object OnCreateWorldProjectile(HitInfo info, Item item) {
            if (isInitialized) {
                if (info == null) return null;
                if (info.InitiatorPlayer != null) {
                    EventPlayer eventPlayer = GetUser(info.InitiatorPlayer);
                    if (eventPlayer != null) {
                        if (!eventPlayer.hasEnteredEvent) return null;
                        return false;
                    }
                }
                if (info.HitEntity?.ToPlayer() != null) {
                    EventPlayer eventPlayer = GetUser(info.HitEntity.ToPlayer());
                    if (eventPlayer != null) {
                        if (!eventPlayer.hasEnteredEvent) return null;
                        return false;
                    }
                }
            }
            return null;
        }
        private object CanDropActiveItem(BasePlayer player) {
            EventPlayer eventPlayer = player.GetComponent<EventPlayer>();
            if (eventPlayer != null) {
                if (!eventPlayer.hasEnteredEvent) return null;
                return false;
            }
            return null;
        }
        private object CanLootEntity(BasePlayer player, StorageContainer container) => CanPlayerLoot(player);
        private object CanLootEntity(BasePlayer player, DroppedItemContainer container) => CanPlayerLoot(player);
        private object CanLootEntity(BasePlayer player, LootableCorpse container) => CanPlayerLoot(player);
        private object CanLootEntity(BasePlayer player, ResourceContainer container) => CanPlayerLoot(player);
        private object CanPlayerLoot(BasePlayer player) {
            if (player != null) {
                EventPlayer eventPlayer = GetUser(player);
                if (eventPlayer != null) {
                    if (!eventPlayer.hasEnteredEvent) return null;
                    EventManager manager = GetEvent(eventPlayer.currentEvent);
                    if (manager != null && manager.status != EventStatus.Started) {
                        player.ChatMessage(msg("nolooting", player.userID));
                        return false;
                    }
                }
            }
            return null;
        }
        private void OnEntityBuilt(Planner planner, GameObject gObject) {
            BasePlayer player = planner?.GetOwnerPlayer();
            if (player == null) return;
            BaseEntity entity = gObject?.ToBaseEntity();
            if (entity == null) return;
            if (entity is BaseCombatEntity) {
                EventPlayer eventPlayer = GetUser(player);
                if (eventPlayer == null) return;
                EventManager manager = GetEvent(eventPlayer.currentEvent);
                if (manager == null) return;
                manager.OnEntityDeployed(entity as BaseCombatEntity);
            }
        }
        private void OnItemDeployed(Deployer deployer, BaseEntity deployedEntity) {
            BasePlayer player = deployer.GetOwnerPlayer();
            if (player == null) return;
            if (deployedEntity is BaseCombatEntity) {
                EventPlayer eventPlayer = GetUser(player);
                if (eventPlayer == null) return;
                EventManager manager = GetEvent(eventPlayer.currentEvent);
                if (manager == null) return;
                manager.OnEntityDeployed(deployedEntity as BaseCombatEntity);
            }
        }
        private object CanNetworkTo(BasePlayer player, BasePlayer target) {
            if (isInitialized) {
                EventPlayer eventPlayer = GetUser(player);
                if (eventPlayer != null && eventPlayer.isDead) return false;
            }
            return null;
        }
        //private object CanNetworkTo(HeldEntity entity, BasePlayer target)
        //{
        //    if (isInitialized)
        //    {
        //        EventPlayer eventPlayer = GetUser(entity?.GetOwnerPlayer());
        //        if (eventPlayer != null && eventPlayer.isDead)
        //            return false;
        //    }
        //    return null;
        //}
        private object OnPlayerChat(BasePlayer player, string message, ConVar.Chat.ChatChannel channel) {
            if (!configData.ServerSettings.UseChat) return null;
            if (player != null) {
                if (player.IsAdmin || permission.UserHasPermission(player.UserIDString, "arena.admin")) return null;
                EventPlayer eventPlayer = GetUser(player);
                if (eventPlayer != null && eventPlayer.hasEnteredEvent) GetEvent(eventPlayer.currentEvent)?.ChatToPlayers(eventPlayer.player, message);
                else {
                    foreach (BasePlayer otherPlayer in BasePlayer.activePlayerList.Where(x => GetUser(x) == null)) otherPlayer.SendConsoleCommand("chat.add", new object[] {
                        0, player.UserIDString, $"<color={(player.IsAdmin ? "#aaff55" : player.IsDeveloper ? "#fa5" : "#55AAFF")}>{player.displayName}</color>: {message}"
                    }
                    );
                }
                return false;
            }
            return false;
        }
        private object OnPlayerCommand(BasePlayer player, string command, string[] args) {
            EventPlayer eventPlayer = GetUser(player);
            if (player == null || player.IsAdmin || eventPlayer == null || !eventPlayer.hasEnteredEvent) return null;
            if (configData.EventSettings.CommandBlacklist.Any(x => command.ToLower().Equals(x.ToLower()))) {
                SendReply(player, msg("blacklistcmd", player.userID));
                return false;
            }
            return null;
        }
        private object OnServerCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            EventPlayer eventPlayer = GetUser(player);
            if (player == null || player.IsAdmin || eventPlayer == null || !eventPlayer.hasEnteredEvent || arg.Args == null) return null;
            if (configData.EventSettings.CommandBlacklist.Any(x => arg.cmd.FullName.ToLower().Equals(x.ToLower()))) {
                SendReply(player, msg("blacklistcmd", player.userID));
                return false;
            }
            return null;
        }
        private object OnTeamLeave(RelationshipManager.PlayerTeam playerTeam, BasePlayer player) {
            EventPlayer eventPlayer = GetUser(player);
            if (eventPlayer == null) return null;
            EventManager eventManager = GetEvent(eventPlayer.currentEvent);
            if (Events.IsTeamEvent(eventManager.config.eventType)) {
                return true;
            }
            return null;
        }
        private object OnTeamDisband(RelationshipManager.PlayerTeam playerTeam) {
            foreach(KeyValuePair<string, EventManager> kvp in events) {
                if (playerTeam == kvp.Value.playerTeamA || playerTeam == kvp.Value.playerTeamB) return true;
            }
            return null;
        }
        private object OnTeamInvite(BasePlayer player, BasePlayer other) {
            EventPlayer eventPlayer = GetUser(player);
            if (eventPlayer != null) return true;
            return null;
        }
        private object OnTeamCreate(BasePlayer player) {
            EventPlayer eventPlayer = GetUser(player);
            if (eventPlayer != null) return true;
            return null;
        }
#endregion
#region Deathnotes
        private object OnDeathNotice(Dictionary<string, object> data, string message) {
            object obj;
            if (data.TryGetValue("VictimEntity", out obj)) {
                BaseCombatEntity victim = obj as BaseCombatEntity;
                if (victim != null) {
                    if (victim.GetComponent<EventPlayer>() || victim.GetComponent<ArenaEvents.NPCSurvival.NPCController>()) return false;
                }
            }
            return null;
        }
#endregion
#region Classes and Components
        public enum EventStatus {
            Pending, Started, Finished
        }
        public enum ScoreType {
            Kills, Deaths, KD
        }
        public enum Team {
            A, B, None
        }
        public class EventManager : MonoBehaviour {
#region Fields
            public string eventName;
            public ArenaData.EventConfig config;
            public EventStatus status;
            internal GameTimer gameTimer;
            internal SpawnManager spawnManagerA;
            internal SpawnManager spawnManagerB;
            private CuiElementContainer scoreContainer = null;
            public List<ScoreEntry> scoreData;
            public List<EventPlayer> eventPlayers = new List<EventPlayer>();
            internal RelationshipManager.PlayerTeam playerTeamA;
            internal RelationshipManager.PlayerTeam playerTeamB;
            internal bool showKillFeed;
            public bool showGameTimers;
            public bool godEnabled;
            public bool isContinual;
            public bool deathKick;
            private bool dropAmmo;
            private bool dropWeapon;
            private bool dropBackpack;
            public string currentKit;
            private double timeRemaining;
            private Dictionary<string, ArenaData.EventConfig> closedEvents = new Dictionary<string, ArenaData.EventConfig>();
            private List<BaseCombatEntity> deployedObjects = new List<BaseCombatEntity>();
#endregion
#region Component Management
            private void Awake() {
                dropAmmo = ins.configData.EventSettings.DropAmmo;
                dropWeapon = ins.configData.EventSettings.DropWeapon;
                dropBackpack = ins.configData.EventSettings.DropBackpack;
                showKillFeed = ins.configData.EventSettings.UseKillFeed;
                showGameTimers = ins.configData.GameTimers.ShowGameTimer;
                isContinual = ins.configData.EventSettings.Continual;
                deathKick = ins.configData.EventSettings.DeathKick;
                enabled = false;
                gameTimer = gameObject.AddComponent<GameTimer>();
                gameTimer.Register(this, TimerExpired, showGameTimers);
            }
            public virtual void OnDestroy() {
                RespawnAllPlayers();
                EjectAllPlayers();
                if (gameTimer != null) Destroy(gameTimer);
            }
            public virtual void InitializeEvent(string eventName, ArenaData.EventConfig config) {
                this.eventName = eventName;
                this.config = config;
                spawnManagerA = new SpawnManager();
                spawnManagerA.SetSpawnFile(config.eventName, config.teamA.spawnfile);
                if (Events.IsTeamEvent(config.eventType)) {
                    spawnManagerB = new SpawnManager();
                    spawnManagerB.SetSpawnFile(config.eventName, config.teamB.spawnfile);
                }
                if (config.eventKits.Count > 0) currentKit = config.eventKits[0];
                godEnabled = true;
                status = EventStatus.Finished;
                InvokeHandler.Invoke(this, WaitMessage, 7f);
                if (Events.IsTeamEvent(config.eventType) && ins.configData.EventSettings.AddToTeams) {
                    playerTeamA = RelationshipManager.Instance.CreateTeam();
                    playerTeamB = RelationshipManager.Instance.CreateTeam();
                }
            }
            public void CheckValidTeams() {
                if (playerTeamA == null) playerTeamA = RelationshipManager.Instance.CreateTeam();
                if (playerTeamB == null) playerTeamB = RelationshipManager.Instance.CreateTeam();
            }
#endregion
#region Event Management
            public void TimerExpired() {
                switch (status) {
                    case EventStatus.Pending : StartMatch();
                    return;
                    case EventStatus.Started : EndMatch();
                    return;
                    case EventStatus.Finished : Prestart();
                    return;
                }
            }
            public virtual void Prestart() {
                if (!HasValidPlayers()) return;
                InvokeHandler.CancelInvoke(this, WaitMessage);
                DestroyAllPopups();
                scoreData = new List<ScoreEntry>();
                status = EventStatus.Pending;
                gameTimer.StartTimer(ins.configData.GameTimers.MatchPrestart[config.eventType], msg("roundstarts"));
                if (!string.IsNullOrEmpty(config.zoneId)) Loot.OnEventStarted(config.zoneId);
                foreach (EventPlayer eventPlayer in eventPlayers) SpawnPlayer(eventPlayer, false, true);
            }
            public virtual void StartMatch() {
                if (!HasValidPlayers()) return;
                status = EventStatus.Started;
                godEnabled = false;
                if (config.timeLimit > 0) gameTimer.StartTimer(config.timeLimit * 60);
                foreach (EventPlayer eventPlayer in eventPlayers) {
                    UI.DestroyUI(eventPlayer.player, ArenaUI.UIPanel.Menu);
                    eventPlayer.ResetStats();
                    SpawnPlayer(eventPlayer);
                }
                UpdateScoreboard();
            }
            public virtual void EndMatch() {
                gameTimer.StopTimer();
                if (!string.IsNullOrEmpty(config.zoneId)) Loot.OnEventFinished(config.zoneId);
                status = EventStatus.Finished;
                godEnabled = true;
                RespawnAllPlayers();
                if (!isUnloading) {
                    ins.NextTick(() => {
                        CleanupEntities();
                        foreach (EventPlayer eventPlayer in eventPlayers) {
                            if (eventPlayer.player == null) continue;
                            Statistics.OnGamePlayed(eventPlayer.player.userID, config);
                            StripInventory(eventPlayer.player);
                            if (eventPlayer.isOOB) {
                                eventPlayer.isOOB = false;
                                if (ins.killTimers.ContainsKey(eventPlayer.player.userID)) {
                                    ins.killTimers[eventPlayer.player.userID].Destroy();
                                    ins.killTimers.Remove(eventPlayer.player.userID);
                                }
                            }
                            UI.DestroyUI(eventPlayer.player, ArenaUI.UIPanel.Menu);
                            DisplayFinalScoreboard();
                        }
                        Statistics.OnGameFinished(config.eventType, config.eventName);
                        if (isContinual) {
                            SwitchTeams();
                            InvokeHandler.Invoke(this, ResetMatch, 5f);
                        }
                        else InvokeHandler.Invoke(this, EjectAllPlayers, 5f);
                    }
                    );
                }
            }
            private void SwitchTeams() {
                if (!Events.IsTeamEvent(config.eventType) || !config.switchTeamOnRepeat) return;
                ArenaData.EventConfig.TeamEntry teamA = config.teamA;
                ArenaData.EventConfig.TeamEntry teamB = config.teamB;
                config.teamA = teamB;
                config.teamB = teamA;
                spawnManagerA.SetSpawnFile(config.eventName, config.teamA.spawnfile);
                spawnManagerB.SetSpawnFile(config.eventName, config.teamB.spawnfile);
            }
            private void ResetMatch() {
                foreach (EventPlayer eventPlayer in eventPlayers) {
                    if (eventPlayer.player.IsSpectating()) eventPlayer.FinishSpectating();
                    StripInventory(eventPlayer.player);
                    eventPlayer.ResetStats();
                }
                if (eventPlayers.Count >= config.playersToStart) {
                    BroadcastToPlayers("playersreached", new string[] {
                        ins.configData.GameTimers.MatchPrestart[config.eventType].ToString()
                    }
                    , true);
                    Prestart();
                }
                else InvokeHandler.Invoke(this, WaitMessage, 5f);
            }
            public void EjectAllPlayers() {
                if (eventPlayers.Count > 0) {
                    for (int i = eventPlayers.Count - 1; i >= 0; i--) LeaveEvent(eventPlayers[i]);
                    eventPlayers.Clear();
                }
            }
            private void RespawnAllPlayers() {
                foreach(EventPlayer eventPlayer in eventPlayers) {
                    if (eventPlayer.player.IsSpectating()) eventPlayer.FinishSpectating();
                    if (eventPlayer.isDead) ins.RespawnPlayer(eventPlayer.player);
                }
            }
            private void CheckPlayers() {
                if (eventPlayers.Count < config.minimumPlayers) {
                    switch (status) {
                        case EventStatus.Finished : case EventStatus.Pending : gameTimer.StopTimer();
                        status = EventStatus.Finished;
                        BroadcastToPlayers("notenoughtostart", null, true);
                        InvokeHandler.Invoke(this, WaitMessage, 7f);
                        break;
                        case EventStatus.Started : gameTimer.StopTimer();
                        BroadcastToPlayers("notenoughtocontinue", null, true);
                        EndMatch();
                        break;
                    }
                }
            }
            private bool HasValidPlayers() {
                for (int i = eventPlayers.Count - 1; i >= 0; i--) {
                    EventPlayer eventPlayer = eventPlayers[i];
                    if (eventPlayer == null || eventPlayer.player == null || !eventPlayer.player.IsConnected) {
                        eventPlayers.Remove(eventPlayer);
                        Destroy(eventPlayer);
                    }
                }
                if (eventPlayers.Count == 0 || eventPlayers.Count < config.playersToStart) {
                    status = EventStatus.Finished;
                    gameTimer.StopTimer();
                    BroadcastToPlayers("notenoughtostart", null, true);
                    InvokeHandler.Invoke(this, WaitMessage, 7f);
                    return false;
                }
                return true;
            }
            private void WaitMessage() {
                if (status == EventStatus.Finished) {
                    BroadcastToPlayers("notenoughtostart", null, true);
                    InvokeHandler.Invoke(this, WaitMessage, 7f);
                }
            }
            public void DisableMatchingZones() {
                closedEvents.Clear();
                KeyValuePair<string, EventManager>[] events = ins.events.Where(x => (!string.IsNullOrEmpty(x.Value.config.zoneId) && x.Value.config.zoneId == config.zoneId && x.Value != this)).ToArray();
                if (events.Length > 0) {
                    for (int i = events.Length - 1; i >= 0; i--) {
                        KeyValuePair<string, EventManager> eventGame = events[i];
                        closedEvents.Add(eventGame.Key, eventGame.Value.config);
                        eventGame.Value.EndMatch();
                        eventGame.Value.EjectAllPlayers();
                        Destroy(eventGame.Value);
                        ins.events.Remove(eventGame.Key);
                    }
                }
            }
            public void EnableMatchingZones() {
                if (isUnloading) return;
                foreach(KeyValuePair<string, ArenaData.EventConfig> eventGame in closedEvents) ins.InitializeEvent(eventGame.Key, eventGame.Value);
                closedEvents.Clear();
            }
#endregion
#region Player Management
            public virtual bool CanJoinEvent() {
                if (eventPlayers.Count >= config.maximumPlayers) return false;
                return true;
            }
            public virtual void JoinEvent(EventPlayer eventPlayer, Team team) {
                if (!string.IsNullOrEmpty(config.zoneId)) {
                    ins.ZoneManager?.Call("AddPlayerToZoneWhitelist", config.zoneId, eventPlayer.player);
                    if (ins.configData.EventSettings.DisableUsedZones && eventPlayers.Count == 1) DisableMatchingZones();
                }
                if (ins.configData.EventSettings.BroadcastJoiners) {
                    BroadcastToAll("joineventglobal", new string[] {
                        eventPlayer.player.displayName, config.eventName
                    }
                    );
                }
            }
            public virtual void LeaveEvent(EventPlayer eventPlayer) {
                if (eventPlayers.Contains(eventPlayer)) {
                    if (eventPlayer.player != null) {
                        if (eventPlayer.player.IsSpectating()) eventPlayer.FinishSpectating();
                        if (eventPlayer.player.IsSleeping()) eventPlayer.player.Die();
                        else {
                            StripInventory(eventPlayer.player);
                            //eventPlayer.player.inventory.Strip();
                            if (!ins.configData.ServerSettings.EventOnly) eventPlayer.RestorePlayer();
                            else ins.SendToWaiting(eventPlayer.player);
                        }
                    }
                    if (!string.IsNullOrEmpty(config.zoneId)) ins.ZoneManager?.Call("RemovePlayerFromZoneWhitelist", config.zoneId, eventPlayer.player);
                    eventPlayers.Remove(eventPlayer);
                    DestroyImmediate(eventPlayer);
                    if (status != EventStatus.Finished) CheckPlayers();
                    if (ins.configData.EventSettings.DisableUsedZones && eventPlayers.Count == 0) EnableMatchingZones();
                }
            }
            public void SpawnPlayer(EventPlayer eventPlayer, bool giveKit = true, bool sleep = false) {
                BasePlayer player = eventPlayer.player;
                if (player == null) return;
                if (!ins.configData.EventSettings.SendToArenaOnJoin) eventPlayer.SetPlayer();
                if (!eventPlayer.hasEnteredEvent) {
                    if (Events.IsTeamEvent(config.eventType) && ins.configData.EventSettings.AddToTeams) {
                        switch (eventPlayer.team) {
                            case Team.A : playerTeamA.AddPlayer(eventPlayer.player);
                            break;
                            case Team.B : playerTeamB.AddPlayer(eventPlayer.player);
                            break;
                        }
                    }
                    eventPlayer.hasEnteredEvent = true;
                }
                StripInventory(player);
                ins.ResetMetabolism(player);
                Vector3 spawnPoint = eventPlayer.team == Team.A ? spawnManagerA.GetSpawnPoint() : spawnManagerB.GetSpawnPoint();
                ins.MovePosition(player, spawnPoint, sleep);
                if (config.useClassSelector && eventPlayer.currentKit == -1) {
                    eventPlayer.RemoveFromNetwork();
                    UI.ShowSpawnScreen(eventPlayer.player);
                    return;
                }
                OnPlayerSpawn(eventPlayer);
                if (scoreContainer != null) {
                    UI.DestroyUI(eventPlayer.player, ArenaUI.UIPanel.Scores);
                    UI.AddUI(eventPlayer.player, ArenaUI.UIPanel.Scores, scoreContainer);
                }
                if (giveKit) {
                    ins.NextTick(() => {
                        if (OverridePlayerKit(eventPlayer) is bool) return;
                        if (config.eventKits.Count > 1 && config.useClassSelector) ins.GiveKit(player, config.eventKits[eventPlayer.currentKit]);
                        else ins.GiveKit(player, currentKit);
                        GiveTeamGear(eventPlayer);
                        if (ins.configData.EventSettings.LockInventory) LockInventory(eventPlayer.player);
                    }
                    );
                }
                UI.ShowHelpText(player);
            }
            public virtual void OnPlayerSpawn(EventPlayer eventPlayer) {
            }
            public virtual void GiveTeamGear(EventPlayer eventPlayer) {
            }
            public virtual object OverridePlayerKit(EventPlayer eventPlayer) {
                return null;
            }
            public virtual EventPlayer[] GetSpectateTargets(Team team) {
                return eventPlayers.Where(x => x.team == team && !x.player.IsSpectating()).ToArray();
            }
            public int CountAlive() {
                int alive = 0;
                foreach (EventPlayer eventPlayer in eventPlayers) if (!eventPlayer.isDead && !eventPlayer.player.IsSpectating()) alive++;
                return alive;
            }
            public int CountStillPlaying() {
                int alive = 0;
                foreach (EventPlayer eventPlayer in eventPlayers) if (!eventPlayer.isEliminated) alive++;
                return alive;
            }
            public int GetTeamCount(Team team) {
                IEnumerable<EventPlayer> players = eventPlayers.Where(x => x.team == team);
                if (players == null) return 0;
                else return players.Count();
            }
            public int GetTeamAlive(Team team) {
                IEnumerable<EventPlayer> players = eventPlayers.Where(x => x.team == team && !x.isDead && !x.player.IsSpectating());
                if (players == null) return 0;
                else return players.Count();
            }
            public virtual int GetTeamScore(Team team) {
                int kills = 0;
                IEnumerable<EventPlayer> teamPlayers = eventPlayers.Where(x => x.team == team);
                foreach (EventPlayer eventPlayer in teamPlayers) kills += eventPlayer.kills;
                return kills;
            }
            public void BalanceTeams() {
                int aCount = GetTeamCount(Team.A);
                int bCount = GetTeamCount(Team.B);
                int difference = aCount > bCount + 1 ? aCount - bCount : bCount > aCount + 1 ? bCount - aCount : 0;
                Team moveFrom = aCount > bCount + 1 ? Team.A : bCount > aCount + 1 ? Team.B : Team.None;
                if (difference > 1 && moveFrom != Team.None) {
                    BroadcastToPlayers("teamsunbalanced", null, true);
                    EventPlayer[] teamPlayers = eventPlayers.Where(x => x.team == moveFrom).ToArray();
                    for (int i = 0; i < (int)Math.Floor((float)difference / 2);
                    i++) {
                        EventPlayer eventPlayer = teamPlayers.GetRandom();
                        eventPlayer.team = moveFrom == Team.A ? Team.B : Team.A;
                        BroadcastToPlayer(eventPlayer, string.Format(msg("teamswitched", eventPlayer.player.userID), eventPlayer.team));
                    }
                }
            }
#endregion
#region Death and Damage Management
            public virtual bool CanPlayerDealDamage(EventPlayer attacker, BaseEntity entity, HitInfo info) {
                return false;
            }
            public virtual void OnPlayerTakeDamage(EventPlayer eventPlayer, HitInfo info) {
                BasePlayer player = eventPlayer.player;
                EventPlayer attacker = ins.GetUser(info.InitiatorPlayer);
                if (godEnabled || eventPlayer.isDead) {
                    ins.NullifyDamage(info);
                    return;
                }
                if (info.isHeadshot) {
                    if (attacker != null) Statistics.OnHeadshot(attacker.player.userID, config);
                }
                float damageModifier = GetDamageModifier(attacker);
                if (damageModifier != 0) info.damageTypes.ScaleAll(damageModifier);
                eventPlayer.OnTakeDamage(attacker?.player.userID ?? 0U);
            }
            public void OnPlayerDeath(EventPlayer eventPlayer, HitInfo info) {
                eventPlayer.isDead = true;
                BasePlayer player = eventPlayer.player;
                if (dropBackpack && CanDropBackpack()) {
                    DroppedItemContainer itemContainer = ItemContainer.Drop("assets/prefabs/misc/item drop/item_drop_backpack.prefab", player.transform.position, Quaternion.identity, new ItemContainer[] {
                        player.inventory.containerBelt, player.inventory.containerMain
                    }
                    );
                    if (itemContainer != null) {
                        itemContainer.playerName = player.displayName;
                        itemContainer.playerSteamID = player.userID;
                    }
                }
                else {
                    if (dropAmmo && CanDropAmmo()) {
                        Item item = player.GetActiveItem();
                        if (item != null) {
                            BaseProjectile weapon = item.GetHeldEntity() as BaseProjectile;
                            if (weapon != null && weapon.primaryMagazine.contents > 0) {
                                Item ammo = ItemManager.Create(weapon.primaryMagazine.ammoType, weapon.primaryMagazine.contents);
                                BaseEntity entity = ammo.Drop(player.transform.position, Vector3.up);
                                ammo.Remove(30f);
                                weapon.primaryMagazine.contents = 0;
                                ins.RotateDroppedItem(entity);
                            }
                        }
                    }
                    if (dropWeapon && CanDropWeapons()) {
                        Item item = player.GetActiveItem();
                        if (item != null) {
                            BaseEntity entity = item.Drop(player.transform.position, Vector3.up);
                            item.Remove(30f);
                            ins.RotateDroppedItem(entity);
                        }
                    }
                }
                Statistics.OnEventPlayerDeath(eventPlayer, info, config);
                //EventPlayer attacker = ins.GetUser(info.InitiatorPlayer);
                OnPlayerDeath(eventPlayer, info?.InitiatorPlayer ?? null, info);
                if (info != null) ins.NullifyDamage(info);
            }
            public virtual bool CanShowDeathScreen() {
                return true;
            }
            public virtual void OnPlayerDeath(EventPlayer victim, BasePlayer attacker = null, HitInfo info = null) {
                if (victim == null || victim.player == null) return;
                victim.isDead = true;
                victim.player.Invoke(()=> StripInventory(victim.player), 0.25f);
                //victim.player.inventory.Strip();
                victim.player.RemoveFromTriggers();
                victim.RemoveFromNetwork();
                if (victim.player.isMounted) {
                    BaseMountable baseMountable = victim.player.GetMounted();
                    if (baseMountable != null) {
                        baseMountable.DismountPlayer(victim.player);
                        victim.player.EnsureDismounted();
                    }
                }
                string attackerName = attacker != null ? attacker.displayName : string.Empty;
                if (CanShowDeathScreen()) UI.ShowDeathScreen(victim.player, string.IsNullOrEmpty(attackerName) ? msg("aredead", victim.player.userID) : string.Format(msg("killedby", victim.player.userID), attackerName), ins.configData.GameTimers.RespawnTimer[config.eventType]);
                if (showKillFeed) DisplayKillToChat(victim, attackerName);
            }
            private void DisplayKillToChat(EventPlayer victim, string attackerName) {
                if (Events.IsSurvivalEvent(config.eventType)) {
                    int remaining = CountAlive();
                    if (remaining > 1) {
                        if (string.IsNullOrEmpty(attackerName)) {
                            if (victim.isOOB) {
                                BroadcastToPlayers("survrunaway", new string[] {
                                    victim.player.displayName, remaining.ToString()
                                }
                                );
                            }
                            else BroadcastToPlayers("survsuicide", new string[] {
                                victim.player.displayName, remaining.ToString()
                            }
                            );
                        }
                        else {
                            BroadcastToPlayers("survkilledplayer", new string[] {
                                attackerName, victim.player.displayName, remaining.ToString()
                            }
                            );
                        }
                    }
                }
                else {
                    if (string.IsNullOrEmpty(attackerName)) {
                        if (victim.isOOB) {
                            BroadcastToPlayers("runaway", new string[] {
                                victim.player.displayName
                            }
                            );
                        }
                        else BroadcastToPlayers("suicide", new string[] {
                            victim.player.displayName
                        }
                        );
                    }
                    else {
                        if (config.eventType != "GunGame") BroadcastToPlayers("killedplayer", new string[] {
                            attackerName, victim.player.displayName
                        }
                        );
                    }
                }
            }
            public virtual void OnNpcDeath(BaseCombatEntity entity, HitInfo info) {
            }
            public virtual void OnNpcCorpseSpawned(LootableCorpse corpse) {
            }
            public virtual bool IsEventNPC(ulong corpseId) {
                return false;
            }
            public virtual bool CanDropWeapons() {
                return true;
            }
            public virtual bool CanDropAmmo() {
                return true;
            }
            public virtual bool CanDropBackpack() {
                return true;
            }
            public virtual float GetDamageModifier(EventPlayer attacker) {
                if (attacker != null) return GetDamageModifier(attacker.player.userID);
                return 0f;
            }
            public virtual float GetDamageModifier(ulong attackerId) {
                return 0f;
            }
#endregion
#region Entity Management
            public void OnEntityDeployed(BaseCombatEntity entity) {
                deployedObjects.Add(entity);
            }
            private void CleanupEntities() {
                for (int i = deployedObjects.Count - 1; i >= 0; i--) {
                    BaseCombatEntity entity = deployedObjects[i];
                    if (entity != null && !entity.IsDestroyed) entity.DieInstantly();
                }
                deployedObjects.Clear();
            }
#endregion
#region Menu Management
            public virtual Dictionary<string, string> GetAdditionalInformation() {
                return new Dictionary<string, string>();
            }
#endregion
#region Scoreboards
            public void DisplayFinalScoreboard() => UI.ShowEventResults(this);
            public void UpdateScoreboard() {
                scoreContainer = UI.ShowGameScores(this);
            }
            public void DestroyScoreboard(BasePlayer player) => UI.DestroyUI(player, ArenaUI.UIPanel.Scores);
            public virtual List<ScoreEntry> GetGameScores(Team team = Team.A) {
                List<ScoreEntry> gameScores = new List<ScoreEntry>();
                int i = 1;
                foreach (EventPlayer eventPlayer in eventPlayers.Where(x => x.team == team).OrderByDescending(x
// ... [Code preview truncated due to length. Full source in attached file] ...

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