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

FREE BoobyTraps : 0.2.18 0.2.18

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using UnityEngine;
using System.Linq;
using Network;
using Rust;
namespace Oxide.Plugins {
    [Info("BoobyTraps", "k1lly0u", "0.2.18")]
    [Description("Booby trap boxes and doors with a variety of traps")]
    class BoobyTraps : RustPlugin {
#region Fields
        [PluginReference]
        Plugin Clans, Friends;
        private DynamicConfigFile datafile;
        private bool initialized;
        private List<ZoneList> m_RadiationZones;
        private List<Timer> m_TrapTimers;
        private Dictionary<ulong, TrapInfo> m_CurrentTraps;
        private const string GRENADE_FX = "assets/prefabs/weapons/f1 grenade/effects/bounce.prefab";
        private const string EXPLOSIVE_FX = "assets/prefabs/locks/keypad/effects/lock.code.denied.prefab";
        private const string BEANCAN_FX = "assets/prefabs/weapons/beancan grenade/effects/bounce.prefab";
        private const string RADIATION_FX = "assets/prefabs/weapons/beancan grenade/effects/beancan_grenade_explosion.prefab";
        private const string LANDMINE_FX = "assets/bundled/prefabs/fx/weapons/landmine/landmine_trigger.prefab";
        private const string BEARTRAP_FX = "assets/bundled/prefabs/fx/beartrap/arm.prefab";
        private const string SHOCK_FX = "assets/prefabs/locks/keypad/effects/lock.code.shock.prefab";
        private const string LANDMINE_PREFAB = "assets/prefabs/deployable/landmine/landmine.prefab";
        private const string BEARTRAP_PREFAB = "assets/prefabs/deployable/bear trap/beartrap.prefab";
        private const string EXPLOSIVE_PREFAB = "assets/prefabs/tools/c4/explosive.timed.deployed.prefab";
        private const string BEANCAN_PREFAB = "assets/prefabs/weapons/beancan grenade/grenade.beancan.deployed.prefab";
        private const string GRENADE_PREFAB = "assets/prefabs/weapons/f1 grenade/grenade.f1.deployed.prefab";
        private const string FIRE_PREFAB = "assets/bundled/prefabs/oilfireballsmall.prefab";
        private const string EXPLOSIVE_PERMISSION = "boobytraps.explosives";
        private const string DEPLOY_PERMISSION = "boobytraps.deployables";
        private const string ELEMENT_PERMISSION = "boobytraps.elements";
        private const string ADMIN_PERMISSION = "boobytraps.admin";
        private const int PLAYER_MASK = 131072;
#endregion
#region Oxide Hooks
        private void Loaded() {
            permission.RegisterPermission(EXPLOSIVE_PERMISSION, this);
            permission.RegisterPermission(DEPLOY_PERMISSION, this);
            permission.RegisterPermission(ELEMENT_PERMISSION, this);
            permission.RegisterPermission(ADMIN_PERMISSION, this);
            LoadData();
            m_RadiationZones = new List<ZoneList>();
            m_TrapTimers = new List<Timer>();
        }
        private void OnServerInitialized() {
            if (!ConVar.Server.radiation) {
                configData.TrapTypes[Traps.Radiation].Enabled = false;
                SaveConfig();
            }
            RemoveInvalidTrapData();
            initialized = true;
        }
        protected override void LoadDefaultMessages() => lang.RegisterMessages(Messages, this);
        private void Unload() {
            for (int i = 0; i < m_RadiationZones.Count; i++) m_RadiationZones[i].Destroy();
            m_RadiationZones.Clear();
            foreach (Timer trapTimer in m_TrapTimers) trapTimer.Destroy();
            SaveData();
        }
        private void OnEntitySpawned(BaseEntity entity) {
            if (!initialized || !entity || entity.IsDestroyed) return;
            if (entity is SupplyDrop) {
                if (configData.AutotrapSettings.UseAirdrops) ProcessEntity(entity, configData.AutotrapSettings.AirdropChance);
            }
            else if (entity is LootContainer) {
                if (configData.AutotrapSettings.UseLootContainers) ProcessEntity(entity, configData.AutotrapSettings.LootContainerChance);
            }
        }
        private void OnLootEntity(BasePlayer inventory, BaseEntity target) {
            if (!target || target.IsDestroyed) return;
            TryActivateTrap(target.net.ID, inventory);
        }
        private void OnEntityTakeDamage(BaseCombatEntity target, HitInfo info) {
            if (!target || target.IsDestroyed || info == null) return;
            TryActivateTrap(target.net.ID, info.InitiatorPlayer);
        }
        private void OnEntityDeath(BaseCombatEntity target, HitInfo info) {
            if (!target || target.IsDestroyed || info == null) return;
            TryActivateTrap(target.net.ID, info.InitiatorPlayer);
        }
        private void CanUseDoor(BasePlayer player, BaseLock locks) {
            BaseEntity target = locks.GetParentEntity();
            if (!target || target.IsDestroyed) return;
            TryActivateTrap(target.net.ID, player);
        }
        private void OnDoorOpened(Door target, BasePlayer player) {
            if (!target || target.IsDestroyed) return;
            TryActivateTrap(target.net.ID, player);
        }
        private void OnDoorClosed(Door target, BasePlayer player) {
            if (!target || target.IsDestroyed) return;
            TryActivateTrap(target.net.ID, player);
        }
        private void OnEntityKill(BaseNetworkable entity) {
            if (!entity || entity.IsDestroyed) return;
            if (m_CurrentTraps.ContainsKey(entity.net.ID.Value)) m_CurrentTraps.Remove(entity.net.ID.Value);
        }
#endregion
#region Functions
        private void RemoveInvalidTrapData() {
            List<ulong> list = Facepunch.Pool.GetList<ulong>();
            list.AddRange(m_CurrentTraps.Keys);
            list.ForEach((id) => {
                if (BaseNetworkable.serverEntities.All(networkable => networkable.net.ID.Value != id)) m_CurrentTraps.Remove(id);
            }
            );
            Facepunch.Pool.FreeList(ref list);
        }
        private void ProcessEntity(BaseEntity entity, int chance) {
            if (!SetRandom(chance)) return;
            Traps trap = configData.TrapTypes.Where(x => x.Value.Enabled).ToList().GetRandom().Key;
            SetTrap(entity, trap, string.Empty);
            if (configData.Options.NotifyRandomSetTraps) Puts($"Random trap has been set at {entity.transform.position} using trap {trap}");
        }
        private void SetTrap(BaseEntity entity, Traps trap, string owner) => m_CurrentTraps[entity.net.ID.Value] = new TrapInfo(trap, entity.transform.position, owner, !string.IsNullOrEmpty(owner));
        private bool TryPurchaseTrap(BasePlayer player, Traps trap) {
            if (configData.Options.OverrideCostsForAdmins && HasPermission(player.UserIDString, ADMIN_PERMISSION)) return true;
            List<TrapCostEntry> costs = configData.TrapTypes[trap].Costs;
            Dictionary<int, int> itemToTake = new Dictionary<int, int>();
            for (int i = 0; i < costs.Count; i++) {
                TrapCostEntry trapCostEntry = costs[i];
                ItemDefinition itemDefinition;
                if (!ItemManager.itemDictionaryByName.TryGetValue(trapCostEntry.Shortname, out itemDefinition)) {
                    PrintError($"Error finding a item with the shortname \"{trapCostEntry.Shortname}\".Please fix this mistake in your BoobyTrap config!");
                    continue;
                }
                if (!HasEnoughRes(player, itemDefinition.itemid, trapCostEntry.Amount)) {
                    SendReply(player, Message("insufficientResources", player.UserIDString));
                    return false;
                }
                itemToTake[itemDefinition.itemid] = trapCostEntry.Amount;
            }
            foreach (KeyValuePair<int, int> item in itemToTake) TakeResources(player, item.Key, item.Value);
            return true;
        }
        private void TryActivateTrap(NetworkableId networkableId, BasePlayer player = null) {
            if (!IsBoobyTrapped(networkableId)) return;
            TrapInfo info = m_CurrentTraps[networkableId.Value];
            if (player != null) {
                if (configData.Options.IgnoreTriggerForTrapOwner) {
                    if (info.trapOwner == player.UserIDString) return;
                }
                if (configData.Options.IgnoreTriggerForFriendsOfTrapOwner) {
                    if (AreFriends(info.trapOwner, player.UserIDString) || IsClanmate(info.trapOwner, player.UserIDString)) return;
                }
            }
            string warningFX = string.Empty;
            string prefab = string.Empty;
            Vector3 location = info.location;
            TrapEntry trapEntry = configData.TrapTypes[info.trapType];
            float fuse = trapEntry.FuseTimer;
            float amount = trapEntry.DamageAmount;
            float radius = trapEntry.Radius;
            bool spawnPrefab = false;
            bool radiusSpawn = false;
            bool isRadiation = false;
            bool isFire = false;
            switch (info.trapType) {
                case Traps.BeancanGrenade : warningFX = BEANCAN_FX;
                prefab = BEANCAN_PREFAB;
                spawnPrefab = true;
                break;
                case Traps.Grenade : warningFX = GRENADE_FX;
                prefab = GRENADE_PREFAB;
                spawnPrefab = true;
                break;
                case Traps.Explosive : warningFX = EXPLOSIVE_FX;
                prefab = EXPLOSIVE_PREFAB;
                spawnPrefab = true;
                break;
                case Traps.Landmine : warningFX = LANDMINE_FX;
                prefab = LANDMINE_PREFAB;
                amount = configData.TrapTypes[Traps.Landmine].Costs[0].Amount;
                radiusSpawn = true;
                break;
                case Traps.Beartrap : warningFX = BEANCAN_FX;
                prefab = BEARTRAP_PREFAB;
                amount = configData.TrapTypes[Traps.Beartrap].Costs[0].Amount;
                radiusSpawn = true;
                break;
                case Traps.Radiation : warningFX = EXPLOSIVE_FX;
                prefab = RADIATION_FX;
                isRadiation = true;
                break;
                case Traps.Fire : warningFX = BEANCAN_FX;
                prefab = FIRE_PREFAB;
                isFire = true;
                break;
                case Traps.Shock : warningFX = EXPLOSIVE_FX;
                prefab = SHOCK_FX;
                break;
            }
            m_CurrentTraps.Remove(networkableId.Value);
            if (configData.Options.PlayTrapWarningSoundFX) Effect.server.Run(warningFX, location);
            if (spawnPrefab) {
                BaseEntity entity = GameManager.server.CreateEntity(prefab, location, new Quaternion(), true);
                TimedExplosive timedExplosive = entity.GetComponent<TimedExplosive>();
                entity.Spawn();
                if (timedExplosive != null) {
                    timedExplosive.SetFuse(fuse);
                    timedExplosive.explosionRadius = radius;
                    timedExplosive.damageTypes = new List<DamageTypeEntry> {
                        new DamageTypeEntry {
                            amount = amount, type = DamageType.Explosion
                        }
                    }
                    ;
                }
            }
            else {
                m_TrapTimers.Add(timer.In(fuse, () => {
                    if (radiusSpawn) {
                        float angle = 360 / amount;
                        for (int i = 0; i < amount; i++) {
                            float ang = i * angle;
                            Vector3 position = GetPositionOnCircle(location, ang, radius);
                            BaseEntity entity = GameManager.server.CreateEntity(prefab, position, new Quaternion(), true);
                            entity.Spawn();
                        }
                    }
                    else if (isFire) {
                        BaseEntity entity = GameManager.server.CreateEntity(prefab, location, new Quaternion(), true);
                        entity.Spawn();
                    }
                    else if (isRadiation) {
                        Effect.server.Run(prefab, location);
                        InitializeZone(location, configData.TrapTypes[Traps.Radiation].DamageAmount, configData.TrapTypes[Traps.Radiation].Duration, configData.TrapTypes[Traps.Radiation].Radius);
                    }
                    else {
                        Effect.server.Run(prefab, location);
                        List<BasePlayer> nearbyPlayers = new List<BasePlayer>();
                        Vis.Entities(location, radius, nearbyPlayers);
                        foreach (BasePlayer nearPlayer in nearbyPlayers) nearPlayer.Hurt(amount, DamageType.ElectricShock, null, true);
                    }
                }
                ));
            }
            if (configData.Options.NotifyPlayersWhenTrapTriggered && player != null) m_TrapTimers.Add(timer.In(fuse, () => SendReply(player, string.Format(Message("triggered", player.UserIDString), info.trapType))));
        }
        private Vector3 GetPositionOnCircle(Vector3 pos, float ang, float radius) {
            Vector3 randPos;
            randPos.x = pos.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
            randPos.z = pos.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
            randPos.y = pos.y;
            Vector3 targetPos = GetGroundPosition(randPos);
            return targetPos;
        }
        private Vector3 GetGroundPosition(Vector3 sourcePos) {
            RaycastHit hitInfo;
            if (Physics.Raycast(sourcePos, Vector3.down, out hitInfo, LayerMask.GetMask("Terrain", "World", "Construction"))) sourcePos.y = hitInfo.point.y;
            sourcePos.y = Mathf.Max(sourcePos.y, TerrainMeta.HeightMap.GetHeight(sourcePos));
            return sourcePos;
        }
        private BaseEntity FindValidEntity(BasePlayer player, bool set) {
            BaseEntity entity = FindEntity(player);
            if (entity == null) {
                SendReply(player, Message("invalidEntity", player.UserIDString));
                return null;
            }
            if (configData.Options.RequireBuildingPrivToTrap) {
                if (player.GetBuildingPrivilege() == null || !player.CanBuild()) {
                    SendReply(player, Message("noPrivilege", player.UserIDString));
                    return null;
                }
            }
            if (configData.Options.RequireOwnershipToTrap) {
                if (entity.OwnerID != player.userID) {
                    SendReply(player, Message("notOwner", player.UserIDString));
                    return null;
                }
            }
            if (set && m_CurrentTraps.ContainsKey(entity.net.ID.Value)) {
                SendReply(player, Message("hasTrap", player.UserIDString));
                return null;
            }
            return entity;
        }
        private BaseEntity FindEntity(BasePlayer player) {
            Vector3 currentRot = Quaternion.Euler(player.serverInput.current.aimAngles) * Vector3.forward;
            Vector3 eyesAdjust = new Vector3(0f, 1.5f, 0f);
            object rayResult = CastRay(player.transform.position + eyesAdjust, currentRot);
            if (rayResult is BaseEntity) {
                BaseEntity entity = rayResult as BaseEntity;
                if (entity.GetComponent<SupplyDrop>()) {
                    if (!configData.Options.CanTrapSupplyDrops) return null;
                }
                else if (entity.GetComponent<LootContainer>()) {
                    if (!configData.Options.CanTrapLoot) return null;
                }
                else if (entity.GetComponent<StorageContainer>()) {
                    if (!configData.Options.CanTrapBoxes) return null;
                }
                else if (entity.GetComponent<Door>()) {
                    if (!configData.Options.CanTrapDoors) return null;
                }
                return entity;
            }
            return null;
        }
        private object CastRay(Vector3 Pos, Vector3 Aim) {
            RaycastHit[] hits = Physics.RaycastAll(Pos, Aim);
            float distance = 100;
            object target = null;
            for (int i = 0; i < hits.Length; i++) {
                RaycastHit hit = hits[i];
                if (hit.collider.GetComponentInParent<BaseEntity>() != null) {
                    if (hit.distance < distance) {
                        distance = hit.distance;
                        target = hit.collider.GetComponentInParent<BaseEntity>();
                    }
                }
            }
            return target;
        }
        private void SendEchoConsole(Network.Connection cn, string msg) {
            if (Net.sv.IsConnected()) {
                NetWrite netWrite = Net.sv.StartWrite();
                netWrite.PacketID(Network.Message.Type.ConsoleMessage);
                netWrite.String(msg);
                netWrite.Send(new SendInfo(cn));
            }
        }
#endregion
#region Helpers
        private bool HasPermission(string userId, string perm) => permission.UserHasPermission(userId, perm);
        private bool HasAnyPerm(string userId) => (HasPermission(userId, EXPLOSIVE_PERMISSION) || HasPermission(userId, DEPLOY_PERMISSION) || HasPermission(userId, ELEMENT_PERMISSION) || HasPermission(userId, ADMIN_PERMISSION));
        private bool IsBoobyTrapped(NetworkableId networkableId) => m_CurrentTraps.ContainsKey(networkableId.Value);
        private void RemoveTrap(NetworkableId networkableId) => m_CurrentTraps.Remove(networkableId.Value);
        private bool HasEnoughRes(BasePlayer player, int itemid, int amount) => player.inventory.GetAmount(itemid) >= amount;
        private void TakeResources(BasePlayer player, int itemid, int amount) => player.inventory.Take(null, itemid, amount);
        private double GrabCurrentTime() => DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
        private int GetRandom(int chance) => UnityEngine.Random.Range(1, chance);
        private bool SetRandom(int chance) => GetRandom(chance) == 1;
#endregion
#region Radiation
        private void InitializeZone(Vector3 Location, float intensity, float duration, float radius) {
            RadiationZone radiationZone = new GameObject().AddComponent<RadiationZone>();
            radiationZone.Activate(Location, radius, intensity);
            ZoneList listEntry = new ZoneList {
                zone = radiationZone
            }
            ;
            listEntry.time = timer.Once(duration, () => DestroyZone(listEntry));
            m_RadiationZones.Add(listEntry);
        }
        private void DestroyZone(ZoneList zone) {
            if (m_RadiationZones.Contains(zone)) {
                int index = m_RadiationZones.FindIndex(a => a.zone == zone.zone);
                m_RadiationZones[index].time.Destroy();
                UnityEngine.Object.Destroy(m_RadiationZones[index].zone.gameObject);
                m_RadiationZones.Remove(zone);
            }
        }
        public class ZoneList {
            public RadiationZone zone;
            public Timer time;
            public void Destroy() {
                time.Destroy();
                UnityEngine.Object.Destroy(zone.gameObject);
            }
        }
        public class RadiationZone : MonoBehaviour {
            private void Awake() {
                gameObject.layer = (int)Layer.Reserved1;
                gameObject.name = "Radiation Zone";
            }
            public void Activate(Vector3 pos, float radius, float amount) {
                transform.position = pos;
                SphereCollider sphereCollider = gameObject.GetComponent<SphereCollider>() ?? gameObject.AddComponent<SphereCollider>();
                sphereCollider.isTrigger = true;
                sphereCollider.radius = radius;
                TriggerRadiation triggerRadiation = gameObject.GetComponent<TriggerRadiation>() ?? gameObject.AddComponent<TriggerRadiation>();
                triggerRadiation.RadiationAmountOverride = amount;
                triggerRadiation.interestLayers = PLAYER_MASK;
                triggerRadiation.enabled = true;
                gameObject.SetActive(true);
                enabled = true;
            }
        }
#endregion
#region Commands
        [ChatCommand("trap")]
        private void cmdTrap(BasePlayer player, string command, string[] args) {
            if (!HasAnyPerm(player.UserIDString)) return;
            if (args.Length == 0) {
                SendReply(player, string.Format(Message("help1", player.UserIDString), Title, Version, configData.Options.CanTrapDoors, configData.Options.CanTrapBoxes, configData.Options.CanTrapLoot, configData.Options.CanTrapSupplyDrops));
                SendReply(player, Message("help2", player.UserIDString));
                Dictionary<Traps, TrapEntry> types = configData.TrapTypes;
                if (HasPermission(player.UserIDString, ADMIN_PERMISSION)) {
                    SendReply(player, Message("help3", player.UserIDString));
                    SendReply(player, Message("help4", player.UserIDString));
                }
                else {
                    List<string> trapTypes = new List<string>();
                    if (HasPermission(player.UserIDString, EXPLOSIVE_PERMISSION)) {
                        if (types[Traps.BeancanGrenade].Enabled && !types[Traps.BeancanGrenade].AdminOnly) trapTypes.Add("Beancan");
                        if (types[Traps.Grenade].Enabled && !types[Traps.Grenade].AdminOnly) trapTypes.Add("Grenade");
                        if (types[Traps.Explosive].Enabled && !types[Traps.BeancanGrenade].AdminOnly) trapTypes.Add("Explosive");
                    }
                    if (HasPermission(player.UserIDString, DEPLOY_PERMISSION)) {
                        if (types[Traps.Landmine].Enabled && !types[Traps.Landmine].AdminOnly) trapTypes.Add("Landmine");
                        if (types[Traps.Beartrap].Enabled && !types[Traps.Beartrap].AdminOnly) trapTypes.Add("Beartrap");
                    }
                    if (HasPermission(player.UserIDString, ELEMENT_PERMISSION)) {
                        if (types[Traps.Radiation].Enabled && !types[Traps.Radiation].AdminOnly && ConVar.Server.radiation) trapTypes.Add("Radiation");
                        if (types[Traps.Fire].Enabled && !types[Traps.Fire].AdminOnly) trapTypes.Add("Fire");
                        if (types[Traps.Shock].Enabled && !types[Traps.Shock].AdminOnly) trapTypes.Add("Shock");
                    }
                    SendReply(player, $"{Message("help5", player.UserIDString)} <color=#939393>{trapTypes.ToSentence()}</color>");
                }
                return;
            }
            switch (args[0].ToLower()) {
                case "cost" : if (args.Length > 1) {
                    Traps trap;
                    switch (args[1].ToLower()) {
                        case "beancan" : {
                            if (!HasPermission(player.UserIDString, EXPLOSIVE_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.BeancanGrenade;
                            break;
                        }
                        case "grenade" : {
                            if (!HasPermission(player.UserIDString, EXPLOSIVE_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Grenade;
                            break;
                        }
                        case "explosive" : {
                            if (!HasPermission(player.UserIDString, EXPLOSIVE_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Explosive;
                            break;
                        }
                        case "landmine" : {
                            if (!HasPermission(player.UserIDString, DEPLOY_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Landmine;
                            break;
                        }
                        case "beartrap" : {
                            if (!HasPermission(player.UserIDString, DEPLOY_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Beartrap;
                            break;
                        }
                        case "radiation" : {
                            if (!ConVar.Server.radiation || (!HasPermission(player.UserIDString, ELEMENT_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION))) return;
                            trap = Traps.Radiation;
                            break;
                        }
                        case "fire" : {
                            if (!HasPermission(player.UserIDString, ELEMENT_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Fire;
                            break;
                        }
                        case "shock" : {
                            if (!HasPermission(player.UserIDString, ELEMENT_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Shock;
                            break;
                        }
                        default : SendReply(player, Message("invalidTrap", player.UserIDString));
                        return;
                    }
                    if (!configData.TrapTypes[trap].Enabled || (configData.TrapTypes[trap].AdminOnly && !HasPermission(player.UserIDString, ADMIN_PERMISSION))) {
                        SendReply(player, Message("notEnabled", player.UserIDString));
                        return;
                    }
                    string costs = string.Format(Message("getCosts", player.UserIDString), trap);
                    for (int i = 0; i < configData.TrapTypes[trap].Costs.Count; i++) {
                        TrapCostEntry trapCostEntry = configData.TrapTypes[trap].Costs[i];
                        ItemDefinition itemDefinition;
                        if (!ItemManager.itemDictionaryByName.TryGetValue(trapCostEntry.Shortname, out itemDefinition)) {
                            PrintError($"Error finding a item with the shortname \"{trapCostEntry.Shortname}\".Please fix this mistake in your BoobyTrap config!");
                            continue;
                        }
                        costs += $"\n<color=#00CC00>{trapCostEntry.Amount}</color> <color=#939393>x</color> <color=#00CC00>{itemDefinition.displayName.translated}</color>";
                    }
                    SendReply(player, costs);
                }
                return;
                case "set" : if (args.Length > 1) {
                    BaseEntity entity = FindValidEntity(player, true);
                    if (entity == null) return;
                    Traps trap;
                    switch (args[1].ToLower()) {
                        case "beancan" : {
                            if (!HasPermission(player.UserIDString, EXPLOSIVE_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.BeancanGrenade;
                            break;
                        }
                        case "grenade" : {
                            if (!HasPermission(player.UserIDString, EXPLOSIVE_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Grenade;
                            break;
                        }
                        case "explosive" : {
                            if (!HasPermission(player.UserIDString, EXPLOSIVE_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Explosive;
                            break;
                        }
                        case "landmine" : {
                            if (!HasPermission(player.UserIDString, DEPLOY_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Landmine;
                            break;
                        }
                        case "beartrap" : {
                            if (!HasPermission(player.UserIDString, DEPLOY_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Beartrap;
                            break;
                        }
                        case "radiation" : {
                            if (!HasPermission(player.UserIDString, ELEMENT_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Radiation;
                            break;
                        }
                        case "fire" : {
                            if (!HasPermission(player.UserIDString, ELEMENT_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Fire;
                            break;
                        }
                        case "shock" : {
                            if (!HasPermission(player.UserIDString, ELEMENT_PERMISSION) && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) return;
                            trap = Traps.Shock;
                            break;
                        }
                        default : SendReply(player, Message("invalidTrap", player.UserIDString));
                        return;
                    }
                    if (!configData.TrapTypes[trap].Enabled || (configData.TrapTypes[trap].AdminOnly && !HasPermission(player.UserIDString, ADMIN_PERMISSION))) {
                        SendReply(player, Message("notEnabled", player.UserIDString));
                        return;
                    }
                    if (TryPurchaseTrap(player, trap)) {
                        SetTrap(entity, trap, player.UserIDString);
                        SendReply(player, string.Format(Message("trapSet", player.UserIDString), trap));
                    }
                }
                return;
                case "remove" : {
                    BaseEntity entity = FindValidEntity(player, false);
                    if (entity == null) return;
                    if (configData.Options.RequireOwnershipToTrap && (entity.OwnerID != 0U && entity.OwnerID != player.userID)) {
                        SendReply(player, Message("notOwner", player.UserIDString));
                        return;
                    }
                    if (!m_CurrentTraps.ContainsKey(entity.net.ID.Value)) {
                        SendReply(player, Message("noTrap", player.UserIDString));
                        return;
                    }
                    else {
                        m_CurrentTraps.Remove(entity.net.ID.Value);
                        SendReply(player, Message("removeSuccess", player.UserIDString));
                        return;
                    }
                }
                case "check" : {
                    BaseEntity entity = FindValidEntity(player, false);
                    if (entity == null) return;
                    if (configData.Options.RequireOwnershipToTrap && (entity.OwnerID != 0U && entity.OwnerID != player.userID)) {
                        SendReply(player, Message("notOwner", player.UserIDString));
                        return;
                    }
                    if (!m_CurrentTraps.ContainsKey(entity.net.ID.Value)) {
                        SendReply(player, Message("noTrap", player.UserIDString));
                        return;
                    }
                    else {
                        TrapInfo info = m_CurrentTraps[entity.net.ID.Value];
                        SendReply(player, string.Format(Message("trapInfo", player.UserIDString), info.trapType));
                        return;
                    }
                }
                case "removeall" : {
                    if (!player.IsAdmin && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) {
                        SendReply(player, Message("noPerm", player.UserIDString));
                        return;
                    }
                    m_CurrentTraps.Clear();
                    SendReply(player, Message("removedAll", player.UserIDString));
                    return;
                }
                case "list" : {
                    if (!player.IsAdmin && !HasPermission(player.UserIDString, ADMIN_PERMISSION)) {
                        SendReply(player, Message("noPerm", player.UserIDString));
                        return;
                    }
                    SendEchoConsole(player.net.connection, string.Format(Message("currentTraps", player.UserIDString), m_CurrentTraps.Count));
                    Puts(string.Format(Message("currentTraps", player.UserIDString), m_CurrentTraps.Count));
                    foreach(var trap in m_CurrentTraps) {
                        string trapInfo = string.Format("{0} - {1} - {2}", trap.Key, trap.Value.trapType, trap.Value.location);
                        SendEchoConsole(player.net.connection, trapInfo);
                        Puts(trapInfo);
                    }
                    return;
                }
            }
        }
        [ConsoleCommand("trap")]
        private void ccmdTrap(ConsoleSystem.Arg arg) {
            if (arg.Connection != null) return;
            if (arg.Args == null || arg.Args.Length == 0) {
                SendReply(arg, $"-- {Title}  v{Version} --");
                SendReply(arg, Message("conHelp"));
                return;
            }
            switch (arg.Args[0].ToLower()) {
                case "removeall" : m_CurrentTraps.Clear();
                SendReply(arg, Message("removedAll"));
                return;
                case "list" : Puts(string.Format(Message("currentTraps"), m_CurrentTraps.Count));
                foreach (KeyValuePair<ulong, TrapInfo> trap in m_CurrentTraps) {
                    string trapInfo = string.Format("{0} - {1} - {2}", trap.Key, trap.Value.trapType, trap.Value.location);
                    Puts(trapInfo);
                }
                return;
                default : return;
            }
        }
#endregion
#region Friends
        private bool AreFriends(string playerId, string friendId) {
            if (Friends) return (bool)Friends?.Call("AreFriends", playerId, friendId);
            return true;
        }
        private bool IsClanmate(string playerId, string friendId) {
            if (Clans) {
                object playerTag = Clans?.Call("GetClanOf", playerId);
                object friendTag = Clans?.Call("GetClanOf", friendId);
                if (playerTag is string && friendTag is string) {
                    if (!string.IsNullOrEmpty((string)playerTag) && !string.IsNullOrEmpty((string)friendTag) && (playerTag == friendTag)) return true;
                }
                return false;
            }
            return true;
        }
#endregion
#region Config
        private ConfigData configData;
        private class TrapCostEntry {
            public string Shortname {
                get;
                set;
            }
            public int Amount {
                get;
                set;
            }
        }
        private class TrapEntry {
            public bool Enabled {
                get;
                set;
            }
            public bool AdminOnly {
                get;
                set;
            }
            public float DamageAmount {
                get;
                set;
            }
            public float Radius {
                get;
                set;
            }
            public float FuseTimer {
                get;
                set;
            }
            public float Duration {
                get;
                set;
            }
            public List<TrapCostEntry> Costs {
                get;
                set;
            }
        }
        private class Autotraps {
            public bool UseAirdrops {
                get;
                set;
            }
            public bool UseLootContainers {
                get;
                set;
            }
            public int AirdropChance {
                get;
                set;
            }
            public int LootContainerChance {
                get;
                set;
            }
        }
        private class Options {
            public bool NotifyRandomSetTraps {
                get;
                set;
            }
            public bool NotifyPlayersWhenTrapTriggered {
                get;
                set;
            }
            public bool PlayTrapWarningSoundFX {
                get;
                set;
            }
            public bool CanTrapBoxes {
                get;
                set;
            }
            public bool CanTrapLoot {
                get;
                set;
            }
            public bool CanTrapSupplyDrops {
                get;
                set;
            }
            public bool CanTrapDoors {
                get;
                set;
            }
            public bool RequireOwnershipToTrap {
                get;
                set;
            }
            public bool RequireBuildingPrivToTrap {
                get;
                set;
            }
            public bool IgnoreTriggerForTrapOwner {
                get;
                set;
            }
            public bool IgnoreTriggerForFriendsOfTrapOwner {
                get;
                set;
            }
            public bool OverrideCostsForAdmins {
                get;
                set;
            }
        }
        private class ConfigData {
            public Autotraps AutotrapSettings {
                get;
                set;
            }
            public Dictionary<Traps, TrapEntry> TrapTypes {
                get;
                set;
            }
            public Options Options {
                get;
                set;
            }
            public Oxide.Core.VersionNumber Version {
                get;
                set;
            }
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            configData = Config.ReadObject<ConfigData>();
            if (configData.Version < Version) UpdateConfigValues();
            Config.WriteObject(configData, true);
        }
        protected override void LoadDefaultConfig() => configData = GetBaseConfig();
        private ConfigData GetBaseConfig() {
            return new ConfigData {
                AutotrapSettings = new Autotraps {
                    AirdropChance = 40, LootContainerChance = 40, UseAirdrops = true, UseLootContainers = true
                }
                , Options = new Options {
                    NotifyRandomSetTraps = true, NotifyPlayersWhenTrapTriggered = true, PlayTrapWarningSoundFX = true, CanTrapBoxes = true, CanTrapDoors = true, CanTrapLoot = false, CanTrapSupplyDrops = false, OverrideCostsForAdmins = true, RequireBuildingPrivToTrap = true, RequireOwnershipToTrap = true, IgnoreTriggerForTrapOwner = false, IgnoreTriggerForFriendsOfTrapOwner = false,
                }
                , TrapTypes = new Dictionary<Traps, TrapEntry> {
                    {
                        Traps.BeancanGrenade, new TrapEntry {
                            AdminOnly = false, Costs = new List<TrapCostEntry> {
                                new TrapCostEntry {
                                    Shortname = "grenade.beancan", Amount = 2
                                }
                            }
                            , DamageAmount = 30, Radius = 4, FuseTimer = 2, Enabled = true
                        }
                    }
                    , {
                        Traps.Beartrap, new TrapEntry {
                            AdminOnly = false, Costs = new List<TrapCostEntry> {
                                new TrapCostEntry {
                                    Shortname = "trap.bear", Amount = 10
                                }
                            }
                            , DamageAmount = 0, Radius = 2, FuseTimer = 2, Enabled = true
                        }
                    }
                    , {
                        Traps.Explosive, new TrapEntry {
                            AdminOnly = false, Costs = new List<TrapCostEntry> {
                                new TrapCostEntry {
                                    Shortname = "explosive.timed", Amount = 2
                                }
                            }
                            , DamageAmount = 110, Radius = 10, FuseTimer = 3, Enabled = true
                        }
                    }
                    , {
                        Traps.Fire, new TrapEntry {
                            AdminOnly = false, Costs = new List<TrapCostEntry> {
                                new TrapCostEntry {
                                    Shortname = "lowgradefuel", Amount = 50
                                }
                            }
                            , DamageAmount = 1, Radius = 2, FuseTimer = 3, Enabled = true
                        }
                    }
                    , {
                        Traps.Grenade, new TrapEntry {
                            AdminOnly = false, Costs = new List<TrapCostEntry> {
                                new TrapCostEntry {
                                    Shortname = "grenade.f1", Amount = 2
                                }
                            }
                            , DamageAmount = 75, Radius = 5, FuseTimer = 3, Enabled = true
                        }
                    }
                    , {
                        Traps.Landmine, new TrapEntry {
                            AdminOnly = false, Costs = new List<TrapCostEntry> {
                                new TrapCostEntry {
                                    Shortname = "trap.landmine", Amount = 10
                                }
                            }
                            , DamageAmount = 0, Radius = 2, FuseTimer = 2, Enabled = true
                        }
                    }
                    , {
                        Traps.Radiation, new TrapEntry {
                            AdminOnly = true, Costs = new List<TrapCostEntry>(), DamageAmount = 20, Radius = 10, FuseTimer = 3, Duration = 20, Enabled = true
                        }
                    }
                    , {
                        Traps.Shock, new TrapEntry {
                            AdminOnly = true, Costs = new List<TrapCostEntry>(), DamageAmount = 95, Radius = 2, FuseTimer = 2, Enabled = true
                        }
                    }
                }
                , Version = Version
            }
            ;
        }
        protected override void SaveConfig() => Config.WriteObject(configData, true);
        private void UpdateConfigValues() {
            PrintWarning("Config update detected! Updating config values...");
            configData.Version = Version;
            PrintWarning("Config update completed!");
        }
#endregion
#region Data Management
        enum Traps {
            BeancanGrenade, Grenade, Explosive, Landmine, Beartrap, Radiation, Fire, Shock
        }
        private class TrapInfo {
            public Traps trapType;
            public Vector3 location;
            public string trapOwner;
            public bool saveTrap;
            public TrapInfo() {
            }
            public TrapInfo(Traps trapType, Vector3 location, string trapOwner, bool saveTrap) {
                this.trapType = trapType;
                this.location = location;
                this.trapOwner = trapOwner;
                this.saveTrap = saveTrap;
            }
        }
        private void SaveData() => datafile.WriteObject(m_CurrentTraps);
        private void LoadData() {
            datafile = Interface.Oxide.DataFileSystem.GetFile("boobytrap_data");
            datafile.Settings.Converters = new JsonConverter[] {
                new StringEnumConverter(), new UnityVector3Converter()
            }
            ;
            m_CurrentTraps = datafile.ReadObject<Dictionary<ulong, TrapInfo>>() ?? new Dictionary<ulong, TrapInfo>();
            foreach (ulong key in m_CurrentTraps.Where(x => !x.Value.saveTrap).Select(x => x.Key)) m_CurrentTraps.Remove(key);
        }
        private class UnityVector3Converter : JsonConverter {
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
                Vector3 vector = (Vector3)value;
                writer.WriteValue($"{vector.x} {vector.y} {vector.z}");
            }
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
                if (reader.TokenType == JsonToken.String) {
                    string[] values = reader.Value.ToString().Trim().Split(' ');
                    return new Vector3(Convert.ToSingle(values[0]), Convert.ToSingle(values[1]), Convert.ToSingle(values[2]));
                }
                JObject o = JObject.Load(reader);
                return new Vector3(Convert.ToSingle(o["x"]), Convert.ToSingle(o["y"]), Convert.ToSingle(o["z"]));
            }
            public override bool CanConvert(Type objectType) {
                return objectType == typeof(Vector3);
            }
        }
#endregion
#region Messaging
        private string Message(string key, string playerid = null) => lang.GetMessage(key, this, playerid);
        private Dictionary<string, string> Messages = new Dictionary<string, string>() {
            ["insufficientResources"]
            = "<color=#939393>You have insufficient resources to purchase this trap!</color>" , ["triggered"] = "<color=#939393>You just triggered a </color><color=#00CC00>{0}</color> <color=#939393>trap!</color>" , ["invalidEntity"] = "<color=#939393>You are not looking at a valid trap-able entity!</color>", ["noPrivilege"] = "<color=#939393>You must have building privilege to place/remove a trap!</color>" , ["notOwner"] = "<color=#939393>You must own the entity you wish to place/remove a trap on!</color>", ["hasTrap"] = "<color=#939393>This entity already has a trap placed on it!</color>", ["help1"] = "<color=#00CC00>-- {0}  v{1} --</color>\n<color=#939393>With this plugin you can set traps on a variety of objects.\nDoors : {2}\nStorage Containers : {3}\nLoot Containers : {4}\nSup
// ... [Code preview truncated due to length. Full source in attached file] ...

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