C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Facepunch;
using Network;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using UnityEngine;
using UnityEngine.SceneManagement;
using static ScientistNPC;
using Time = UnityEngine.Time;
namespace Oxide.Plugins {
[Info("XDCobaltLaboratory", "https://topplugin.ru/ / https://discord.com/invite/5DPTsRmd3G", "2.0.0")]
public class XDCobaltLaboratory : RustPlugin {
#region Var
[PluginReference]
Plugin CopyPaste, IQChat, RustMap, NpcSpawn;
private static XDCobaltLaboratory _;
private HashSet<Vector3> busyPoints3D = new HashSet<Vector3>();
private List<BaseEntity> HouseCobaltLab = new List<BaseEntity>();
private List<NPCMonitor> nPCMonitors = new List<NPCMonitor>();
private List<NpcZones> npcZones = new List<NpcZones>();
private List<UInt64> HideUIUser = new List<UInt64>();
private string PosIvent;
private int maxTry = 250000;
private const int MaxRadius = 5;
public Timer SpawnHouseTime;
public Timer RemoveHouseTime;
public static DateTime TimeCreatedSave = SaveRestore.SaveCreatedTime.Date;
public static DateTime RealTime = DateTime.Now.Date;
public static int SaveCreated = RealTime.Subtract(TimeCreatedSave).Days;
#endregion
#region Lang
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["XD_IVENT_START"]
= "Ученые разбили на этом острове свою лабораторию под названием Кобальт,скорее всего там находится ценные вещи, ведь он охраняется!\nКвадрат : {0}", ["XD_IVENT_STARTUI"] = "Ученые разбили свою лабораторию под названием Кобальт!\nКвадрат : {0}", ["XD_IVENT_NOPLAYER"] = "Ученые закончили свой эксперимент и успешно покинули остров без происшествий", ["XD_IVENT_CRATEHACK"] = "В лаборатории кобальт {0} начал взлом секретного ящика в квадрате {1}\nСоберитесь с силами и отбейте его", ["XD_IVENT_CRATEHACKHELP"] = "В лаборатории кобальт {0} начал взлом секретного ящика в квадрате {1}\nСоберитесь с силами и отбейте его\nНа это место уже прибыла подмога! Будте осторожней", ["XD_IVENT_CRATEHACKEND"] = "В лаборатории кобальт был взломан секретный ящик, ученые начинают эвакуацию с острова, у вас осталось {0} минут, чтобы забрать его!", ["XD_IVENT_CRATELOOTFOUND"] = " В лаборатории кобальт никто не успел залутать взломанный ящик, лаборатория была эвакуирована и постройка разрушена", ["XD_IVENT_CRATELOOTPLAYER"] = "{0} успешно ограбил лабораторию кобальт и забрал ценные вещи с секретного ящика", ["XD_IVENT_HOUSECOBALT"] = "Лаборатория КОБАЛЬТ", ["XD_IVENT_START_DISCORD"] = "Ученые разбили на этом острове свою лабораторию под названием Кобальт,скорее всего там находится ценные вещи, ведь он охраняется!\nКвадрат : {0}", ["XD_IVENT_NOPLAYER_DISCORD"] = "Ученые закончили свой эксперимент и успешно покинули остров без происшествий", ["XD_IVENT_CRATEHACK_DISCORD"] = "В лаборатории кобальт {0} начал взлом секретного ящика в квадрате {1}\nСоберитесь с силами и отбейте его", ["XD_IVENT_CRATEHACKHELP_DISCORD"] = "В лаборатории кобальт {0} начал взлом секретного ящика в квадрате {1}\nСоберитесь с силами и отбейте его\nНа это место уже прибыла подмога! Будте осторожней", ["XD_IVENT_CRATEHACKEND_DISCORD"] = "В лаборатории кобальт был взломан секретный ящик, ученые начинают эвакуацию с острова, у вас осталось {0} минут, чтобы забрать его!", ["XD_IVENT_CRATELOOTFOUND_DISCORD"] = " В лаборатории кобальт никто не успел залутать взломанный ящик, лаборатория была эвакуирована и постройка разрушена", ["XD_IVENT_CRATELOOTPLAYER_DISCORD"] = "{0} успешно ограбил лабораторию кобальт и забрал ценные вещи с секретного ящика",
}
, this);
}
#endregion
#region api
int ApiGetTimeToStart() {
if (SpawnHouseTime.Destroyed) return 0;
int time = (int)(SpawnHouseTime.Delay - DateTime.Now.Second);
if (time <= 0) return 0;
return time;
}
#endregion
#region Data
public void LoadDataCopyPaste() {
if (!Interface.Oxide.DataFileSystem.ExistsDatafile("copypaste/HouseCobalt")) {
PrintError($"Файл постройки не найден!\nНачинаем импортировать...");
webrequest.Enqueue("http://utilite.skyplugins.ru/XDCasinoOutPost/HouseCobaltNew.json", null, (i, s) => {
{
if (i == 200) {
PasteData obj = JsonConvert.DeserializeObject<PasteData>(s);
Interface.Oxide.DataFileSystem.WriteObject("copypaste/HouseCobalt", obj);
PrintWarning("Постройка успешно загружена");
}
else {
PrintError("Ошибка при загрузке постройки!\nПробуем загрузить еще раз");
timer.Once(10f, () => LoadDataCopyPaste());
return;
}
}
}
, this, RequestMethod.GET);
}
}
public class PasteData {
public Dictionary<string, object> @default;
public ICollection<Dictionary<string, object>> entities;
public Dictionary<string, object> protocol;
}
#endregion
#region Configuration
public class LootNpcOrBox {
[JsonProperty("ShortName")]
public string Shortname;
[JsonProperty("SkinID")]
public ulong SkinID;
[JsonProperty("Имя предмета")]
public string DisplayName;
[JsonProperty("Чертеж?")]
public bool BluePrint;
[JsonProperty("Минимальное количество")]
public int MinimalAmount;
[JsonProperty("максимальное количество")]
public int MaximumAmount;
[JsonProperty("Шанс выпадения предмета")]
public int DropChance;
[JsonProperty("Умножать этот предмета на день вайпа ?")]
public bool wipeCheck;
}
private static Configuration config = new Configuration();
private class Configuration {
[JsonProperty("Настройка постройки для ивента (CopyPaste)")]
public BuildingPasteSettings pasteSettings = new BuildingPasteSettings();
[JsonProperty("Настройка запуска и остановки ивента")]
public IventController iventController = new IventController();
[JsonProperty("Настройка уведомлений")]
public NotiferSettings notiferSettings = new NotiferSettings();
[JsonProperty("Настройка радиации в зоне ивента")]
public RadiationConroller radiationConroller = new RadiationConroller();
[JsonProperty("Отображения ивента на картах")]
public MapMarkers mapMarkers = new MapMarkers();
[JsonProperty("Настройка NPC")]
public NpcController npcController = new NpcController();
[JsonProperty("Настройка ящика")]
public BoxSetting boxSetting = new BoxSetting();
public SpawnBots BotSetting = new SpawnBots {
UnderBots = new SpawnBots.GeneralBot {
UseBots = true, CounSetting = new SpawnBots.GeneralBot.CountSettings {
AmountMin = 1, AmountMax = 2
}
, HealthBot = 150, WearNPC = new List<SpawnBots.GeneralBot.ItemBot> {
new SpawnBots.GeneralBot.ItemBot {
Shortname = "hoodie", SkinID = 2187105866,
}
, new SpawnBots.GeneralBot.ItemBot {
Shortname = "pants", SkinID = 2187107432,
}
, new SpawnBots.GeneralBot.ItemBot {
Shortname = "riot.helmet", SkinID = 1988565302,
}
, new SpawnBots.GeneralBot.ItemBot {
Shortname = "shoes.boots", SkinID = 1088000573,
}
, new SpawnBots.GeneralBot.ItemBot {
Shortname = "metal.plate.torso", SkinID = 1134374285,
}
,
}
, BeltNPC = new List<SpawnBots.GeneralBot.ItemBot> {
new SpawnBots.GeneralBot.ItemBot {
Shortname = "rifle.lr300", SkinID = 1837475559
}
, new SpawnBots.GeneralBot.ItemBot {
Shortname = "lmg.m249", SkinID = 0
}
, new SpawnBots.GeneralBot.ItemBot {
Shortname = "rifle.semiauto", SkinID = 1845749582
}
, new SpawnBots.GeneralBot.ItemBot {
Shortname = "rifle.ak", SkinID = 2437435853
}
,
}
}
}
;
internal class SpawnBots {
// [JsonProperty("Setting up bots under the sphere")]
[JsonProperty("Настройка")]
public GeneralBot UnderBots = new GeneralBot();
internal class GeneralBot {
// [JsonProperty("Enable spawn bots(true-yes/false-no)")]
[JsonProperty("Включить спавн ботов(true - да/false - нет)")]
public Boolean UseBots;
// [JsonProperty("Setting up the spawn of the number of NPCs")]
[JsonProperty("Настройка спавна количества NPC")]
public CountSettings CounSetting = new CountSettings();
// [JsonProperty("Health bots")]
[JsonProperty("ХП ботов")]
public Single HealthBot;
// [JsonProperty("The radius of visibility of bots")]
[JsonProperty("Радиус видимости ботов")]
public Single RadiusVisBots = 150f;
//// [JsonProperty("Percentage of bot accuracy (from 0.0 to 100.0)")]
[JsonProperty("Процент точности ботов (от 0.0 до 100.0)")]
public Single Accuracy = 30.5f;
/// [JsonProperty("The display name of the bots")]
[JsonProperty("Отображаемое имя ботов")]
public String DisplayNameBot;
[JsonProperty("Дальность патрулирования местности")]
// [JsonProperty("Roam Range")]
public float RoamRange = 30f;
[JsonProperty("Дальность погони за целью")]
//// [JsonProperty("Chase Range")]
public float ChaseRange = 90f;
[JsonProperty("Множитель радиуса атаки")]
//// [JsonProperty("Attack Range Multiplier")]
public float AttackRangeMultiplier = 2f;
[JsonProperty("Радиус обнаружения цели")]
//// [JsonProperty("Sense Range")]
public float SenseRange = 50f;
[JsonProperty("Множитель урона")]
/// [JsonProperty("Scale damage")]
public float DamageScale = 1f;
[JsonProperty("Множитель разброса")]
/// [JsonProperty("Aim Cone Scale")]
public float AimConeScale = 1f;
[JsonProperty("Обнаруживать цель только в углу обзора NPC?")]
// [JsonProperty("Detect the target only in the NPC's viewing vision cone?")]
public bool CheckVisionCone = false;
[JsonProperty("Угол обзора")]
//// [JsonProperty("Vision Cone")]
public float VisionCone = 135f;
[JsonProperty("Скорость")]
// [JsonProperty("Speed")]
public float Speed = 7f;
// [JsonProperty("Wear NPC")]
[JsonProperty("Одежда NPC")]
public List<ItemBot> WearNPC = new List<ItemBot>(6);
// [JsonProperty("NPC Weapon Variation")]
[JsonProperty("Вариация оружия NPC")]
public List<ItemBot> BeltNPC = new List<ItemBot>();
// [JsonProperty("Setting up a drop-out loot with an NPC")]
internal class ItemBot {
[JsonProperty("Shortname")]
public String Shortname;
[JsonProperty("SkinID")]
public UInt64 SkinID;
}
internal class CountSettings {
// [JsonProperty("Minimum value")]
[JsonProperty("Минимальное значение")]
public Int32 AmountMin;
// [JsonProperty("Maximum value")]
[JsonProperty("Максимальное значение")]
public Int32 AmountMax;
}
}
}
internal class RadiationConroller {
[JsonProperty("Включить радиацию ?")]
public bool radUse;
[JsonProperty("Количество радиационных частиц")]
public int radCount;
}
internal class MapMarkers {
[JsonProperty("Отметить ивент на карте RustMap?")]
public bool rustMapUse;
[JsonProperty("Иконка для карты RustMap")]
public string rustMapIcon;
[JsonProperty("Текст для карты RustMap")]
public string rustMapTxt;
[JsonProperty("Отметить ивент на карте G (Требуется https://umod.org/plugins/marker-manager)")]
public bool MapUse;
[JsonProperty("Текст для карты G")]
public string MapTxt;
}
internal class IventController {
[JsonProperty("Минимальное количество игроков для запуска ивента")]
public int minPlayedPlayers;
[JsonProperty("Время до начала ивента (Минимальное в секундах)")]
public int minSpawnIvent;
[JsonProperty("Время до начала ивента (Максимальное в секундах)")]
public int maxSpawnIvent;
[JsonProperty("Время до удаления ивента если никто не откроет ящик (Секунды)")]
public int timeRemoveHouse;
[JsonProperty("Время до удаления ивента после того как разблокируется ящик")]
public int timeRemoveHouse2;
}
internal class NpcController {
[JsonProperty("Спавнить NPC вокруг дома ?")]
public bool useSpawnNPC;
[JsonProperty("Колличевство NPC")]
public int countSpawnNpc;
[JsonProperty("ХП NPC")]
public int healthNPC;
[JsonProperty("Дистанция видимости")]
public int DistanceRange;
[JsonProperty("Точность оружия ученого (1 - 100)")]
public int Accuracy;
[JsonProperty("Спавнить ли подмогу после взлома ящика ? (НПС)")]
public bool helpBot;
[JsonProperty("Колличевство нпс (Подмога)")]
public int helpCount;
[JsonProperty("Рандомные ники нпс")]
public List<string> nameNPC = new List<string>();
[JsonProperty("Одежда для NPC")]
public List<ItemNpc> wearNpc = new List<ItemNpc>();
[JsonProperty("Варианты оружия для NPC")]
public List<ItemNpc> beltNpc = new List<ItemNpc>();
[JsonProperty("Использовать свой лут в нпс ?")]
public bool useCustomLoot;
[JsonProperty("Настройка лута в NPC (Если выключенно то будет стандартный) /cl.botitems")]
public List<LootNpcOrBox> lootNpcs = new List<LootNpcOrBox>();
internal class ItemNpc {
[JsonProperty("ShortName")]
public string Shortname;
[JsonProperty("SkinID")]
public ulong SkinID;
}
}
internal class BuildingPasteSettings {
[JsonProperty("Настройка высоты постройки (Требуется в настройке, если вы хотите ставить свою постройку)")]
public int heightBuilding;
[JsonProperty("файл в папке /oxide/data/copypaste с вашей постройкой(Если не указать загрузится стандартная)")]
public string housepath;
[JsonProperty("радиус для обнаружения построек игроков")]
public int radiusClear;
}
internal class BoxSetting {
[JsonProperty("Настройка лута в ящике /cl.items")]
public List<LootNpcOrBox> lootBoxes = new List<LootNpcOrBox>();
[JsonProperty("Время разблокировки ящика (Сек)")]
public int unBlockTime;
[JsonProperty("Макcимальное количество предметов в ящике")]
public int maxItemCount;
[JsonProperty("умножать количество лута на количество дней с начала вайпа (на 3й день - лута будет в 3 раза больше)")]
public bool lootWipePlus;
[JsonProperty("Включить сигнализацию *?")]
public bool signaling;
}
internal class NotiferSettings {
[JsonProperty("ВебХук дискорда (Если не нужны уведомления в дискорд, оставьте поле пустым)")]
public string weebHook;
[JsonProperty("Включить UI Уведомления ?")]
public bool useUiNotifi;
[JsonProperty("Цвет заднего фона окна UI")]
public string colorBackground;
[JsonProperty("Цвет Кнопки закрытия UI")]
public string colorBtnCloseUi;
}
public static Configuration GetNewConfiguration() {
return new Configuration {
notiferSettings = new NotiferSettings {
weebHook = string.Empty, useUiNotifi = true, colorBackground = "0.8 0.28 0.2 0.8", colorBtnCloseUi = "0.6784314 0.254902 0.1843137 0.8"
}
, pasteSettings = new BuildingPasteSettings {
housepath = "", radiusClear = 25, heightBuilding = 2,
}
, iventController = new IventController {
minPlayedPlayers = 0, minSpawnIvent = 3000, maxSpawnIvent = 7200, timeRemoveHouse = 900, timeRemoveHouse2 = 300
}
, boxSetting = new BoxSetting {
unBlockTime = 900, lootWipePlus = false, maxItemCount = 10, lootBoxes = new List<LootNpcOrBox> {
new LootNpcOrBox {
Shortname = "pistol.python", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 1, DropChance = 60, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "multiplegrenadelauncher", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 1, DropChance = 15, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "sulfur", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 500, MaximumAmount = 800, DropChance = 40, wipeCheck = true
}
, new LootNpcOrBox {
Shortname = "gunpowder", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 300, MaximumAmount = 400, DropChance = 10, wipeCheck = true
}
, new LootNpcOrBox {
Shortname = "door.hinged.toptier", SkinID = 0UL, DisplayName = "", BluePrint = true, MinimalAmount = 1, MaximumAmount = 1, DropChance = 15, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "wall.external.high.ice", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 5, DropChance = 75, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "ammo.rocket.basic", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 3, DropChance = 25, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "ammo.grenadelauncher.smoke", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 3, MaximumAmount = 10, DropChance = 70, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "ammo.grenadelauncher.he", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 2, MaximumAmount = 5, DropChance = 10, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "metal.facemask", SkinID = 0UL, DisplayName = "", BluePrint = true, MinimalAmount = 1, MaximumAmount = 1, DropChance = 15, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "metal.plate.torso", SkinID = 0UL, DisplayName = "", BluePrint = true, MinimalAmount = 1, MaximumAmount = 1, DropChance = 10, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "clatter.helmet", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 1, DropChance = 70, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "carburetor3", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 1, DropChance = 20, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "crankshaft3", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 1, DropChance = 10, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "techparts", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 5, MaximumAmount = 15, DropChance = 35, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "xmas.lightstring.advanced", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 30, MaximumAmount = 70, DropChance = 45, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "largemedkit", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 3, MaximumAmount = 5, DropChance = 70, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "largemedkit", SkinID = 0UL, DisplayName = "", BluePrint = true, MinimalAmount = 3, MaximumAmount = 5, DropChance = 70, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "metal.fragments", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 1000, MaximumAmount = 2000, DropChance = 70, wipeCheck = true
}
, new LootNpcOrBox {
Shortname = "explosives", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 10, MaximumAmount = 50, DropChance = 30, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "autoturret", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 1, DropChance = 60, wipeCheck = false
}
, new LootNpcOrBox {
Shortname = "explosive.timed", SkinID = 0UL, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 1, DropChance = 5, wipeCheck = true
}
,
}
, signaling = true
}
, npcController = new NpcController {
useSpawnNPC = true, countSpawnNpc = 8, healthNPC = 170, DistanceRange = 140, Accuracy = 40, helpBot = true, helpCount = 4, nameNPC = new List<string> {
"Cobalt guard", "Cobalt defense"
}
, wearNpc = new List<NpcController.ItemNpc> {
new NpcController.ItemNpc {
Shortname = "roadsign.kilt", SkinID = 1121447954
}
, new NpcController.ItemNpc {
Shortname = "burlap.shirt", SkinID = 2076298726
}
, new NpcController.ItemNpc {
Shortname = "shoes.boots", SkinID = 0
}
, new NpcController.ItemNpc {
Shortname = "roadsign.gloves", SkinID = 0
}
, new NpcController.ItemNpc {
Shortname = "burlap.trousers", SkinID = 2076292007
}
, new NpcController.ItemNpc {
Shortname = "metal.facemask", SkinID = 835028125
}
,
}
, beltNpc = new List<NpcController.ItemNpc> {
new NpcController.ItemNpc {
Shortname = "rifle.lr300", SkinID = 1975712725
}
, new NpcController.ItemNpc {
Shortname = "rifle.lr300", SkinID = 1837473292
}
, new NpcController.ItemNpc {
Shortname = "pistol.semiauto", SkinID = 1557105240
}
, new NpcController.ItemNpc {
Shortname = "rifle.semiauto", SkinID = 1845735432
}
, new NpcController.ItemNpc {
Shortname = "rifle.ak", SkinID = 1352726257
}
,
}
, useCustomLoot = true, lootNpcs = new List<LootNpcOrBox> {
new LootNpcOrBox {
Shortname = "halloween.surgeonsuit", SkinID = 0, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 1, DropChance = 70
}
, new LootNpcOrBox {
Shortname = "metal.facemask", SkinID = 1886184322, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 1, DropChance = 20
}
, new LootNpcOrBox {
Shortname = "door.double.hinged.metal", SkinID = 191100000, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 2, DropChance = 60
}
, new LootNpcOrBox {
Shortname = "rifle.bolt", SkinID = 0, DisplayName = "", BluePrint = true, MinimalAmount = 1, MaximumAmount = 1, DropChance = 10
}
, new LootNpcOrBox {
Shortname = "rifle.lr300", SkinID = 0, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 1, DropChance = 15
}
, new LootNpcOrBox {
Shortname = "pistol.revolver", SkinID = 0, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 3, DropChance = 60
}
, new LootNpcOrBox {
Shortname = "supply.signal", SkinID = 0, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 3, DropChance = 20
}
, new LootNpcOrBox {
Shortname = "explosive.satchel", SkinID = 0, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 3, DropChance = 5
}
, new LootNpcOrBox {
Shortname = "grenade.smoke", SkinID = 0, DisplayName = "", BluePrint = false, MinimalAmount = 1, MaximumAmount = 20, DropChance = 45
}
, new LootNpcOrBox {
Shortname = "ammo.rifle", SkinID = 0, DisplayName = "", BluePrint = false, MinimalAmount = 50, MaximumAmount = 120, DropChance = 35
}
, new LootNpcOrBox {
Shortname = "scrap", SkinID = 0, DisplayName = "", BluePrint = false, MinimalAmount = 100, MaximumAmount = 500, DropChance = 20
}
, new LootNpcOrBox {
Shortname = "giantcandycanedecor", SkinID = 0, DisplayName = "Новый год", BluePrint = false, MinimalAmount = 1, MaximumAmount = 5, DropChance = 70
}
,
}
}
, radiationConroller = new RadiationConroller {
radUse = true, radCount = 20
}
, mapMarkers = new MapMarkers {
rustMapUse = true, rustMapIcon = "https://i.imgur.com/bwg6de6.png", rustMapTxt = "Лабаратория кобальт", MapUse = false, MapTxt = "Лабаратория кобальт"
}
}
;
}
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) LoadDefaultConfig();
}
catch {
PrintWarning("Ошибка #132" + $"чтения конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
LoadDefaultConfig();
}
if (config.notiferSettings.colorBtnCloseUi == null) {
config.notiferSettings.colorBtnCloseUi = "0.6784314 0.254902 0.1843137 0.8";
config.notiferSettings.colorBackground = "0.8 0.28 0.2 0.8";
}
if (config.boxSetting.unBlockTime == 0) {
config.boxSetting.unBlockTime = 900;
}
if (config.npcController.Accuracy == 0) {
config.npcController.Accuracy = 40;
}
if (config.npcController.DistanceRange == 0) {
config.npcController.DistanceRange = 130;
}
NextTick(SaveConfig);
}
protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region SpawnPoint
#region CheckFlat
private List<Vector3>[] patternPositionsAboveWater = new List<Vector3>[MaxRadius];
private List<Vector3>[] patternPositionsUnderWater = new List<Vector3>[MaxRadius];
private readonly Quaternion[] directions = {
Quaternion.Euler(90, 0, 0), Quaternion.Euler(0, 0, 90), Quaternion.Euler(0, 0, 180)
}
;
private void FillPatterns() {
Vector3[] startPositions = {
new Vector3(1, 0, 1), new Vector3(-1, 0, 1), new Vector3(-1, 0, -1), new Vector3(1, 0, -1)
}
;
patternPositionsAboveWater[0] = new List<Vector3> {
new Vector3(0, -1.0f, 0)
}
;
for (int loop = 1; loop < MaxRadius; loop++) {
patternPositionsAboveWater[loop] = new List<Vector3>();
for (int step = 0; step < loop * 2; step++) {
for (int pos = 0; pos < 4; pos++) {
Vector3 sPos = startPositions[pos] * step;
for (int rot = 0; rot < 3; rot++) {
Vector3 rPos = directions[rot] * sPos;
rPos.y = -1.0f;
patternPositionsAboveWater[loop].Add(rPos);
}
}
}
}
for (int i = 0; i < patternPositionsAboveWater.Length; i++) {
patternPositionsUnderWater[i] = new List<Vector3>();
foreach (var vPos in patternPositionsAboveWater[i]) {
var rPos = new Vector3(vPos.x, 1.0f, vPos.z);
patternPositionsUnderWater[i].Add(rPos);
}
}
}
[ConsoleCommand("isflat")]
private void CmdIsFlat(ConsoleSystem.Arg arg) {
Vector3 pPos = new Vector3(arg.Player().transform.position.x, TerrainMeta.HeightMap.GetHeight(arg.Player().transform.position), arg.Player().transform.position.z);
var b = IsFlat(ref pPos);
arg.Player().Teleport(pPos);
}
public bool IsFlat(ref Vector3 position) {
List<Vector3>[] AboveWater = new List<Vector3>[MaxRadius];
Array.Copy(patternPositionsAboveWater, AboveWater, patternPositionsAboveWater.Length);
for (int i = 0; i < AboveWater.Length; i++) {
for (int j = 0; j < AboveWater[i].Count; j++) {
Vector3 pPos = AboveWater[i][j];
Vector3 resultAbovePos = new Vector3(pPos.x + position.x, position.y + 1.0f, pPos.z + position.z);
Vector3 resultUnderPos = new Vector3(pPos.x + position.x, position.y - 1.0f, pPos.z + position.z);
if (resultAbovePos.y >= TerrainMeta.HeightMap.GetHeight(resultAbovePos) && resultUnderPos.y <= TerrainMeta.HeightMap.GetHeight(resultUnderPos)) {
}
else return false;
}
}
return true;
}
#endregion
#region GenerateSpawnPoint
public bool IsDistancePoint(Vector3 point) {
bool result = busyPoints3D.Count(x => Vector3.Distance(point, x) < 20f) == 0;
return result;
}
private void GenerateSpawnPoints() {
for (int i = 0; i < 100; i++) {
maxTry -= 1;
Vector3 point3D = new Vector3();
Vector2 point2D = new Vector3(UnityEngine.Random.Range(-TerrainMeta.Size.x / 2, TerrainMeta.Size.x / 2), UnityEngine.Random.Range(-TerrainMeta.Size.z / 2, TerrainMeta.Size.z / 2));
point3D.x = point2D.x;
point3D.z = point2D.y;
point3D.y = TerrainMeta.HeightMap.GetHeight(point3D);
if (!IsFlat(ref point3D)) continue;
if (!Is3DPointValid(ref point3D)) continue;
if (!IsDistancePoint(point3D)) continue;
if (point3D != Vector3.zero) {
AcceptValue(ref point3D);
}
}
if (maxTry > 0) {
NextTick(() => {
GenerateSpawnPoints();
}
);
}
else {
PrintWarning($"{busyPoints3D.Count} точек сгенерированно!");
maxTry = 250000;
}
}
private bool Is3DPointValid(ref Vector3 point) {
List<BuildingPrivlidge> cupboards = new List<BuildingPrivlidge>();
Vis.Entities(point, config.pasteSettings.radiusClear, cupboards);
if (Physics.CheckSphere(point, config.pasteSettings.radiusClear, LayerMask.GetMask("Construction", "Default", "Deployed", "World", "Trigger", "Prevent Building")) || cupboards.Count > 0 || point.y < ConVar.Env.oceanlevel + 4f) {
return false;
}
return true;
}
private void AcceptValue(ref Vector3 point) {
busyPoints3D.Add(point);
}
#endregion
#region GetPosition
private object GetSpawnPoints() {
if (busyPoints3D.ToList().Count <= 3) {
PrintWarning("Все точки закончены!\n" + "Начинаем генерировать новые...");
busyPoints3D.Clear();
GenerateSpawnPoints();
GenerateIvent();
return Vector3.zero;
}
Vector3 targetPos = busyPoints3D.ToList().GetRandom();
if (targetPos == Vector3.zero) {
busyPoints3D.Remove(targetPos);
return GetSpawnPoints();
}
bool valid = Is3DPointValid(ref targetPos);
if (!valid) {
busyPoints3D.Remove(targetPos);
return GetSpawnPoints();
}
busyPoints3D.Remove(targetPos);
return targetPos;
}
#endregion
#endregion
#region Hooks
void OnEntityMounted(BaseMountable entity, BasePlayer player) {
if (HouseCobaltLab.Contains(entity?.GetParentEntity())) HouseCobaltLab.Remove(entity.GetParentEntity());
}
void Unload() {
foreach (BaseEntity iventEnt in HouseCobaltLab) {
if (!iventEnt.IsDestroyed) iventEnt?.Kill();
}
HouseCobaltLab.Clear();
if (SpawnHouseTime != null) SpawnHouseTime.Destroy();
if (RemoveHouseTime != null) RemoveHouseTime.Destroy();
DestroyZone();
RemoveMapMarker();
Cui.DestroyAllPlayer();
}
void Init() {
UnscribeHook();
}
private void OnServerInitialized() {
if (!CopyPaste) {
PrintError("Проверьте установлен ли у вас плагин 'CopyPaste'");
Interface.Oxide.UnloadPlugin(Name);
return;
}
else if (CopyPaste.Version < new VersionNumber(4, 1, 27)) {
PrintError("У вас старая версия CopyPaste!\nПожалуйста обновите плагин до последней версии (4.1.27 или выше) - https://umod.org/plugins/copy-paste");
Interface.Oxide.UnloadPlugin(Name);
return;
}
_ = this;
FillPatterns();
NextTick(() => {
GenerateSpawnPoints();
}
);
GenerateIvent();
if (string.IsNullOrEmpty(config.pasteSettings.housepath)) LoadDataCopyPaste();
}
private void CanHackCrate(BasePlayer player, HackableLockedCrate crate) {
if (crate.OwnerID == 3566257) {
if (RemoveHouseTime != null) RemoveHouseTime.Destroy();
if (config.boxSetting.signaling) {
var Alarm = GameManager.server.CreateEntity("assets/prefabs/deployable/playerioents/alarms/audioalarm.prefab", crate.transform.position, default(Quaternion), true);
Alarm.Spawn();
Alarm.SetFlag(BaseEntity.Flags.Reserved8, true);
Alarm.gameObject.Identity();
Alarm.SetParent(crate);
var Light = GameManager.server.CreateEntity("assets/prefabs/deployable/playerioents/lights/sirenlight/electric.sirenlight.deployed.prefab", crate.transform.position, Quaternion.identity, false);
Light.enableSaving = true;
Light.Spawn();
Light.SetParent(crate);
Light.transform.localPosition = new Vector3(0.4f, 1.45f, -0.3f);
Light.transform.hasChanged = true;
Light.SendNetworkUpdate();
Light.SetFlag(BaseEntity.Flags.Reserved8, true);
}
SendChatAll(config.npcController.helpBot ? "XD_IVENT_CRATEHACKHELP" : "XD_IVENT_CRATEHACK", player.displayName, PosIvent);
if (config.npcController.helpBot) SpawnBots(crate, true);
}
}
void OnCrateHackEnd(HackableLockedCrate crate) {
if (crate.OwnerID == 3566257) {
if (RemoveHouseTime != null) RemoveHouseTime.Destroy();
SendChatAll("XD_IVENT_CRATEHACKEND", (config.iventController.timeRemoveHouse2 / 60));
RemoveHouseTime = timer.Once(config.iventController.timeRemoveHouse2, () => {
SendChatAll("XD_IVENT_CRATELOOTFOUND");
StopIvent();
}
);
}
}
void CanLootEntity(BasePlayer player, StorageContainer container) {
if (container is HackableLockedCrate && container.OwnerID == 3566257) {
SendChatAll("XD_IVENT_CRATELOOTPLAYER", player.displayName);
if (RemoveHouseTime != null) RemoveHouseTime.Destroy();
RemoveHouseTime = timer.Once(300, () => {
StopIvent();
}
);
container.OwnerID = 123425345634634;
}
}
void OnCorpsePopulate(ScientistNPC npc, NPCPlayerCorpse corpse) {
if (npc?.GetComponent<NPCMonitor>() != null && corpse != null) {
if (config.npcController.useCustomLoot && config.npcController.lootNpcs?.Count > 0) {
corpse.containers[0].itemList.Clear();
for (int i = 0; i < config.npcController.lootNpcs.Count; i++) {
var main = config.npcController.lootNpcs[i];
if (corpse.containers[0].IsFull()) break;
bool goodChance = random.Next(0, 100) >= (100 - main.DropChance);
if (goodChance) {
if (main.BluePrint) {
Item item = ItemManager.Create(ItemManager.FindItemDefinition("blueprintbase"), 1, 0UL);
item.blueprintTarget = ItemManager.FindItemDefinition(main.Shortname).itemid;
if (!item.MoveToContainer(corpse.containers[0])) item.Remove();
}
else {
Item item = ItemManager.CreateByName(main.Shortname, random.Next(main.MinimalAmount, main.MaximumAmount), main.SkinID);
if (!string.IsNullOrEmpty(main.DisplayName)) {
item.name = main.DisplayName;
}
if (!item.MoveToContainer(corpse.containers[0])) item.Remove();
}
}
}
corpse.containers[0].capacity = corpse.containers[0].itemList.Count;
corpse.containers[1].capacity = 0;
corpse.containers[2].capacity = 0;
corpse.containers[0].MarkDirty();
corpse.SendNetworkUpdate();
}
}
}
void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo) {
if (!entity.IsValid() || hitInfo == null) return;
if (entity?.OwnerID == 342968945867) {
hitInfo.damageTypes.ScaleAll(0);
}
var attacker = hitInfo.InitiatorPlayer;
if (attacker.IsValid() && attacker is ScientistNPC && (attacker as ScientistNPC).OwnerID == 3566257 && config.npcController.Accuracy < UnityEngine.Random.Range(0f, 100f)) {
hitInfo.damageTypes = new DamageTypeList();
hitInfo.DidHit = false;
hitInfo.DoHitEffects = false;
hitInfo.HitEntity = null;
return;
}
}
#endregion
#region MetodsPasteBuild
void GenerateBuilding() {
string[] options = {
"stability", "true", "deployables", "true", "autoheight", "false", "entityowner", "false"
}
;
Vector3 resultVector = (Vector3)GetSpawnPoints();
if (resultVector == null || resultVector == Vector3.zero) return;
var success = CopyPaste.Call("TryPasteFromVector3", new Vector3(resultVector.x, resultVector.y + config.pasteSettings.heightBuilding, resultVector.z), 0f, !string.IsNullOrWhiteSpace(config.pasteSettings.housepath) ? config.pasteSettings.housepath : "HouseCobalt", options);
if (success is string) {
PrintWarning("Ошибка #1 \nПлагин не будет работать, Обратитесь к разработчику");
GenerateIvent();
return;
}
}
void OnPasteFinished(List<BaseEntity> pastedEntities, string fileName) {
if (fileName != "HouseCobalt" && fileName != config.pasteSettings.housepath) return;
HouseCobaltLab = pastedEntities;
BaseEntity box = null;
List<CCTV_RC> cam = new List<CCTV_RC>();
ComputerStation comp = null;
foreach (BaseEntity ent in pastedEntities) {
if (ent is MiniCopter) {
MiniCopter copter = (ent as MiniCopter);
copter.GetFuelSystem().AddStartingFuel(50);
copter.transform.position = new Vector3(copter.transform.position.x, copter.transform.position.y + 3f, copter.transform.position.z);
continue;
}
ent.OwnerID = 342968945867;
if (ent is Signage) {
var ents = ent as Signage;
if (ents == null) continue;
ents?.SetFlag(BaseEntity.Flags.Locked, true);
ents.SendNetworkUpdate(global : : BasePla
// ... [Code preview truncated due to length. Full source in attached file] ...