C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using ConVar;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using UnityEngine;
using VLB;
using Object = System.Object;
using Physics = UnityEngine.Physics;
using Random = System.Random;
using Time = UnityEngine.Time;
using Pool = Facepunch.Pool;
namespace Oxide.Plugins {
[Info("IQDefenderSupply", "Mercury", "1.9.15")]
[Description("IQDefenderSupply")]
public class IQDefenderSupply : RustPlugin {
/// <summary>
/// - Теперь для каждого дропа на карте будет свое название в зависимости от уровня сложности
/// - Скорректирована очистка локальных хранилищ
/// - Исправлен конфликт с PVEMode (Calling hook CanEntityTakeDamage resulted in a conflict between the following plugins: IQDefenderSupply - True (Boolean), PveMode (False (Boolean)))
/// - Исправлено когда нет сохраненных позиций - команда не позволяла вызвать защищенный груз на игрока
/// - Добавлена поддержка GoldCard (разработчик должен обновить свой плагин)
/// </summary>
private const Boolean LanguageEn = false;
#region Reference
[PluginReference]
Plugin IQChat, IQDronePatrol, IQGuardianDrone, NpcSpawn, IQTurret, PveMode, LootDefender, TruePVE;
#region Removed
private Object canRemove(BasePlayer player, BaseEntity entity) {
if (entity.OwnerID == ownerIDElemnts) return false;
return null;
}
#endregion
#region IQChat
public void SendChat(String Message, BasePlayer player, ConVar.Chat.ChatChannel channel = ConVar.Chat.ChatChannel.Global) {
if (IQChat) IQChat?.Call("API_ALERT_PLAYER", player, Message, config.generalSetting.alertSetting.iqchatSetting.customPrefix, config.generalSetting.alertSetting.iqchatSetting.customAvatar);
else player.SendConsoleCommand("chat.add", channel, 0, Message);
}
#endregion
#region IQDronePatrol
private Boolean IsDronePatrol(UInt64 ownerID) {
if (!IQDronePatrol) return false;
return IQDronePatrol.Call<Boolean>("IsValidTurret", ownerID);
}
private class CustomPatrol {
public String pluginName;
public Vector3 position;
public PositionSetting settingPosition = new();
public DroneSetting settingDrone = new();
internal class DroneSetting {
public Int32 droneCountSpawned;
public Int32 droneAttackedCount;
public Dictionary<String, Int32> keyDrones = new();
}
internal class PositionSetting {
public Int32 countSpawnPoint;
public Int32 radiusFindedPoints;
}
}
#endregion
#region Pve
private void PveModeRemoveZone(UInt64 netID) {
if (!PveMode) return;
if (!config.otherPlugins.pveMode.usePveMode) return;
PveMode.Call("EventRemovePveMode", $"IQDefenderSupply_Drop_{netID}", true);
}
private void PveModeAddedZone(SupplyDrop supplyDrop) {
if (!PveMode) return;
if (!config.otherPlugins.pveMode.usePveMode) return;
if (!supplyDrop) return;
Configuration.OtherPlugins.PveModePlugin pveModeConfiguration = config.otherPlugins.pveMode;
Dictionary<String, Object> configPve = new() {
["Damage"]
= pveModeConfiguration.Damage, ["ScaleDamage"] = pveModeConfiguration.ScaleDamage.ToDictionary(x => x.Type, v => v.Scale), ["LootCrate"] = pveModeConfiguration.LootCrate, ["HackCrate"] = true, ["LootNpc"] = pveModeConfiguration.LootNpc, ["DamageNpc"] = pveModeConfiguration.DamageNpc, ["DamageTank"] = true, ["DamageHelicopter"] = true, ["DamageTurret"] = true, ["TargetNpc"] = pveModeConfiguration.TargetNpc, ["TargetTank"] = true, ["TargetHelicopter"] = true, ["TargetTurret"] = true, ["CanEnter"] = pveModeConfiguration.CanEnter, ["CanEnterCooldownPlayer"] = pveModeConfiguration.CanEnterCooldownPlayer, ["TimeExitOwner"] = pveModeConfiguration.TimeExitOwner, ["AlertTime"] = pveModeConfiguration.AlertTime, ["RestoreUponDeath"] = pveModeConfiguration.RestoreUponDeath, ["CooldownOwner"] = pveModeConfiguration.CooldownOwner, ["Darkening"] = pveModeConfiguration.Darkening
}
;
HashSet<UInt64> npcIdSet = new();
if (npcDefendersDrops.TryGetValue(supplyDrop, out Dictionary<ScientistNPC, String> npcs)) {
foreach (ScientistNPC npc in npcs.Keys) npcIdSet.Add(npc.net.ID.Value);
}
HashSet<UInt64> turretsID = new();
if (turretsDefenderDrops.TryGetValue(supplyDrop, out List<AutoTurret> turrets)) {
foreach (AutoTurret turret in turrets) npcIdSet.Add(turret.net.ID.Value);
}
PveMode.CallHook("EventAddPveMode", $"IQDefenderSupply_Drop_{supplyDrop.net.ID.Value}", configPve, supplyDrop.transform.position, pveModeConfiguration.radiusPveZone, new HashSet<UInt64> {
supplyDrop.net.ID.Value
}
, npcIdSet, new HashSet<UInt64>(), new HashSet<UInt64>(), turretsID, new HashSet<UInt64>(), null);
}
#endregion
#endregion
#region Vars
private static IQDefenderSupply _;
private const UInt64 ownerIDElemnts = 3746538364;
private const UInt64 skinIDElement = 3352994990;
private const Single checkDirectionsDistance = 5;
// Расстояние для проверки вокруг точки
private const String explosionPrefab = "assets/bundled/prefabs/fx/explosions/explosion_01.prefab";
private const String engineStopperPrefab = "assets/prefabs/weapons/military flamethrower/militaryflamethrower.entity.prefab";
private const String supplyDropPrefab = "assets/prefabs/misc/supply drop/supply_drop.prefab";
private const String simpleLightPrefab = "assets/prefabs/deployable/playerioents/lights/simplelight.prefab";
private const String sirenLightPrefab = "assets/prefabs/deployable/playerioents/lights/sirenlight/electric.sirenlight.deployed.prefab";
private const String shutterMetalEmbrasurePrefab = "assets/prefabs/building/wall.window.embrasure/shutter.metal.embrasure.a.prefab";
private const String windowWallPrefab = "assets/prefabs/building/wall.window.bars/wall.window.bars.toptier.prefab";
private const String prisonWallPrefab = "assets/prefabs/building/wall.frame.cell/wall.frame.cell.prefab";
private const String prisonFloorPrefab = "assets/prefabs/building/floor.grill/floor.grill.prefab";
private const String prisonDoorPrefab = "assets/prefabs/building/wall.frame.cell/wall.frame.cell.gate.prefab";
private const String cardReaderPrefab = "assets/prefabs/io/electric/switches/cardreader.prefab";
private const String sphereVisualPrefab = "assets/prefabs/visualization/sphere.prefab";
private const String turretPrefab = "assets/prefabs/npc/autoturret/autoturret_deployed.prefab";
private const String cargoPlanePrefab = "assets/prefabs/npc/cargo plane/cargo_plane.prefab";
private const String markerPrefab = "assets/prefabs/tools/map/genericradiusmarker.prefab";
private const String invisibleVendingPrefab = "assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab";
public Dictionary<TypeLevels, String> namingMappingMarker = new() {
[TypeLevels.Level0]
= "LITE DEFENDER SUPPLY", [TypeLevels.Level1] = "MIDDLE DEFENDER SUPPLY", [TypeLevels.Level2] = "HARD DEFENDER SUPPLY",
}
;
public enum TypeLevels {
Level0, Level1, Level2,
}
private enum TypeActionDiscord {
CargoSpawned, SupplyDropped, SupplyDestroyed, SupplyOpened
}
private Coroutine routineGeneratedPosition;
private Timer timerController;
private Dictionary<String, Vector3> allMonuments = new Dictionary<String, Vector3>();
private Dictionary<SupplyDrop, Vector3> droneActivePosition = new();
private Dictionary<SupplyDrop, Dictionary<ScientistNPC, String>> npcDefendersDrops = new ();
private Dictionary<SupplyDrop, List<AutoTurret>> turretsDefenderDrops = new ();
private List<SupplyDrop> listDestroyedSupplyInvoke = new ();
private Dictionary<CargoPlane, CargoPlaneRepository> activeCargoPlane = new();
private List<LangingController> langingComponents = new ();
private Dictionary<SupplyDrop, ActiveDropRepository> levelsDropActive = new();
private Dictionary<SupplyDrop, BaseEntity> alarmDrops = new ();
private Dictionary<CardReader, List<BaseEntity>> readerManipulator = new();
private Dictionary<SupplyDrop, MarkerRepository> mapMarkers = new ();
private class ActiveDropRepository {
public List<BaseEntity> entitiesList = new();
public TypeLevels levelSupply;
}
private class CargoPlaneRepository {
public String presetKey;
public Vector3 dropPosition;
}
private readonly Dictionary<TypeLevels, Dictionary<String, PositionEntity>> positionCashed = new() {
[TypeLevels.Level0]
= new Dictionary<String, PositionEntity> {
[engineStopperPrefab]
= new PositionEntity {
entityPosList = new List<PositionEntity.EntityPos>() {
new PositionEntity.EntityPos {
localPosition = new Vector3(-0.9f, 0.18f, 1f), localQuaternion = Quaternion.Euler(-10f, 0f, 90f),
}
, new PositionEntity.EntityPos {
localPosition = new Vector3(-0.9f, 0.18f, -1f), localQuaternion = Quaternion.Euler(-4f, 0f, 90f),
}
, new PositionEntity.EntityPos {
localPosition = new Vector3(0.9f, 0.18f, 1f), localQuaternion = Quaternion.Euler(-10f, 0f, 90f),
}
, new PositionEntity.EntityPos {
localPosition = new Vector3(0.9f, 0.18f, -1f), localQuaternion = Quaternion.Euler(-4f, 0f, 90f),
}
,
}
, spherePos = new PositionEntity.SpherePos {
sizeSphere = 1f, position = new Vector3(0f, 0.9f, 0f),
}
}
, [turretPrefab] = new PositionEntity {
entityPosList = new List<PositionEntity.EntityPos>() {
new PositionEntity.EntityPos {
localPosition = new Vector3(0f, 0.4f, 0f), localQuaternion = default,
}
}
, spherePos = new PositionEntity.SpherePos() {
sizeSphere = 1.7f, position = new Vector3(0f, 0.8f, 0f),
}
}
, [shutterMetalEmbrasurePrefab] = new PositionEntity {
spherePos = new PositionEntity.SpherePos() {
sizeSphere = 0.8f, position = new Vector3(0f, 0.8f, 0f),
}
, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(-1.67f, 0.1f, 0f), localQuaternion = Quaternion.Euler(0, 0, -4),
}
, new() {
localPosition = new Vector3(1.27f, 0.1f, 0f), localQuaternion = Quaternion.Euler(0, 0, 4),
}
, new() {
localPosition = new Vector3(0f, 0.1f, -1.37f), localQuaternion = Quaternion.Euler(0, 90, 4),
}
, new() {
localPosition = new Vector3(0f, 0.1f, 1.67f), localQuaternion = Quaternion.Euler(0, 90, -4),
}
, new() {
localPosition = new Vector3(-1.67f, 1.9f, 0f), localQuaternion = Quaternion.Euler(0, 0, -4),
}
, new() {
localPosition = new Vector3(1.27f, 1.9f, 0f), localQuaternion = Quaternion.Euler(0, 0, 4),
}
, new() {
localPosition = new Vector3(0f, 1.9f, -1.37f), localQuaternion = Quaternion.Euler(0, 90, 4),
}
, new() {
localPosition = new Vector3(0f, 1.9f, 1.67f), localQuaternion = Quaternion.Euler(0, 90, -4),
}
,
}
,
}
}
, [TypeLevels.Level1] = new Dictionary<String, PositionEntity> {
[engineStopperPrefab]
= new PositionEntity {
entityPosList = new List<PositionEntity.EntityPos>() {
new PositionEntity.EntityPos {
localPosition = new Vector3(-0.9f, 0.18f, 1f), localQuaternion = Quaternion.Euler(-10f, 0f, 90f),
}
, new PositionEntity.EntityPos {
localPosition = new Vector3(-0.9f, 0.18f, -1f), localQuaternion = Quaternion.Euler(-4f, 0f, 90f),
}
, new PositionEntity.EntityPos {
localPosition = new Vector3(0.9f, 0.18f, 1f), localQuaternion = Quaternion.Euler(-10f, 0f, 90f),
}
, new PositionEntity.EntityPos {
localPosition = new Vector3(0.9f, 0.18f, -1f), localQuaternion = Quaternion.Euler(-4f, 0f, 90f),
}
,
}
, spherePos = new PositionEntity.SpherePos {
sizeSphere = 1f, position = new Vector3(0f, 0.9f, 0f),
}
}
, [prisonWallPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(1.3f, 0f, 0f), localQuaternion = Quaternion.Euler(0, 0, 0),
}
, new() {
localPosition = new Vector3(0f, 0f, -1.3f), localQuaternion = Quaternion.Euler(0, 90, 0),
}
, new() {
localPosition = new Vector3(0f, 0f, 1.3f), localQuaternion = Quaternion.Euler(0, 90, 0),
}
,
}
,
}
, [prisonFloorPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(0f, 0f, 0f), localQuaternion = Quaternion.Euler(0, 0, 0),
}
, new() {
localPosition = new Vector3(0f, 2.8f, 0f), localQuaternion = Quaternion.Euler(0, 0, 0),
}
,
}
,
}
, [prisonDoorPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(-1.3f, 0f, 0f), localQuaternion = Quaternion.Euler(0, 0, 0),
}
,
}
,
}
, [cardReaderPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(-0.13f, 0.08f, -1.1f), localQuaternion = Quaternion.Euler(0, -90, 0),
}
,
}
,
}
, [simpleLightPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(0f, 2.85f, 0f), localQuaternion = Quaternion.Euler(0, 90, 0),
}
, new() {
localPosition = new Vector3(0f, 2.85f, 0f), localQuaternion = Quaternion.Euler(0, -90, 0),
}
,
}
,
}
,
}
, [TypeLevels.Level2] = new Dictionary<String, PositionEntity> {
[engineStopperPrefab]
= new PositionEntity {
entityPosList = new List<PositionEntity.EntityPos>() {
new PositionEntity.EntityPos {
localPosition = new Vector3(-0.9f, 0.18f, 1f), localQuaternion = Quaternion.Euler(-10f, 0f, 90f),
}
, new PositionEntity.EntityPos {
localPosition = new Vector3(-0.9f, 0.18f, -1f), localQuaternion = Quaternion.Euler(-4f, 0f, 90f),
}
, new PositionEntity.EntityPos {
localPosition = new Vector3(0.9f, 0.18f, 1f), localQuaternion = Quaternion.Euler(-10f, 0f, 90f),
}
, new PositionEntity.EntityPos {
localPosition = new Vector3(0.9f, 0.18f, -1f), localQuaternion = Quaternion.Euler(-4f, 0f, 90f),
}
,
}
, spherePos = new PositionEntity.SpherePos {
sizeSphere = 1f, position = new Vector3(0f, 0.9f, 0f),
}
}
, [prisonWallPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(1.3f, 0f, 0f), localQuaternion = Quaternion.Euler(0, 0, 0),
}
, new() {
localPosition = new Vector3(0f, 0f, -1.3f), localQuaternion = Quaternion.Euler(0, 90, 0),
}
, new() {
localPosition = new Vector3(0f, 0f, 1.3f), localQuaternion = Quaternion.Euler(0, 90, 0),
}
,
}
,
}
, [prisonFloorPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(0f, 0f, 0f), localQuaternion = Quaternion.Euler(0, 0, 0),
}
, new() {
localPosition = new Vector3(0f, 2.8f, 0f), localQuaternion = Quaternion.Euler(0, 0, 0),
}
,
}
,
}
, [windowWallPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(1.3f, 2.75f, 0f), localQuaternion = Quaternion.Euler(0, 0, -90),
}
, new() {
localPosition = new Vector3(-1.3f, 2.75f, 0f), localQuaternion = Quaternion.Euler(180, 0, 90),
}
,
}
,
}
, [prisonDoorPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(-1.3f, 0f, 0f), localQuaternion = Quaternion.Euler(0, 0, 0),
}
,
}
,
}
, [cardReaderPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(-0.13f, 0.08f, -1.1f), localQuaternion = Quaternion.Euler(0, -90, 0),
}
,
}
,
}
, [simpleLightPrefab] = new PositionEntity {
spherePos = null, entityPosList = new List<PositionEntity.EntityPos>() {
new() {
localPosition = new Vector3(0f, 0.65f, 1f), localQuaternion = Quaternion.Euler(0, 0, 90),
}
, new() {
localPosition = new Vector3(0f, 0.65f, -1f), localQuaternion = Quaternion.Euler(180, 0, 90),
}
, new() {
localPosition = new Vector3(0f, 0.65f, 1f), localQuaternion = Quaternion.Euler(0, 0, 90),
}
, new() {
localPosition = new Vector3(0f, 0.65f, -1f), localQuaternion = Quaternion.Euler(-180, 0, 90),
}
,
}
,
}
, [turretPrefab] = new PositionEntity {
entityPosList = new List<PositionEntity.EntityPos>() {
new PositionEntity.EntityPos {
localPosition = new Vector3(0f, -0.2f, 0f), localQuaternion = Quaternion.Euler(0, 0, 90),
}
, new PositionEntity.EntityPos {
localPosition = new Vector3(0f, -0.2f, 0f), localQuaternion = Quaternion.Euler(0, 0, 90),
}
}
, spherePos = new PositionEntity.SpherePos() {
sizeSphere = 1.3f, position = new Vector3(0f, 0.8f, 0f),
}
}
,
}
,
}
;
private class MarkerRepository {
public VendingMachineMapMarker vending;
public MapMarkerGenericRadius marker;
}
public class PositionEntity {
public List<EntityPos> entityPosList = new List<EntityPos>();
public SpherePos spherePos = new SpherePos();
public class SpherePos {
public Single sizeSphere;
public Vector3 position;
}
public class EntityPos {
public Vector3 localPosition;
public Quaternion localQuaternion;
}
}
#endregion
#region Configuration
private static Configuration config = new Configuration();
private class Configuration {
[JsonProperty(LanguageEn ? "Auto event settings for protected cargo plane launch" : "Настройка автоматического запуска самолета с защищенным грузом")]
public AutoEvent autoEventSetting = new AutoEvent();
[JsonProperty(LanguageEn ? "Other settings" : "Прочие настройки")]
public GeneralSetting generalSetting = new GeneralSetting();
[JsonProperty(LanguageEn ? "Protected cargo presets settings" : "Настройка пресетов защищенных грузов")]
public Dictionary<String, PresetSupply> presetSupplyDrops = new Dictionary<String, PresetSupply>();
[JsonProperty(LanguageEn ? "Configuring supported plugins" : "Настройка поддерживаемых плагинов")]
public OtherPlugins otherPlugins = new OtherPlugins();
public String GetRandomPreset() {
List<String> randomList = Pool.Get<List<String>>();
String presetKey = String.Empty;
randomList = presetSupplyDrops.Keys.ToList();
presetKey = randomList.GetRandom();
Pool.FreeUnmanaged(ref randomList);
return presetKey;
}
internal class GeneralSetting {
[JsonProperty(LanguageEn ? "Time after which protected cargo will be removed after being fully looted" : "Через сколько будет удален защищенный груз после его полного залутывания")]
public Int32 timeRevomeDropAfterLoot;
[JsonProperty(LanguageEn ? "When will the protected loot be removed if players do not loot it" : "Через сколько будет удален защищенный груз если его не залутали игроки")]
public Int32 timeRevomeDropNoLoot;
[JsonProperty(LanguageEn ? "Notification settings from the plugin" : "Настройка уведомлений от плагина")]
public AlertController alertSetting;
[JsonProperty(LanguageEn ? "Automatically clear custom drop positions on map change/server wipe (true - yes/false - no)" : "Автоматически очищать кастомные позиции для сброса груза при смене карты/очистки сервера (true - да/false - нет)")]
public Boolean clearCustomPositionsWipe;
[JsonProperty(LanguageEn ? "Discord notification settings.[MessageType (CargoSpawned - Plane departure, SupplyDropped - Supply drop, SupplyDestroyed - Supply removed, SupplyOpened - Supply opened)] = Setting" : "Настройка уведомлений в Discord.[ТипСообщения (CargoSpawned - Вылет самолета, SupplyDropped - Сброс груза, SupplyDestroyed - Удаление груза, SupplyOpened - Открытие груза)] = Настройка")]
public Dictionary<TypeActionDiscord, DiscordSettings> typeAlertDiscord = new();
internal class DiscordSettings {
[JsonProperty(LanguageEn ? "WebHook (leave empty to not use this type of notification)" : "WebHook (оставьте пустым чтобы не использовать этот тип уведомления)")]
public String webHooks;
[JsonProperty(LanguageEn ? "Title" : "Заголовок")]
public String title;
[JsonProperty(LanguageEn ? "Description" : "Описание")]
public String description;
[JsonProperty(LanguageEn ? "Color (Embed discord format)" : "Цвет (формат Embed discord)")]
public Int32 color;
[JsonProperty(LanguageEn ? "Footer text" : "Текст в подвале")]
public String footer;
[JsonProperty(LanguageEn ? "Author name" : "Имя автора")]
public String authorName;
[JsonProperty(LanguageEn ? "Author avatar (use direct.png link)" : "Аватар автора (используйте прямую ссылку.png)")]
public String authorAvatar;
[JsonProperty(LanguageEn ? "Thumbnail avatar (use direct.png link)" : "Аватар в оглавлении (используйте прямую ссылку.png)")]
public String thumbnailAvatar;
[JsonProperty(LanguageEn ? "Message above embed (e.g., @everyone)" : "Сообщение над embed (например @everyone)")]
public String content;
public DiscordMessage GetMessageDiscord() {
if (String.IsNullOrWhiteSpace(webHooks)) return null;
DiscordMessage message = new DiscordMessage {
Embeds = new List<Embed> {
new Embed {
Title = title, Description = description, Color = color, Footer = new EmbedFooter {
Text = footer
}
, Author = new EmbedAuthor {
Name = authorName, IconUrl = authorAvatar
}
, Thumbnail = new EmbedThumbnail {
Url = thumbnailAvatar
}
}
}
, Content = content
}
;
return message;
}
}
internal class AlertController {
[JsonProperty(LanguageEn ? "IQChat: Notification format settings" : "IQChat : Настройка формата уведомлений")]
public IQChatSetting iqchatSetting;
[JsonProperty(LanguageEn ? "Use GameTip notification for cargo plane takeoff" : "Использовать уведомление GameTip о вылете самолета с защищенным грузом")]
public Boolean useAlertGameTipStartCargo;
[JsonProperty(LanguageEn ? "Use chat notification for cargo plane takeoff" : "Использовать уведомление в чате о вылете самолета с защищенным грузом")]
public Boolean useAlertChatStartCargo;
[JsonProperty(LanguageEn ? "Use chat notification for dropped protected cargo" : "Использовать уведомление в чате о сброшенном защищенном грузе")]
public Boolean useAlertDropped;
[JsonProperty(LanguageEn ? "Use chat notification when player starts looting protected cargo" : "Использовать уведомление в чате о том что игрок начал лутать защищенный груз")]
public Boolean useAlertLootedDrop;
internal class IQChatSetting {
[JsonProperty(LanguageEn ? "IQChat : Custom prefix in chat" : "IQChat : Кастомный префикс в чате")]
public String customPrefix;
[JsonProperty(LanguageEn ? "IQChat : Custom chat avatar (If required)" : "IQChat : Кастомный аватар в чате(Если требуется)")]
public String customAvatar;
}
}
}
internal class AutoEvent {
[JsonProperty(LanguageEn ? "Use automatic launch of planes with protected cargo (true - yes/false - no)" : "Использовать автоматический запуск самолетов с защищенным грузом (true - да/false - нет)")]
public Boolean useAutoEvent;
[JsonProperty(LanguageEn ? "Preset list settings for automatic launch [Preset] = Chance (From 0 to 100)" : "Настройка списка пресетов для автоматического запуска [Пресет] = Шанс (От 0 до 100)")]
public Dictionary<String, Int32> presetDroppedList = new Dictionary<String, Int32>();
[JsonProperty(LanguageEn ? "How often the protected drop will be launched automatically (specify the time in seconds)" : "Раз в какое время будет запускаться автоматически защищенный дроп (укажите время в секундах)")]
public Int32 timeStarted;
public String GetRandomPreset() {
foreach (KeyValuePair<String, Int32> presetList in presetDroppedList) {
if (_.IsRare(presetList.Value)) return presetList.Key;
}
List<String> randomList = Pool.Get<List<String>>();
String presetKey = String.Empty;
randomList = presetDroppedList.Keys.ToList();
presetKey = randomList.GetRandom();
Pool.FreeUnmanaged(ref randomList);
return presetKey;
}
}
internal class PresetSupply {
[JsonProperty(LanguageEn ? "Drop protection settings" : "Настройка защиты дропа")]
public GeneralDrop generalSetting = new GeneralDrop();
internal class GeneralDrop {
[JsonProperty(LanguageEn ? "Drop protection level: 0 - Easy, 1 - Medium, 2 - Hard" : "Уровень защиты дропа : 0 - Легий, 1 - Средний, 2 - Сложный")]
public TypeLevels defenderLevel;
[JsonProperty(LanguageEn ? "Drop protection settings with access card (for defender levels `Medium` and `Hard`)" : "Настройка защиты дропа картой доступа (для уровней защиты `Средний` и `Сложный`)")]
public CardReaders cardReaderSetting = new CardReaders();
[JsonProperty(LanguageEn ? "G-Map marker display settings" : "Настройка отображения маркеров на G-Map")]
public MapMarkerPreset mapMarkerSetting = new MapMarkerPreset();
[JsonProperty(LanguageEn ? "Additional settings" : "Настройка дополнений")]
public ReferenceAdditional referenceAdditional = new ReferenceAdditional();
internal class MapMarkerPreset {
[JsonProperty(LanguageEn ? "Display marker with protected cargo on the map (true - yes/false - no)" : "Отображать на карте маркер с защищенным грузом (true - да/false - нет)")]
public Boolean useMapMarker;
[JsonProperty(LanguageEn ? "Main marker color" : "Основной цвет маркера")]
public String mainColorMarker;
[JsonProperty(LanguageEn ? "Outline marker color" : "Цвет обводки маркера")]
public String additionalColorMarker;
[JsonProperty(LanguageEn ? "Marker radius on the map" : "Радиус маркера на карте")]
public Single radiusMarker;
}
internal class ReferenceAdditional {
[JsonProperty(LanguageEn ? "IQDronePatrol: Drone protection settings for the drop" : "IQDronePatrol : Настройка дронов для защиты дропа")]
public IQDronePatrol droneSpawnSetting = new IQDronePatrol();
[JsonProperty(LanguageEn ? "NPCSpawn: NPC protection settings for the drop" : "NPCSpawn : Настройка NPC для защиты дропа")]
public NPCSpawn npcSpawnSetting = new NPCSpawn();
internal class IQDronePatrol {
[JsonProperty(LanguageEn ? "Use defender drones in this preset" : "Использовать дронов-защитников в данном пресете")]
public Boolean useDrones;
[JsonProperty(LanguageEn ? "Number of drones spawned to protect the drop" : "Сколько дронов будет спавнится для защиты дропа")]
public AmountSetting countDrone;
[JsonProperty(LanguageEn ? "Number of drones that can attack one player simultaneously" : "Сколько дронов смогут одновремено нападать на одного игрока сразу")]
public Int32 droneAttackedCount;
[JsonProperty(LanguageEn ? "Drone preset settings and selection chance [PresetFromConfig] = Chance" : "Настройка пресетов дронов и шанс на выбор данного пресета [ПресетИзКонфига] = Шанс")]
public Dictionary<String, Int32> keyDrones;
public CustomPatrol GetPresetPatrol(Vector3 position) {
CustomPatrol myPatrol = new CustomPatrol {
pluginName = "IQDefenderSupply", position = position, settingDrone = new CustomPatrol.DroneSetting {
droneCountSpawned = countDrone.GetAmount(), droneAttackedCount = droneAttackedCount, keyDrones = keyDrones,
}
, settingPosition = new CustomPatrol.PositionSetting {
countSpawnPoint = 200, radiusFindedPoints = 40
}
,
}
;
return myPatrol;
}
}
internal class NPCSpawn {
[JsonProperty(LanguageEn ? "Use NPCSpawn in this preset" : "Использовать NPCSpawn в данном пресете")]
public Boolean useNpcSpawn;
[JsonProperty(LanguageEn ? "Number of NPCs to spawn near the drop" : "Сколько NPC будет заспавнено возле дропа")]
public AmountSetting countSpawnNpc;
[JsonProperty(LanguageEn ? "Bot settings" : "Настройка ботов")]
public PresetBot presetBot = new();
internal class PresetBot {
[JsonProperty(LanguageEn ? "Bot health" : "Здоровье ботов")]
public Single health;
[JsonProperty(LanguageEn ? "Damage multiplier" : "Множитель урона")]
public Single damageScale;
[JsonProperty(LanguageEn ? "Aim cone multiplier" : "Множитель разброса")]
public Single aimConeScale;
[JsonProperty(LanguageEn ? "Running speed" : "Скорость бега")]
public Single runningSpeed;
[JsonProperty(LanguageEn ? "NPC clothing" : "Одежда NPC")]
public List<ItemBot> wearNPC = new List<ItemBot>(6);
[JsonProperty(LanguageEn ? "NPC weapon variation" : "Вариация оружия NPC")]
public List<ItemBot> beltNPC = new List<ItemBot>();
[JsonProperty(LanguageEn ? "Drop loot settings from NPC" : "Настройка выпадаемого лута с NPC")]
public PresetsLoot itemDropLootNPC = new PresetsLoot();
internal class ItemBot {
[JsonProperty("Shortname")]
public String shortname;
[JsonProperty("SkinID")]
public UInt64 skinID;
[JsonProperty(LanguageEn ? "Mods weapon" : "Список модов")]
public List<String> mods;
}
public JObject GetJObjectConfigNpc() {
JArray arrayWear = new JArray();
foreach (ItemBot wearItem in wearNPC) arrayWear.Add(new JObject {
["ShortName"]
= wearItem.shortname, ["Amount"] = 1, ["SkinID"] = wearItem.skinID,
}
);
JArray arrayBelt = new JArray();
foreach (ItemBot beltItem in beltNPC) arrayBelt.Add(new JObject {
["ShortName"]
= beltItem.shortname, ["Amount"] = 1, ["SkinID"] = beltItem.skinID, ["Mods"] = new JArray {
beltItem.mods.Select(y => y)
}
}
);
HashSet<String> states = new() {
"RoamState", "ChaseState", "CombatState"
}
;
if (beltNPC.Any(x => x.shortname is "rocket.launcher" or "explosive.timed")) states.Add("RaidState");
JObject configNpc = new JObject() {
["Name"]
= "DEFENDER_SUPPLY_BOT", ["WearItems"] = arrayWear, ["BeltItems"] = arrayBelt, ["Kit"] = "", ["Health"] = health, ["RoamRange"] = 30f, ["ChaseRange"] = 90f, ["DamageScale"] = damageScale, ["TurretDamageScale"] = 1f, ["AreaMask"] = 1, ["AgentTypeID"] = -1372625422, ["HomePosition"] = "", ["AimConeScale"] = aimConeScale, ["States"] = new JArray {
states
}
, ["DisableRadio"] = false, ["Stationary"] = false, ["CanUseWeaponMounted"] = false, ["CanRunAwayWater"] = true, ["Speed"] = runningSpeed, ["AttackRangeMultiplier"] = 2f, ["SenseRange"] = 150f, ["CheckVisionCone"] = false, ["MemoryDuration"] = 300f, ["VisionCone"] = 135f,
}
;
return configNpc;
}
}
}
}
internal class CardReaders {
[JsonProperty(LanguageEn ? "Use access cards for drop (true - yes/false - no)" : "Использовать карты доступы для дропа (true - да/false - нет)")]
public Boolean useCardLevel;
[JsonProperty(LanguageEn ? "Use random access card for drop" : "Использовать случайную карту доступа для дропа")]
public Boolean useRandomCardLevel;
[JsonProperty(LanguageEn ? "Required access card: 1 - Green, 2 - Blue, 3 - Red" : "Требуемая карта доступа : 1 - Зеленая, 2 - Синяя, 3 - Красная")]
public Int32 keyCardLevel;
public Int32 GetCardLevel() => useRandomCardLevel ? Oxide.Core.Random.Range(1, 3) : keyCardLevel;
}
}
[JsonProperty(LanguageEn ? "Turret settings for protected drop" : "Настройка турели на защищенном дропе")]
public TurretSettings turretSetting = new TurretSettings();
[JsonProperty(LanguageEn ? "Custom loot settings in drop" : "Настройка кастомного лута в дропе")]
public PresetsLoot lootSetting = new PresetsLoot();
internal class PresetsLoot {
[JsonProperty(LanguageEn ? "Use custom loot list (true - yes/false - no)" : "Использовать свой список лута (true - да/false - нет)")]
public Boolean useCustomLoot;
[JsonProperty(LanguageEn ? "Maximum loot drops" : "Сколько максимум выпадет лута")]
public Int32 maxCountLoot;
[JsonProperty(LanguageEn ? "List of loot drops" : "Список выпадаемого лута")]
public List<LootSetting> lootList = new List<LootSetting>();
public List<ResultLoot> GetLootList() {
List<ResultLoot> resutlLoot = new List<ResultLoot>();
Random random = new Random();
List<LootSetting> shuffledLootList = lootList.OrderBy(x => random.Next()).ToList();
foreach (LootSetting lootPreset in shuffledLootList) {
if (_.IsRare(lootPreset.rareDrop) && resutlLoot.All(x => x.shortname != lootPreset.shortname)) resutlLoot.Add(new ResultLoot {
shortname = lootPreset.shortname, skinID = lootPreset.skinID, amount = lootPreset.amountController.GetAmount(),
}
);
}
return resutlLoot;
}
internal class ResultLoot {
[JsonIgnore]
public String shortname;
[JsonIgnore]
public UInt64 skinID;
[JsonIgnore]
public Int32 amount;
}
internal class LootSetting {
[JsonProperty(LanguageEn ? "Drop chance" : "Шанс выпадения")]
public Int32 rareDrop;
[JsonProperty("Shortname")]
public String shortname;
[JsonProperty("SkinID")]
public UInt64 skinID;
[JsonProperty(LanguageEn ? "Drop quantity setting" : "Настройка количества выпадения")]
public AmountSetting amountController = new();
}
}
internal class AmountSetting {
[JsonProperty(LanguageEn ? "Minimum quantity" : "Минимальное количество")]
public Int32 minAmount;
[JsonProperty(LanguageEn ? "Maximum quantity" : "Максимальное количество")]
public Int32 maxAmount;
public Int32 GetAmount() => minAmount >= maxAmount ? minAmount : Oxide.Core.Random.Range(minAmount, maxAmount);
}
internal class TurretSettings {
[JsonProperty(LanguageEn ? "Use the turret on the cargo (true - yes/false - no)" : "Использовать турель на грузе (true - да/false - нет)")]
public Boolean useTurrets;
[JsonProperty(LanguageEn ? "Will loot drop from the turret upon destruction? (true - yes/false - no)" : "Будет ли выпадать лут с турели в случае ее уничтожения (true - да/false - нет)")]
public Boolean dropLootTurret;
[JsonProperty(LanguageEn ? "Turret mode: true - passive / false - active" : "Мод турели : true - пассивный / false - активный")]
public Boolean passiveMode;
[JsonProperty(LanguageEn ? "Enemy detection radius (according to the standard - 30.0)" : "Радиус обнаружения врага (по стандарту - 30.0)")]
public Single visRadius;
[JsonProperty(LanguageEn ? "Turret accuracy (aimCone) (default 4)" : "Точность турели (aimCone) (стандартно 4)")]
public Single accuracy;
[JsonProperty(LanguageEn ? "Turret health level (default 1000)" : "Уровень здоровья турели (стандартно 1000)")]
public Int32 healthTurret;
[JsonProperty(LanguageEn ? "Turret weapon configuration" : "Настройка оружия в турели")]
public WeaponSetting weaponTurretSetting = new WeaponSetting();
internal class WeaponSetting {
[JsonProperty(LanguageEn ? "Turret weapon" : "Оружие в турели")]
// ... [Code preview truncated due to length. Full source in attached file] ...