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

FREE DangerousTreasures : 1.1.4 1.1.4

Нет прав для скачивания
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;
namespace Oxide.Plugins {
    [Info("Dangerous Treasures", "nivex", "1.1.4", ResourceId = 2479)]
    [Description("Event with treasure chests.")]
    public class DangerousTreasures : RustPlugin {
        [PluginReference]
        Plugin LustyMap, ZoneManager, Economics, ServerRewards, Map, GUIAnnouncements;
        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 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");
        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
        }
        ;
        List<Vector3> monuments = new List<Vector3>();
        // positions of monuments on the server
        static List<uint> newmanProtections = new List<uint>();
        static List<FireBall> spawnedFireballs = new List<FireBall>();
        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> treasureLooters = new Dictionary<uint, string>();
        static Dictionary<uint, List<NPCPlayer>> npcs = new Dictionary<uint, List<NPCPlayer>>();
        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 : MonoBehaviour {
            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<BaseEntity>();
                    var colliders = Pool.GetList<Collider>();
                    Vis.Colliders(launchPos, eventRadius + missileDetectionDistance, colliders, playerMask, QueryTriggerInteraction.Collide);
                    foreach (var collider in colliders) {
                        var player = collider.GetComponentInParent<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<Collider>(ref colliders);
                    if (list.Count > 0) {
                        SetTarget(list.GetRandom());
                        // pick a random player
                        list.Clear();
                    }
                    else if (!targetChest) {
                        missile.Kill();
                        return;
                    }
                    projectile.speed = rocketSpeed * rocketSpeedMulti;
                    InvokeHandler.InvokeRepeating(this, 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 || !missile || missile.IsDestroyed) return;
                if (target.IsDestroyed) {
                    if (missile != null && !missile.IsDestroyed) missile.Kill();
                    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();
                InvokeHandler.CancelInvoke(this, GuideMissile);
                GameObject.Destroy(this);
            }
        }
        class TreasureChest : MonoBehaviour {
            public StorageContainer container;
            public bool started = false;
            long _unlockTime;
            bool lerped = false;
            public Vector3 containerPos;
            uint uid;
            int countdownTime;
            float posMulti = 3f;
            float sphereMulti = 2f;
            float claimTime;
            float lastStayTick;
            Vector3 lastFirePos;
            Dictionary<ulong, long> fireticks = new Dictionary<ulong, long>();
            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;
            void Awake() {
                container = GetComponent<StorageContainer>();
                containerPos = container.transform.position;
                uid = container.net.ID;
                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;
                lastStayTick = Time.time;
                if (useSpheres && amountOfSpheres > 0) {
                    for (int i = 0; i < amountOfSpheres; i++) {
                        if (!useSpheres) break;
                        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;
                            lerped = true;
                            // bug fix for prefab being invalid, otherwise event will not continue
                        }
                    }
                    if (useSpheres) InvokeHandler.InvokeRepeating(this, LerpUpdate, 0.1f, 0.1f);
                }
                else lerped = true;
                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) InvokeHandler.InvokeRepeating(this, SpawnFire, 0.1f, secondsBeforeTick);
                }
                if (launchMissiles) {
                    missilePositions = GetRandomPositions(containerPos, eventRadius, 25, 1);
                    if (missilePositions.Count > 0) {
                        InvokeHandler.InvokeRepeating(this, LaunchMissile, 0.1f, missileFrequency);
                        LaunchMissile();
                    }
                }
            }
            void LerpUpdate() {
                foreach (var sphere in spheres) {
                    if (sphere != null && sphere.currentRadius == sphere.lerpRadius) {
                        InvokeHandler.CancelInvoke(this, LerpUpdate);
                        lerped = true;
                        break;
                    }
                }
            }
            void OnTriggerEnter(Collider col) {
                if (started) return;
                var player = col.GetComponentInParent<BasePlayer>();
                if (!player || player is NPCPlayer || players.Contains(player.userID)) return;
                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) return;
                if (protects.Contains(player.net.ID)) {
                    if (newmanProtections.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 || !lerped || Time.time - lastStayTick < 0.1f) return;
                lastStayTick = 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);
                        if (newmanProtections.Contains(player.net.ID)) newmanProtections.Remove(player.net.ID);
                        if (protects.Contains(player.net.ID)) protects.Remove(player.net.ID);
                    }
                }
                if (!useFireballs) return;
                var stamp = TimeStamp();
                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 entry in npcs.ToList()) {
                    if (entry.Key == uid) {
                        foreach (var npc in entry.Value.ToList()) {
                            if (npc != null && !npc.IsDestroyed) {
                                npc.Kill();
                            }
                        }
                        npcs.Remove(entry.Key);
                    }
                }
            }
            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;
                }
                if (!lerped) 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);
                foreach (var entry in missiles.ToList()) if (entry == null || entry.IsDestroyed) missiles.Remove(entry);
                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 || !lerped) return;
                if (fireballs.Count >= 6)  // limit fireballs
                {
                    foreach (var entry in fireballs) {
                        if (entry != null && !entry.IsDestroyed) entry.Kill();
                        fireballs.Remove(entry);
                        if (spawnedFireballs.Contains(entry)) spawnedFireballs.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;
                    if (firePositions.Count > 0) {
                        InvokeHandler.CancelInvoke(this, SpawnFire);
                        firePositions.Clear();
                    }
                    return;
                }
                fireball.Spawn();
                fireballs.Add(fireball);
            }
            public void Destruct() {
                unlock?.Destroy();
                destruct?.Destroy();
                if (container != null) {
                    container.inventory?.Clear();
                    if (!container.IsDestroyed) container.Kill();
                }
            }
            void Unclaimed() {
                if (!started) return;
                float time = claimTime - TimeStamp();
                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 long UnlockTime {
                get {
                    return this._unlockTime;
                }
            }
            public void SetUnlockTime(float time) {
                var posStr = FormatGridReference(containerPos);
                countdownTime = Convert.ToInt32(time);
                _unlockTime = Convert.ToInt64(TimeStamp() + 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 = TimeStamp() + 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) {
                    InvokeHandler.CancelInvoke(this, 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) {
                    InvokeHandler.CancelInvoke(this, SpawnFire);
                    firePositions.Clear();
                }
                if (useFireballs) {
                    foreach (var fireball in fireballs) {
                        if (fireball != null && !fireball.IsDestroyed) fireball.Kill();
                        if (spawnedFireballs.Contains(fireball)) spawnedFireballs.Remove(fireball);
                    }
                    fireballs.Clear();
                }
                foreach (var protect in protects) if (newmanProtections.Contains(protect)) newmanProtections.Remove(protect);
                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(Title.Replace(" ", ""));
            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 - TimeStamp() > 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();
            }
            if (useRocketOpener) {
                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: ", string.Join(", ", managedZones.Select(zone => string.Format("{0} ({1}m)", FormatGridReference(zone.Key), zone.Value)).ToArray()));
            }
            monuments = UnityEngine.Object.FindObjectsOfType<MonumentInfo>().Select(monument => monument.transform.position).ToList();
            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 (spawnedFireballs.Count > 0) {
                foreach (var entry in spawnedFireballs) if (entry != null && !entry.IsDestroyed) entry.Kill();
                spawnedFireballs.Clear();
            }
            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();
        }
        private object OnNpcPlayerTarget(NPCPlayerApex npc, BaseEntity entity) {
            if (entity is BasePlayer) {
                var player = entity as BasePlayer;
                if (player.net != null && newmanProtections.Contains(player.net.ID)) {
                    return 0f;
                }
            }
            return null;
        }
        void OnPlayerDie(BasePlayer player) {
            var npc = player as NPCPlayer;
            if (npc == null || !npcs.Any(entry => entry.Value.Contains(npc))) return;
            player.svActiveItemID = 0;
            player.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
        }
        void OnEntitySpawned(BaseNetworkable entity) {
            if (!init || entity == null || (!(entity is FireBall)) && !(entity is BaseLock) && !(entity is NPCPlayerCorpse)) return;
            if (entity is NPCPlayerCorpse) {
                if (spawnsDespawnInventory) {
                    var corpse = entity as NPCPlayerCorpse;
                    foreach (var entry in npcs) {
                        foreach (var npc in entry.Value) {
                            if (npc.userID == corpse.playerSteamID) {
                                NextTick(() => {
                                    corpse.containers[0].Clear();
                                    corpse.containers[1].Clear();
                                    corpse.containers[2].Clear();
                                }
                                );
                                break;
                            }
                        }
                    }
                }
                return;
            }
            NextTick(() => {
                if (entity == null || entity.transform == null) return;
                foreach (var entry in treasureChests) {
                    if (Vector3.Distance(entity.transform.position, entry.Value.containerPos) <= eventRadius + 25f)  // some extra distance for fireballs that travel outside the sphere, usually on hills
                    {
                        if (entity is FireBall) {
                            var fireball = entity as FireBall;
                            ModifyFireball(fireball);
                        }
                        else if (entity is BaseLock || entity is CodeLock) {
                            entity.KillMessage();
                        }
                        break;
                    }
                }
            }
            );
        }
        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 (treasureLooters.ContainsKey(entity.net.ID)) treasureLooters.Remove(entity.net.ID);
            treasureLooters.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 (treasureLooters.ContainsKey(box.net.ID)) treasureLooters.Remove(box.net.ID);
                    treasureLooters.Add(box.net.ID, looter.UserIDString);
                }
                if (box.inventory.itemList.Count == 0) {
                    if (looter == null && treasureLooters.ContainsKey(box.net.ID)) looter = BasePlayer.activePlayerList.Find(x => x.UserIDString == treasureLooters[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);
                }
            }
            );
        }
        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));
                    }
                }
                hitInfo?.damageTypes?.ScaleAll(0f);
            }
        }
        void SaveData() {
            if (storedData != null) {
                dataFile.WriteObject(storedData);
            }
        }
        void SubscribeHooks(bool flag) {
            if (flag) {
                if (init) {
                    if (useFireballs || spawnNpcs) {
                        Subscribe(nameof(OnEntitySpawned));
                        Subscribe(nameof(OnPlayerDie));
                    }
                    Subscribe(nameof(OnEntityTakeDamage));
                    Subscribe(nameof(OnItemRemovedFromContainer));
                    Subscribe(nameof(OnLootEntity));
                    Subscribe(nameof(CanAcceptItem));
                    Subscribe(nameof(CanBuild));
                }
            }
            else {
                Unsubscribe(nameof(OnEntitySpawned));
                Unsubscribe(nameof(OnEntityTakeDamage));
                Unsubscribe(nameof(OnItemRemovedFromContainer));
                Unsubscribe(nameof(OnLootEntity));
                Unsubscribe(nameof(CanAcceptItem));
                Unsubscribe(nameof(CanBuild));
                Unsubscribe(nameof(OnPlayerDie));
            }
        }
        static void ModifyFireball(FireBall fireball) {
            fireball.enableSaving = false;
            if (BaseEntity.saveList.Contains(fireball)) 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();
            spawnedFireballs.Add(fireball);
            float lifeTime = UnityEngine.Random.Range(fbLifeTimeMin, fbLifeTimeMax);
            ins.timer.Once(lifeTime, () => fireball?.Extinguish());
        }
        static void CreateRocket(Vector3 rocketPos, Vector3 targetPos, Vector3 offset) {
            if (!useRocketOpener || rocketDef == null) return;
            var rocket = GameManager.server.CreateEntity(rocketDef.GetComponent<ItemModProjectile>().projectileObject.resourcePath, 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;
            do {
                eventPos = GetSafeDropPosition(RandomDropPosition());
                if (Interface.CallHook("OnDangerousOpen", eventPos) != null) {
                    eventPos = Vector3.zero;
                    continue;
                }
                if (managedZones.Count > 0) {
                    foreach (var zone in managedZones) {
                        if (Vector3.Distance(zone.Key, eventPos) <= zone.Value) {
                            eventPos = Vector3.zero;
                            // blocked by zone manager
                            break;
                        }
                    }
                }
                foreach (var monument in monuments) {
                    if (Vector3.Distance(eventPos, monument) < 150f)  // don't put the treasure chest near a monument
                    {
                        eventPos = Vector3.zero;
                        break;
                    }
                }
            }
            while (eventPos == Vector3.zero && --maxRetries > 0);
            return eventPos;
        }
        public Vector3 GetSafeDropPosition(Vector3 position) {
            RaycastHit hit;
            position.y += 200f;
            if (Physics.Raycast(position, Vector3.down, out hit)) {
                if (hit.collider?.gameObject == null) return Vector3.zero;
                if (!BlockedLayers.Contains(hit.collider.gameObject.layer)) {
                    position.y = Mathf.Max(hit.point.y, TerrainMeta.HeightMap.GetHeight(position));
                    var colliders = Pool.GetList<Collider>();
                    Vis.Colliders(position, eventRadius, colliders, blockedMask, QueryTriggerInteraction.Collide);
                    bool blocked = colliders.Count > 0;
                    Pool.FreeList<Collider>(ref colliders);
                    if (!blocked) return position;
                }
            }
            return Vector3.zero;
        }
        public Vector3 RandomDropPosition()  // CargoPlane.RandomDropPosition()
        {
            var vector = Vector3.zero;
            float num = 100f, x = TerrainMeta.Size.x / 3f;
            do {
                vector = Vector3Ex.Range(-x, x);
            }
            while (filter.GetFactor(vector) == 0f && (num -= 1f) > 0f);
            vector.y = 0f;
            return vector;
        }
        static long TimeStamp() => (DateTime.Now.Ticks - DateTime.Parse("01/01/1970 00:00:00").Ticks) / 10000000;
        void GetWorkshopIDs(int code, string response) {
            if (response != null && code == 200) {
                var items = JsonConvert.DeserializeObject<Rust.Workshop.ItemSchema>(response).items;
                foreach (var item in items) {
                    if (string.IsNullOrEmpty(item.itemshortname) || string.IsNullOrEmpty(item.workshopdownload)) continue;
                    if (!workshopskinsCache.ContainsKey(item.itemshortname)) workshopskinsCache.Add(item.itemshortname, new List<ulong>());
                    workshopskinsCache[item.itemshortname].Add(Convert.ToUInt64(item.workshopdownload));
                }
            }
        }
        List<ulong> GetItemSkins(ItemDefinition def) {
            if (!skinsCache.ContainsKey(def.shortname)) {
                var skins = new List<ulong>();
                skins.AddRange(def.skins.Select(skin => Convert.ToUInt64(skin.id)));
                if ((def.shortname == boxShortname && includeWorkshopBox) || (def.shortname != boxShortname && includeWorkshopTreasure)) {
                    if (workshopskinsCache.ContainsKey(def.shortname)) {
                        skins.AddRange(workshopskinsCache[def.shortname]);
                        workshopskinsCache.Remove(def.shortname);
                    }
                }
                if (skins.Cont
// ... [Code preview truncated due to length. Full source in attached file] ...

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