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

FREE DangerousTreasures : 1.2.9 1.2.9

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using Facepunch;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Rust;
using UnityEngine;
using System.Reflection;
namespace Oxide.Plugins {
    [Info("Dangerous Treasures", "nivex", "1.2.9")]
    [Description("Event with treasure chests.")]
    public class DangerousTreasures : RustPlugin {
        [PluginReference]
        Plugin LustyMap, ZoneManager, Economics, ServerRewards, Map, GUIAnnouncements;
        public static readonly FieldInfo AllScientists = typeof(Scientist).GetField("AllScientists", (BindingFlags.Static | BindingFlags.NonPublic));
        static DangerousTreasures ins;
        static bool unloading = false;
        bool init = false;
        bool wipeChestsSeed = false;
        SpawnFilter filter = new SpawnFilter();
        ItemDefinition boxDef;
        static ItemDefinition rocketDef;
        const string boxShortname = "box.wooden.large";
        const string fireRocketShortname = "ammo.rocket.fire";
        const string basicRocketShortname = "ammo.rocket.basic";
        const string boxPrefab = "assets/prefabs/deployable/large wood storage/box.wooden.large.prefab";
        const string spherePrefab = "assets/prefabs/visualization/sphere.prefab";
        const string fireballPrefab = "assets/bundled/prefabs/oilfireballsmall.prefab";
        static string rocketResourcePath;
        DynamicConfigFile dataFile;
        StoredData storedData = new StoredData();
        Vector3 sd_customPos;
        static int playerMask = LayerMask.GetMask("Player (Server)");
        static int blockedMask = LayerMask.GetMask(new[] {
            "Player (Server)", "Trigger", "Prevent Building"
        }
        );
        static int obstructionMask = LayerMask.GetMask(new[] {
            "Player (Server)", "Construction"
        }
        );
        static int heightMask = LayerMask.GetMask(new[] {
            "Terrain", "World", "Default", "Construction", "Deployed"
        }
        );
        static int twdMask = LayerMask.GetMask(new[] {
            "Terrain", "World", "Default"
        }
        );
        static int twwMask = LayerMask.GetMask(new[] {
            "Terrain", "World", "Water"
        }
        );
        static int worldMask = LayerMask.GetMask("World", "Default");
        List<int> BlockedLayers = new List<int> {
            (int)Layer.Water, (int)Layer.Construction, (int)Layer.Trigger, (int)Layer.Prevent_Building, (int)Layer.Deployed, (int)Layer.Tree
        }
        ;
        static List<MonumentInfo> monuments = new List<MonumentInfo>();
        // positions of monuments on the server
        static List<uint> newmanProtections = new List<uint>();
        List<ulong> indestructibleWarnings = new List<ulong>();
        // indestructible messages limited to once every 10 seconds
        List<ulong> drawGrants = new List<ulong>();
        // limit draw to once every 15 seconds by default
        Dictionary<Vector3, float> managedZones = new Dictionary<Vector3, float>();
        static Dictionary<uint, MapInfo> mapMarkers = new Dictionary<uint, MapInfo>();
        static Dictionary<uint, string> lustyMarkers = new Dictionary<uint, string>();
        Dictionary<string, List<ulong>> skinsCache = new Dictionary<string, List<ulong>>();
        Dictionary<string, List<ulong>> workshopskinsCache = new Dictionary<string, List<ulong>>();
        static Dictionary<uint, TreasureChest> treasureChests = new Dictionary<uint, TreasureChest>();
        static Dictionary<uint, string> looters = new Dictionary<uint, string>();
        List<uint> storage = new List<uint>();
        class MapInfo {
            public string Url;
            public string IconName;
            public Vector3 Position;
            public MapInfo() {
            }
        }
        class TreasureItem {
            public object shortname {
                get;
                set;
            }
            = string.Empty;
            public object amount {
                get;
                set;
            }
            = 0;
            public object skin {
                get;
                set;
            }
            = 0uL;
            public TreasureItem() {
            }
        }
        class PlayerInfo {
            public int StolenChestsTotal {
                get;
                set;
            }
            = 0;
            public int StolenChestsSeed {
                get;
                set;
            }
            = 0;
            public PlayerInfo() {
            }
        }
        class StoredData {
            public double SecondsUntilEvent = double.MinValue;
            public int TotalEvents = 0;
            public readonly Dictionary<string, PlayerInfo> Players = new Dictionary<string, PlayerInfo>();
            public List<uint> Markers = new List<uint>();
            public string CustomPosition;
            public StoredData() {
            }
        }
        class GuidanceSystem : FacepunchBehaviour {
            TimedExplosive missile;
            ServerProjectile projectile;
            BaseEntity target;
            float rocketSpeedMulti = 2f;
            Timer launch;
            Vector3 launchPos;
            List<ulong> exclude = new List<ulong>();
            void Awake() {
                missile = GetComponent<TimedExplosive>();
                projectile = missile.GetComponent<ServerProjectile>();
                launchPos = missile.transform.position;
                launchPos.y = TerrainMeta.HeightMap.GetHeight(launchPos);
                projectile.gravityModifier = 0f;
                projectile.speed = 5f;
                projectile.InitializeVelocity(Vector3.up);
                missile.explosionRadius = 0f;
                missile.timerAmountMin = timeUntilExplode;
                missile.timerAmountMax = timeUntilExplode;
                missile.damageTypes = new List<DamageTypeEntry>();
                // no damage
                missile.Spawn();
                if (!missile) return;
                launch = ins.timer.Once(targettingTime, () => {
                    if (!missile || missile.IsDestroyed) return;
                    var list = new List<BasePlayer>();
                    var entities = Pool.GetList<BaseEntity>();
                    Vis.Entities<BaseEntity>(launchPos, eventRadius + missileDetectionDistance, entities, playerMask, QueryTriggerInteraction.Collide);
                    foreach (var entity in entities) {
                        var player = entity as BasePlayer;
                        if (!player || player is NPCPlayer || !player.CanInteract()) continue;
                        if (ignoreFlying && player.IsFlying) continue;
                        if (exclude.Contains(player.userID) || newmanProtections.Contains(player.net.ID)) continue;
                        list.Add(player);
                        // acquire a player target
                    }
                    Pool.FreeList<BaseEntity>(ref entities);
                    if (list.Count > 0) {
                        SetTarget(list.GetRandom());
                        // pick a random player
                        list.Clear();
                    }
                    else if (!targetChest) {
                        missile.Kill();
                        return;
                    }
                    projectile.speed = rocketSpeed * rocketSpeedMulti;
                    InvokeRepeating(new Action(GuideMissile), 0.1f, 0.1f);
                }
                );
            }
            public void SetTarget(BaseEntity target) {
                this.target = target;
            }
            public void Exclude(List<ulong> list) {
                if (list != null && list.Count > 0) {
                    exclude.Clear();
                    exclude.AddRange(list);
                }
            }
            void GuideMissile() {
                if (target == null) return;
                if (target.IsDestroyed) {
                    if (missile != null && !missile.IsDestroyed) {
                        missile.Kill();
                    }
                    return;
                }
                if (missile == null || missile.IsDestroyed || projectile == null) {
                    GameObject.Destroy(this);
                    return;
                }
                if (Vector3.Distance(target.transform.position, missile.transform.position) <= 1f) {
                    missile.Explode();
                    return;
                }
                var direction = (target.transform.position - missile.transform.position) + Vector3.down;
                // direction to guide the missile
                projectile.InitializeVelocity(direction);
                // guide the missile to the target's position
            }
            void OnDestroy() {
                exclude.Clear();
                launch?.Destroy();
                CancelInvoke(new Action(GuideMissile));
                GameObject.Destroy(this);
            }
        }
        class TreasureChest : FacepunchBehaviour {
            public StorageContainer container;
            public bool started = false;
            long _unlockTime;
            public Vector3 containerPos;
            uint uid;
            int countdownTime;
            float posMulti = 3f;
            float sphereMulti = 2f;
            float claimTime;
            float lastTick;
            Vector3 lastFirePos;
            bool firstEntered;
            Dictionary<ulong, float> fireticks = new Dictionary<ulong, float>();
            List<FireBall> fireballs = new List<FireBall>();
            List<ulong> players = new List<ulong>();
            List<ulong> newmans = new List<ulong>();
            List<ulong> traitors = new List<ulong>();
            List<uint> protects = new List<uint>();
            List<TimedExplosive> missiles = new List<TimedExplosive>();
            List<int> times = new List<int>();
            List<SphereEntity> spheres = new List<SphereEntity>();
            List<Vector3> missilePositions = new List<Vector3>();
            List<Vector3> firePositions = new List<Vector3>();
            Timer destruct, unlock, countdown, announcement;
            public List<NPCPlayerApex> npcs = new List<NPCPlayerApex>();
            List<Vector3> spawnpoints;
            public bool HasNPC(ulong userID) {
                return npcs.Any(x => x.userID == userID);
            }
            public Vector3 GetSpawn() {
                if (monuments.Any(x => Vector3.Distance(x.transform.position, containerPos) < 50f)) {
                    return containerPos;
                }
                if (spawnpoints == null || spawnpoints.Count == 0) spawnpoints = BaseNetworkable.serverEntities.Where(e => e != null && e.transform != null && Vector3.Distance(e.transform.position, containerPos) < eventRadius * 0.75f && IsValidSpawn(e)).Select(e => new Vector3(e.transform.position.x, e.transform.position.y + 0.25f, e.transform.position.z)).ToList();
                if (!undergroundLoot) {
                    spawnpoints.RemoveAll(e => e.y < containerPos.y);
                }
                var narrowed = spawnpoints.Where(x => Vector3.Distance(x, containerPos) < 15f).ToList();
                if (narrowed.Count >= spawnNpcsAmount) {
                    return narrowed.GetRandom();
                }
                var spawnpoint = spawnpoints.Count > 2 ? spawnpoints.GetRandom() : containerPos;
                return spawnpoint;
            }
            void Awake() {
                container = GetComponent<StorageContainer>();
                containerPos = container.transform.position;
                uid = container.net.ID;
                lastTick = Time.time;
                gameObject.layer = (int)Layer.Reserved1;
                var collider = gameObject.GetComponent<SphereCollider>() ?? gameObject.AddComponent<SphereCollider>();
                collider.center = Vector3.zero;
                collider.radius = eventRadius;
                collider.isTrigger = true;
                collider.enabled = true;
                if (useSpheres && amountOfSpheres > 0) {
                    for (int i = 0; i < amountOfSpheres; i++) {
                        var sphere = GameManager.server.CreateEntity(spherePrefab, containerPos, new Quaternion(), true) as SphereEntity;
                        if (sphere != null) {
                            sphere.currentRadius = 1f;
                            sphere.Spawn();
                            sphere.LerpRadiusTo(eventRadius * sphereMulti, 5f);
                            spheres.Add(sphere);
                        }
                        else {
                            ins.Puts(ins.msg(szInvalidConstant, null, spherePrefab));
                            useSpheres = false;
                            break;
                        }
                    }
                }
                if (useRocketOpener) {
                    var positions = GetRandomPositions(containerPos, eventRadius * posMulti, numRockets, 0f);
                    foreach (var position in positions) CreateRocket(position, containerPos, Vector3.down);
                    positions.Clear();
                }
                if (useFireballs) {
                    firePositions = GetRandomPositions(containerPos, eventRadius, 25, containerPos.y + 25f);
                    if (firePositions.Count > 0) InvokeRepeating(new Action(SpawnFire), 0.1f, secondsBeforeTick);
                }
                if (launchMissiles) {
                    missilePositions = GetRandomPositions(containerPos, eventRadius, 25, 1);
                    if (missilePositions.Count > 0) {
                        InvokeRepeating(new Action(LaunchMissile), 0.1f, missileFrequency);
                        LaunchMissile();
                    }
                }
            }
            void OnTriggerEnter(Collider col) {
                if (started) return;
                var player = col.GetComponentInParent<BasePlayer>();
                if (!player || player is NPCPlayer || players.Contains(player.userID)) return;
                if (showFirstEntered && !firstEntered) {
                    firstEntered = true;
                    string eventPos = FormatGridReference(containerPos);
                    foreach (var target in BasePlayer.activePlayerList) target.ChatMessage(ins.msg("OnFirstPlayerEntered", target.UserIDString, target.displayName, eventPos));
                }
                player.ChatMessage(ins.msg(useFireballs ? szProtected : szUnprotected, player.UserIDString));
                players.Add(player.userID);
            }
            void OnTriggerExit(Collider col) {
                if (!newmanProtect) return;
                var player = col.GetComponentInParent<BasePlayer>();
                if (!player || player is NPCPlayer) return;
                if (protects.Contains(player.net.ID)) {
                    newmanProtections.Remove(player.net.ID);
                    protects.Remove(player.net.ID);
                    player.ChatMessage(ins.msg(szNewmanProtectFade, player.UserIDString));
                }
            }
            void OnTriggerStay(Collider col) {
                if (!useFireballs && !newmanMode && !newmanProtect) return;
                if (started || Time.time - lastTick < 0.1f) return;
                lastTick = Time.time;
                var player = col.GetComponentInParent<BasePlayer>();
                if (!player || player is NPCPlayer) return;
                if (newmanMode || newmanProtect) {
                    int count = player.inventory.AllItems().Where(item => item.info.shortname != "torch" && item.info.shortname != "rock" && player.IsHostileItem(item))?.Count() ?? 0;
                    if (count == 0) {
                        if (newmanMode && !newmans.Contains(player.userID) && !traitors.Contains(player.userID)) {
                            player.ChatMessage(ins.msg(szNewmanEnter, player.UserIDString));
                            newmans.Add(player.userID);
                        }
                        if (newmanProtect && !newmanProtections.Contains(player.net.ID) && !protects.Contains(player.net.ID) && !traitors.Contains(player.userID)) {
                            player.ChatMessage(ins.msg(szNewmanProtect, player.UserIDString));
                            newmanProtections.Add(player.net.ID);
                            protects.Add(player.net.ID);
                        }
                        if (!traitors.Contains(player.userID)) return;
                    }
                    if (newmans.Contains(player.userID)) {
                        player.ChatMessage(ins.msg(useFireballs ? szNewmanTraitorBurn : szNewmanTraitor, player.UserIDString));
                        newmans.Remove(player.userID);
                        if (!traitors.Contains(player.userID)) traitors.Add(player.userID);
                        newmanProtections.Remove(player.net.ID);
                        protects.Remove(player.net.ID);
                    }
                }
                if (!useFireballs) return;
                float stamp = Time.realtimeSinceStartup;
                if (!fireticks.ContainsKey(player.userID)) fireticks[player.userID] = stamp + secondsBeforeTick;
                if (fireticks[player.userID] - stamp <= 0) {
                    fireticks[player.userID] = stamp + secondsBeforeTick;
                    SpawnFire(player.transform.position);
                }
            }
            void KillNpc() {
                foreach (var npc in npcs.ToList()) {
                    if (npc != null && !npc.IsDestroyed) {
                        npc.Kill();
                    }
                }
                npcs.Clear();
            }
            void OnDestroy() {
                ins.RemoveLustyMarker(uid);
                ins.RemoveMapMarker(uid);
                DestroyLauncher();
                DestroySphere();
                DestroyFire();
                fireticks?.Clear();
                players?.Clear();
                times?.Clear();
                unlock?.Destroy();
                destruct?.Destroy();
                countdown?.Destroy();
                announcement?.Destroy();
                KillNpc();
                if (treasureChests.ContainsKey(uid)) {
                    treasureChests.Remove(uid);
                    if (!unloading && treasureChests.Count == 0)  // 0.1.21 - nre fix
                    {
                        ins.SubscribeHooks(false);
                    }
                }
                GameObject.Destroy(this);
            }
            public void LaunchMissile() {
                if (string.IsNullOrEmpty(rocketResourcePath)) launchMissiles = false;
                if (!launchMissiles) {
                    DestroyLauncher();
                    return;
                }
                var missilePos = missilePositions.GetRandom();
                float y = TerrainMeta.HeightMap.GetHeight(missilePos) + 15f;
                missilePos.y = 200f;
                RaycastHit hit;
                if (Physics.Raycast(missilePos, Vector3.down, out hit, heightMask))  // don't want the missile to explode before it leaves its spawn location
                missilePos.y = Mathf.Max(hit.point.y, y);
                var missile = GameManager.server.CreateEntity(rocketResourcePath, missilePos, new Quaternion(), true) as TimedExplosive;
                if (!missile) {
                    launchMissiles = false;
                    return;
                }
                missiles.Add(missile);
                missiles.RemoveAll(x => x == null || x.IsDestroyed);
                var gs = missile.gameObject.AddComponent<GuidanceSystem>();
                gs.Exclude(newmans);
                gs.SetTarget(container);
            }
            void SpawnFire() {
                var firePos = firePositions.GetRandom();
                int retries = firePositions.Count;
                while (Vector3.Distance(firePos, lastFirePos) < eventRadius * 0.35f && --retries > 0) {
                    firePos = firePositions.GetRandom();
                }
                SpawnFire(firePos);
                lastFirePos = firePos;
            }
            void SpawnFire(Vector3 firePos) {
                if (!useFireballs) return;
                if (fireballs.Count >= 6)  // limit fireballs
                {
                    foreach (var entry in fireballs) {
                        if (entry != null && !entry.IsDestroyed) entry.Kill();
                        fireballs.Remove(entry);
                        break;
                    }
                }
                var fireball = GameManager.server.CreateEntity(fireballPrefab, firePos, new Quaternion(), true) as FireBall;
                if (fireball == null) {
                    ins.Puts(ins.msg(szInvalidConstant, null, fireballPrefab));
                    useFireballs = false;
                    CancelInvoke(new Action(SpawnFire));
                    firePositions.Clear();
                    return;
                }
                fireball.Spawn();
                //fireball.enableSaving = false;
                //BaseEntity.saveList.Remove(fireball);
                fireball.damagePerSecond = fbDamagePerSecond;
                fireball.generation = fbGeneration;
                fireball.lifeTimeMax = fbLifeTimeMax;
                fireball.lifeTimeMin = fbLifeTimeMin;
                fireball.radius = fbRadius;
                fireball.tickRate = fbTickRate;
                fireball.waterToExtinguish = fbWaterToExtinguish;
                fireball.SendNetworkUpdate();
                fireball.Think();
                float lifeTime = UnityEngine.Random.Range(fbLifeTimeMin, fbLifeTimeMax);
                ins.timer.Once(lifeTime, () => fireball?.Extinguish());
                fireballs.Add(fireball);
            }
            public void Destruct() {
                unlock?.Destroy();
                destruct?.Destroy();
                if (container != null && !container.IsDestroyed) {
                    container.inventory.Clear();
                    container.Kill();
                }
            }
            void Unclaimed() {
                if (!started) return;
                float time = claimTime - Time.realtimeSinceStartup;
                if (time < 60f) return;
                string eventPos = FormatGridReference(containerPos);
                foreach (var target in BasePlayer.activePlayerList) target.ChatMessage(ins.msg(szDestroyingTreasure, target.UserIDString, eventPos, ins.FormatTime(time, target.UserIDString), szDistanceChatCommand));
            }
            public string GetUnlockTime(string userID = null) {
                return started ? null : ins.FormatTime(_unlockTime - Time.realtimeSinceStartup, userID);
            }
            public void SetUnlockTime(float time) {
                var posStr = FormatGridReference(containerPos);
                countdownTime = Convert.ToInt32(time);
                _unlockTime = Convert.ToInt64(Time.realtimeSinceStartup + time);
                unlock = ins.timer.Once(time, () => {
                    if (container.HasFlag(BaseEntity.Flags.Locked)) container.SetFlag(BaseEntity.Flags.Locked, false);
                    if (container.HasFlag(BaseEntity.Flags.OnFire)) container.SetFlag(BaseEntity.Flags.OnFire, false);
                    if (showStarted) foreach (var target in BasePlayer.activePlayerList) SendDangerousMessage(target, containerPos, ins.msg(szEventStarted, target.UserIDString, posStr));
                    if (destructTime > 0f) destruct = ins.timer.Once(destructTime, () => Destruct());
                    DestroyFire();
                    DestroySphere();
                    DestroyLauncher();
                    started = true;
                    if (useUnclaimedAnnouncements) {
                        claimTime = Time.realtimeSinceStartup + destructTime;
                        announcement = ins.timer.Repeat(unclaimedInterval * 60f, 0, () => Unclaimed());
                    }
                }
                );
                if (useCountdown && countdownTimes.Count > 0) {
                    if (times.Count == 0) times.AddRange(countdownTimes);
                    countdown = ins.timer.Repeat(1f, 0, () => {
                        countdownTime--;
                        if (started || times.Count == 0) {
                            countdown.Destroy();
                            return;
                        }
                        if (times.Contains(countdownTime)) {
                            string eventPos = FormatGridReference(containerPos);
                            foreach (var target in BasePlayer.activePlayerList) SendDangerousMessage(target, containerPos, ins.msg(szEventCountdown, target.UserIDString, eventPos, ins.FormatTime(countdownTime, target.UserIDString)));
                            times.Remove(countdownTime);
                        }
                    }
                    );
                }
            }
            public void DestroyLauncher() {
                if (missilePositions.Count > 0) {
                    CancelInvoke(new Action(LaunchMissile));
                    missilePositions.Clear();
                }
                if (missiles.Count > 0) {
                    foreach (var entry in missiles) if (entry != null && !entry.IsDestroyed) entry.Kill();
                    missiles.Clear();
                }
            }
            public void DestroySphere() {
                foreach (var sphere in spheres) if (sphere != null && !sphere.IsDestroyed) sphere.Kill();
            }
            public void DestroyFire() {
                if (firePositions.Count > 0) {
                    CancelInvoke(new Action(SpawnFire));
                    firePositions.Clear();
                }
                if (useFireballs) {
                    foreach (var fireball in fireballs) {
                        if (fireball != null && !fireball.IsDestroyed) fireball.Kill();
                    }
                    fireballs.Clear();
                }
                newmanProtections.RemoveAll(x => protects.Contains(x));
                traitors.Clear();
                newmans.Clear();
                protects.Clear();
            }
        }
        void OnNewSave(string filename) => wipeChestsSeed = true;
        void Init() {
            SubscribeHooks(false);
        }
        void OnServerInitialized() {
            if (init) return;
            ins = this;
            dataFile = Interface.Oxide.DataFileSystem.GetFile(Name);
            try {
                storedData = dataFile.ReadObject<StoredData>();
            }
            catch {
            }
            if (storedData?.Players == null) storedData = new StoredData();
            LoadVariables();
            if (chestLoot.Count == 0) {
                Puts(msg(szUnloading, null, "Treasure"));
                Interface.Oxide.UnloadPlugin(Name);
                return;
            }
            if (automatedEvents) {
                if (storedData.SecondsUntilEvent != double.MinValue) if (storedData.SecondsUntilEvent - Time.realtimeSinceStartup > eventIntervalMax)  // Allows users to lower max event time
                storedData.SecondsUntilEvent = double.MinValue;
                eventTimer = timer.Repeat(1f, 0, () => CheckSecondsUntilEvent());
            }
            if (!string.IsNullOrEmpty(storedData.CustomPosition)) sd_customPos = storedData.CustomPosition.ToVector3();
            else sd_customPos = Vector3.zero;
            if (wipeChestsSeed) {
                if (storedData.Players.Count > 0) {
                    var ladder = storedData.Players.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.StolenChestsSeed).ToList<KeyValuePair<string, int>>();
                    if (AssignTreasureHunters(ladder)) {
                        foreach (var kvp in storedData.Players.ToList()) {
                            storedData.Players[kvp.Key].StolenChestsSeed = 0;
                        }
                    }
                }
                sd_customPos = Vector3.zero;
                storedData.CustomPosition = "";
                wipeChestsSeed = false;
                SaveData();
            }
            rocketDef = ItemManager.FindItemDefinition(useFireRockets ? fireRocketShortname : basicRocketShortname);
            if (!rocketDef) {
                ins.Puts(ins.msg(szInvalidConstant, null, useFireRockets ? fireRocketShortname : basicRocketShortname));
                useRocketOpener = false;
            }
            else rocketResourcePath = rocketDef.GetComponent<ItemModProjectile>().projectileObject.resourcePath;
            boxDef = ItemManager.FindItemDefinition(boxShortname);
            if (!boxDef) {
                Puts(msg(szInvalidConstant, null, boxShortname));
                useRandomBoxSkin = false;
            }
            if (ZoneManager != null) {
                var zoneIds = ZoneManager?.Call("GetZoneIDs");
                if (zoneIds != null && zoneIds is string[]) {
                    foreach (var zoneId in (string[])zoneIds) {
                        var zoneLoc = ZoneManager?.Call("GetZoneLocation", zoneId);
                        if (zoneLoc is Vector3 && (Vector3)zoneLoc != Vector3.zero) {
                            var position = (Vector3)zoneLoc;
                            var zoneRadius = ZoneManager?.Call("GetZoneRadius", zoneId);
                            float distance = 0f;
                            if (zoneRadius is float && (float)zoneRadius > 0f) {
                                distance = (float)zoneRadius;
                            }
                            else {
                                var zoneSize = ZoneManager?.Call("GetZoneSize", zoneId);
                                if (zoneSize is Vector3 && (Vector3)zoneSize != Vector3.zero) {
                                    var size = (Vector3)zoneSize;
                                    distance = Mathf.Max(size.x, size.y);
                                }
                            }
                            if (distance > 0f) {
                                distance += eventRadius + 5f;
                                managedZones[position] = distance;
                            }
                        }
                    }
                }
                if (managedZones.Count > 0) Puts("Blocking events at zones: {0}", string.Join(", ", managedZones.Select(zone => string.Format("{0} ({1}: {2}m)", zone.Key.ToString().Replace("(", "").Replace(")", ""), FormatGridReference(zone.Key), zone.Value)).ToArray()));
            }
            if (!undergroundLoot) blacklistedMonuments.Add("Sewer");
            monuments.AddRange(UnityEngine.Object.FindObjectsOfType<MonumentInfo>().Where(info => info?.transform != null && info.shouldDisplayOnMap).ToList());
            if (monuments.Count == 0) {
                onlyMonuments = false;
                allowMonumentChance = 0f;
            }
            else {
                foreach (var m in monuments.ToList()) {
                    if (blacklistedMonuments.Any(x => m.displayPhrase.english.ToLower().Trim() == x.ToLower().Trim())) {
                        monuments.Remove(m);
                    }
                }
            }
            if (includeWorkshopBox || includeWorkshopTreasure) webrequest.Enqueue("http://s3.amazonaws.com/s3.playrust.com/icons/inventory/rust/schema.json", null, GetWorkshopIDs, this, Core.Libraries.RequestMethod.GET);
            init = true;
            RemoveAllTemporaryMarkers();
        }
        void Unload() {
            if (!init) return;
            unloading = true;
            if (treasureChests.Count > 0) {
                foreach (var entry in treasureChests) {
                    var container = BaseEntity.serverEntities.Find(entry.Key) as StorageContainer;
                    if (container == null) continue;
                    Puts(msg(szDestroyed, null, container.transform.position));
                    container.inventory?.Clear();
                    if (!container.IsDestroyed) container.Kill();
                }
            }
            var objects = GameObject.FindObjectsOfType(typeof(TreasureChest));
            // this isn't needed but doesn't hurt to be here
            if (objects != null) foreach (var gameObj in objects) GameObject.Destroy(gameObj);
            if (lustyMarkers.Count > 0) foreach (var entry in lustyMarkers.ToList()) RemoveLustyMarker(entry.Key);
            if (mapMarkers.Count > 0) foreach (var entry in mapMarkers.ToList()) RemoveMapMarker(entry.Key);
            BlockedLayers.Clear();
            chestLoot?.Clear();
            eventTimer?.Destroy();
            indestructibleWarnings.Clear();
            countdownTimes.Clear();
            skinsCache.Clear();
            workshopskinsCache.Clear();
            RemoveAllTemporaryMarkers();
        }
        object CanBradleyApcTarget(BradleyAPC apc, BaseEntity entity) {
            if (entity is NPCPlayer) {
                var npc = entity as NPCPlayer;
                if (treasureChests.Values.Any(x => x.HasNPC(npc.userID))) {
                    return false;
                }
            }
            return null;
        }
        object OnNpcPlayerTarget(NPCPlayerApex npc, BaseEntity entity) {
            if (init && entity?.transform != null && entity is BasePlayer) {
                var player = entity as BasePlayer;
                if (player.net != null && newmanProtections.Contains(player.net.ID)) {
                    return 0f;
                }
                else if (player is NPCPlayer && treasureChests.Values.Any(x => x.HasNPC(player.userID) && x.HasNPC(npc.userID))) {
                    return true;
                }
            }
            return null;
        }
        void OnPlayerDie(BasePlayer player) {
            if (!init || !player || !(player is NPCPlayer)) return;
            var npc = player as NPCPlayer;
            foreach (var chest in treasureChests.Values) {
                if (chest.HasNPC(npc.userID)) {
                    player.svActiveItemID = 0;
                    player.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    break;
                }
            }
        }
        void OnEntitySpawned(BaseNetworkable entity) {
            if (!init || entity == null) return;
            if (entity as Scientist != null) {
                AllScientists.SetValue((entity as Scientist), new HashSet<Scientist>());
                // Steenamaroo fix for NPCPlayerApex.OnAiQuestion NullReferenceException #1
            }
            else if (entity is NPCPlayerCorpse) {
                var corpse = entity as NPCPlayerCorpse;
                if (treasureChests.Values.Any(x => x.HasNPC(corpse.playerSteamID))) {
                    if (spawnsDespawnInventory) {
                        NextTick(() => {
                            if (corpse != null && !corpse.IsDestroyed) {
                                corpse.containers[0].Clear();
                                corpse.containers[1].Clear();
                                corpse.containers[2].Clear();
                            }
                        }
                        );
                    }
                    var chest = treasureChests.Values.First(x => x.HasNPC(corpse.playerSteamID));
                    chest.npcs.RemoveAll(npc => npc.userID == corpse.playerSteamID);
                    if (treasureChests.Values.All(x => x.npcs.Count == 0)) {
                        Unsubscribe(nameof(OnNpcPlayerTarget));
                        Unsubscribe(nameof(CanBradleyApcTarget));
                        Unsubscribe(nameof(OnPlayerDie));
                    }
                }
            }
            else if (entity is BaseLock) {
                NextTick(() => {
                    if (entity != null && !entity.IsDestroyed) {
                        if (treasureChests.Values.Any(x => Vector3.Distance(entity.transform.position, x.containerPos) <= eventRadius)) {
                            entity.KillMessage();
                        }
                    }
                }
                );
            }
        }
        object CanBuild(Planner plan, Construction prefab) {
            if (!init || plan?.GetOwnerPlayer() == null) return null;
            var player = plan.GetOwnerPlayer();
            if (player.IsAdmin) return null;
            foreach (var entry in treasureChests) {
                if (Vector3.Distance(player.transform.position, entry.Value.containerPos) <= eventRadius) {
                    player.ChatMessage(msg(szBuildingBlocked, player.UserIDString));
                    return false;
                }
            }
            return null;
        }
        object CanAcceptItem(ItemContainer container, Item item) {
            if (!init || container?.entityOwner?.net == null) return null;
            return treasureChests.ContainsKey(container.entityOwner.net.ID) ? (object)ItemContainer.CanAcceptResult.CannotAccept : null;
        }
        void OnLootEntity(BasePlayer player, BaseEntity entity) {
            if (!init || player == null || entity?.net == null || !(entity is StorageContainer) || !treasureChests.ContainsKey(entity.net.ID)) return;
            if (looters.ContainsKey(entity.net.ID)) looters.Remove(entity.net.ID);
            looters.Add(entity.net.ID, player.UserIDString);
        }
        void OnItemRemovedFromContainer(ItemContainer container, Item item) {
            if (container?.entityOwner == null || !(container.entityOwner is StorageContainer)) return;
            NextTick(() => {
                var box = container?.entityOwner as StorageContainer;
                if (box?.net == null || !treasureChests.ContainsKey(box.net.ID)) return;
                var looter = item.GetOwnerPlayer();
                if (looter != null) {
                    if (looters.ContainsKey(box.net.ID)) looters.Remove(box.net.ID);
                    looters.Add(box.net.ID, looter.UserIDString);
                }
                if (box.inventory.itemList.Count == 0) {
                    if (looter == null && looters.ContainsKey(box.net.ID)) looter = BasePlayer.activePlayerList.Find(x => x.UserIDString == looters[box.net.ID]);
                    if (looter != null) {
                        if (recordStats) {
                            if (!storedData.Players.ContainsKey(looter.UserIDString)) storedData.Players.Add(looter.UserIDString, new PlayerInfo());
                            storedData.Players[looter.UserIDString].StolenChestsTotal++;
                            storedData.Players[looter.UserIDString].StolenChestsSeed++;
                            SaveData();
                        }
                        var posStr = FormatGridReference(looter.transform.position);
                        Puts(msg(szEventThief, null, posStr, looter.displayName));
                        foreach (var target in BasePlayer.activePlayerList) SendDangerousMessage(target, looter.transform.position, msg(szEventThief, target.UserIDString, posStr, looter.displayName));
                        looter.EndLooting();
                        if (useEconomics && economicsMoney > 0) {
                            if (Economics != null) {
                                Economics?.Call("Deposit", looter.UserIDString, economicsMoney);
                                looter.ChatMessage(msg(szEconomicsDeposit, looter.UserIDString, economicsMoney));
                            }
                        }
                        if (useServerRewards && serverRewardsPoints > 0) {
                            if (ServerRewards != null) {
                                var success = ServerRewards?.Call("AddPoints", looter.userID, serverRewardsPoints);
                                if (success != null && success is bool && (bool)success) looter.ChatMessage(msg(szRewardPoints, looter.UserIDString, serverRewardsPoints));
                            }
                        }
                    }
                    ins.RemoveLustyMarker(box.net.ID);
                    ins.RemoveMapMarker(box.net.ID);
                    if (!box.IsDestroyed) box.Kill();
                    if (treasureChests.Count == 0) SubscribeHooks(false);
                }
            }
            );
        }
        object CanEntityTakeDamage(BaseEntity entity, HitInfo hitInfo)  // TruePVE!!!! <3 @ignignokt84
        {
            if (entity == null || !(entity is BasePlayer) || hitInfo == null) {
                return null;
            }
            if (truePVEServerWidePVP && hitInfo.InitiatorPlayer != null)  // 1.2.9
            {
                return true;
            }
            return truePVEAllowPVPAtEvents && EventTerritory(hitInfo.PointStart) && EventTerritory(hitInfo.PointEnd) ? (object)true : null;
        }
        bool EventTerritory(Vector3 position) {
            return treasureChests.Values.Any(x => Vector3.Distance(x.containerPos, new Vector3(position.x, x.containerPos.y, position.z)) <= eventRadius);
        }
        void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo) {
            if (!init || entity?.net == null) return;
            bool newman = newmanProtections.Contains(entity.net.ID);
            bool chest = treasureChests.ContainsKey(entity.net.ID);
            if (newman || chest) {
                var attacker = hitInfo?.InitiatorPlayer ?? null;
                if (attacker) {
                    var uid = attacker.userID;
                    if (!indestructibleWarnings.Contains(uid)) {
                        indestructibleWarnings.Add(uid);
                        timer.Once(10f, () => indestructibleWarnings.Remove(uid));
                        attacker.ChatMessage(msg(chest ? szIndestructible : szNewmanProtected, attacker.UserIDString));
                    }
                }
                if (hitInfo != null && hitInfo.hasDamage) {
                    hitInfo.damageTypes.ScaleAll(0f);
                }
            }
            var npc = entity as NPCPlayer;
            if (npc == null || !treasureChests.Values.Any(x => x.HasNPC(npc.userID))) return;
            if (hitInfo.hasDamage && hitInfo.damageTypes.GetMajorityDamageType() == DamageType.Heat)  // make npc's immune to fire
            {
                hitInfo.damageTypes = new DamageTypeList();
                return;
            }
        }
        void SaveData() => dataFile.WriteObject(storedData);
        void SubscribeHooks(bool flag) {
            if (flag && init) {
                if (spawnNpcs) {
                    Subscribe(nameof(OnEntitySpawned));
                    Subscribe(nameof(OnPlayerDie));
                }
                if (truePVEAllowPVPAtEvents || truePVEServerWidePVP) {
                    Subscribe(nameof(CanEntityTakeDamage));
                }
                Subscribe(nameof(CanBradleyApcTarget));
                Subscribe(nameof(OnNpcPlayerTarget));
                Subscribe(nameof(OnEntityTakeDamage));
                Subscribe(nameof(OnItemRemovedFromContainer));
                Subscribe(nameof(OnLootEntity));
                Subscribe(nameof(CanAcceptItem));
                Subscribe(nameof(CanBuild));
            }
            else {
                Unsubscribe(nameof(CanEntityTakeDamage));
                Unsubscribe(nameof(CanBradleyApcTarget));
                Unsubscribe(nameof(OnNpcPlayerTarget));
                Unsubscribe(nameof(OnEntitySpawned));
                Unsubscribe(nameof(OnEntityTakeDamage));
                Unsubscribe(nameof(OnItemRemovedFromContainer));
                Unsubscribe(nameof(OnLootEntity));
                Unsubscribe(nameof(CanAcceptItem));
                Unsubscribe(nameof(CanBuild));
                Unsubscribe(nameof(OnPlayerDie));
            }
        }
        static void CreateRocket(Vector3 rocketPos, Vector3 targetPos, Vector3 offset) {
            if (!useRocketOpener || rocketDef == null) return;
            var rocket = GameManager.server.CreateEntity(rocketResourcePath, rocketPos, new Quaternion(), true) as TimedExplosive;
            if (!rocket) {
                ins.Puts(ins.msg(szInvalidConstant, null, "Rocket Creation"));
                useRocketOpener = false;
                return;
            }
            var projectile = rocket.GetComponent<ServerProjectile>();
            var direction = (targetPos - rocketPos) + offset;
            projectile.gravityModifier = 0f;
            projectile.speed = rocketSpeed;
            projectile.InitializeVelocity(direction);
            rocket.timerAmountMin = 10f;
            rocket.timerAmountMax = 20f;
            //rocket.damageTypes = new List<DamageTypeEntry>(); // no damage
            foreach (var type in rocket.damageTypes) {
                type.amount = rocketDamageAmount;
            }
            rocket.Spawn();
        }
        static List<Vector3> GetRandomPositions(Vector3 destination, float radius, int amount, float y) {
            var positions = new List<Vector3>();
            if (amount <= 0) return positions;
            int retries = 100;
            float space = (radius / amount);
            // space each rocket out from one another
            for (int i = 0; i < amount; i++) {
                var position = destination + UnityEngine.Random.insideUnitSphere * radius;
                position.y = y != 0f ? y : UnityEngine.Random.Range(100f, 200f);
                var match = positions.FirstOrDefault(p => Vector3.Distance(p, position) < space);
                if (match != Vector3.zero) {
                    if (--retries < 0) break;
                    i--;
                    continue;
                }
                retries = 100;
                positions.Add(position);
            }
            return positions;
        }
        public Vector3 GetEventPosition() {
            if (sd_customPos != Vector3.zero) return sd_customPos;
            var eventPos = Vector3.zero;
            int maxRetries = 100;
            if (allowMonumentChance > 0f && UnityEngine.Random.Range(0.1f, 1.0f) >= allowMonumentChance) {
                return GetMonumentDropPosition();
            }
            if (onlyMonuments) {
                return GetMonumentDropPosition();
            }
            do {
                eventPos = GetSafeDropPosition(RandomDropPosition());
                if (eventPos == Vector3.zero) continue;
                if (Interface.CallHook("OnDangerousOpen", eventPos) != null) {
                    eventPos = Vector3.zero;
                    continue;
                }
                if (treasureChests.Values.Any(x => Vector3.Distance(x.containerPos, eventPos) < eventRadius)) {
                    eventPos = Vector3.zero;
                    continue;
                }
// ... [Code preview truncated due to length. Full source in attached file] ...

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