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 Rust;
using UnityEngine;
using UnityEngine.SceneManagement;
using static NPCPlayerApex;
using Time = UnityEngine.Time;
namespace Oxide.Plugins {
[Info("XDCobaltLaboratory", "DezLife", "1.3.0")]
public class XDCobaltLaboratory : RustPlugin {
#region Var
[PluginReference]
Plugin CopyPaste, IQChat, XDNotifications, RustMap, ImageLibrary;
private static XDCobaltLaboratory _;
private HashSet<Vector3> busyPoints3D = new HashSet<Vector3>();
private List<BaseEntity> HouseCobaltLab = new List<BaseEntity>();
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;
public string GetImage(string shortname, ulong skin = 0) => (string)ImageLibrary?.Call("GetImage", shortname, skin);
public bool AddImage(string url, string shortname, ulong skin = 0) => (bool)ImageLibrary?.Call("AddImage", url, shortname, skin);
public void SendImage(BasePlayer player, string imageName, ulong imageId = 0) => ImageLibrary?.Call("SendImage", player, imageName, imageId);
//private void AddNotify(BasePlayer player, string title, string description, string command = "", string cmdyes = "", string cmdno = "")
//{
// var Setting = config.xDNotification;
// Interface.Oxide.CallHook("AddNotify", player, title, description, Setting.Color, Setting.AlertDelete, Setting.SoundEffect, command, cmdyes, cmdno);
//}
#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"] = "Cobalt laboratory",
}
, 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/HouseCobalt.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();
//[JsonProperty(PropertyName = "Настройка XDNotifications(Если есть)")]
//public XDNotification xDNotification = new XDNotification();
//public class XDNotification
//{
// [JsonProperty("Включить поддержку XDNotifications(UI уведомления будут заменены на уведомление с XDNotifications)")]
// public bool UseXDNotifications;
// [JsonProperty("Цвет заднего фона уведомления(HEX)")]
// public string Color;
// [JsonProperty("Через сколько удалиться уведомление")]
// public int AlertDelete;
// [JsonProperty("Звуковой эффект")]
// public string SoundEffect;
//}
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 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("Мак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;
}
public static Configuration GetNewConfiguration() {
return new Configuration {
notiferSettings = new NotiferSettings {
weebHook = string.Empty, useUiNotifi = true
}
, pasteSettings = new BuildingPasteSettings {
housepath = "", radiusClear = 25, heightBuilding = 2,
}
, iventController = new IventController {
minPlayedPlayers = 0, minSpawnIvent = 3000, maxSpawnIvent = 7200, timeRemoveHouse = 900, timeRemoveHouse2 = 300
}
, boxSetting = new BoxSetting {
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, 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();
}
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) {
if (point.y <= ConVar.Env.oceanlevel) return false;
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) {
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();
DestroyAll<NpcZones>();
DestroyAll<NPCMonitor>();
RemoveMapMarker();
Cui.DestroyAllPlayer();
}
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;
}
AddImage("https://i.imgur.com/qD3f1TY.png", "pngForUi");
_ = 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, GetGridString(crate.transform.position));
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(Scientist 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(ResearchTable.GetBlueprintTemplate(), 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 victim, HitInfo info) {
try {
if (victim?.OwnerID == 342968945867) {
info.damageTypes.ScaleAll(0);
}
}
catch (NullReferenceException) {
}
}
#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.fuelSystem.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 : : BasePlayer.NetworkQueue.Update);
}
if (ent is Workbench || ent is ResearchTable || ent is MixingTable || ent is BaseArcadeMachine || ent is IOEntity || ent is ComputerStation || ent is CCTV_RC) {
if(ent is IOEntity) ent.SetFlag(BaseEntity.Flags.Reserved8, true);
if (ent is ComputerStation) comp = ent as ComputerStation;
if (ent is CCTV_RC) cam.Add(ent as CCTV_RC);
var ents = ent as BaseCombatEntity;
if (ents == null) continue;
ents.pickup.enabled = false;
continue;
}
if (ent is VendingMachine) {
var ents = ent as VendingMachine;
if (ents == null) continue;
ents.SetFlag(BaseEntity.Flags.Reserved4, false);
ents.UpdateMapMarker();
}
if (ent is FogMachine) {
var ents = ent as FogMachine;
if (ents == null) continue;
ents.SetFlag(BaseEntity.Flags.Reserved8, true);
ents.SetFlag(BaseEntity.Flags.Reserved7, false);
ents.SetFlag(BaseEntity.Flags.Reserved6, false);
}
if (ent.name == "assets/prefabs/deployable/large wood storage/box.wooden.large.prefab") {
box = CrateHackableLocked(ent);
NextTick(() => {
HouseCobaltLab.Remove(ent);
ent.Kill();
HouseCobaltLab.Add(box);
}
);
continue;
}
if (ent is Door) {
var ents = ent as Door;
if (ents == null) continue;
ents.pickup.enabled = false;
ents.canTakeLock = false;
ents.canTakeCloser = false;
continue;
}
if (ent is ElectricGenerator) {
(ent as ElectricGenerator).electricAmount = 400;
}
if (ent as BuildingBlock) {
var build = ent as BuildingBlock;
build?.SetFlag(BaseEntity.Flags.Reserved1, false);
build?.SetFlag(BaseEntity.Flags.Reserved2, false);
}
ent?.SetFlag(BaseEntity.Flags.Busy, true);
ent?.SetFlag(BaseEntity.Flags.Locked, true);
}
if (comp != null && cam.Count > 0) {
foreach (CCTV_RC sd in cam) comp.controlBookmarks.Add(sd.GetIdentifier(), sd.net.ID);
}
if (box == null) {
PrintError("Ошибка #3, В постройке не найден ящик");
StopIvent();
GenerateIvent();
return;
}
NpcZones Zone = new GameObject().AddComponent<NpcZones>();
Zone.Activate(box, 15, config.radiationConroller.radUse);
if (config.npcController.useSpawnNPC) SpawnBots(box);
GenerateMapMarker(box.transform.position);
SendChatAll("XD_IVENT_START", GetGridString(box.transform.position));
if(config.notiferSettings.useUiNotifi) Cui.CreateUIAllPlayer(json, box.transform.position);
RemoveHouseTime = timer.Once(config.iventController.timeRemoveHouse, () => {
SendChatAll("XD_IVENT_NOPLAYER");
StopIvent();
}
);
}
private void GenerateMapMarker(Vector3 pos) {
if(config.mapMarkers.rustMapUse) RustMap?.Call("ApiAddPointUrl", config.mapMarkers.rustMapIcon, Title, pos, config.mapMarkers.rustMapTxt);
if(config.mapMarkers.MapUse) Interface.CallHook("API_CreateMarker", pos, "xdcobaltlab", 0, 3f, 0.3f, config.mapMarkers.MapTxt, "f3ecad", "ff3535");
}
private void RemoveMapMarker() {
if (config.mapMarkers.rustMapUse) RustMap?.Call("ApiRemovePointUrl", Title);
if (config.mapMarkers.MapUse) Interface.CallHook("API_RemoveMarker", "xdcobaltlab");
}
#endregion
#region MainMetods
private void GenerateIvent() {
if (RemoveHouseTime != null) RemoveHouseTime.Destroy();
if (SpawnHouseTime != null) SpawnHouseTime.Destroy();
SpawnHouseTime = timer.Once(GenerateSpawnIventTime(), () => {
StartIvent();
}
);
}
private BaseEntity CrateHackableLocked(BaseEntity box) {
HackableLockedCrate CrateEnt = GameManager.server.CreateEntity("assets/prefabs/deployable/chinooklockedcrate/codelockedhackablecrate.prefab", new Vector3(box.transform.position.x, box.transform.position.y + 1f, box.transform.position.z), box.transform.rotation, true) as HackableLockedCrate;
CrateEnt.enableSaving = false;
CrateEnt.Spawn();
CrateEnt.OwnerID = 3566257;
CrateEnt.inventory.itemList.Clear();
for (int i = 0; i < config.boxSetting.lootBoxes.Count; i++) {
if (CrateEnt.inventory.itemList.Count >= config.boxSetting.maxItemCount) break;
var cfg = config.boxSetting.lootBoxes[i];
bool goodChance = UnityEngine.Random.Range(0, 100) >= (100 - cfg.DropChance);
if (goodChance) {
if (cfg.BluePrint) {
Item bp = ItemManager.Create(ResearchTable.GetBlueprintTemplate());
bp.blueprintTarget = ItemManager.FindItemDefinition(cfg.Shortname).itemid;
if (!bp.MoveToContainer(CrateEnt.inventory)) bp.Remove();
}
else {
int s = random.Next(cfg.MinimalAmount, cfg.MaximumAmount);
if (config.boxSetting.lootWipePlus && cfg.wipeCheck) s = s * 2;
Item GiveItem = ItemManager.CreateByName(cfg.Shortname, s, cfg.SkinID);
if (!string.IsNullOrEmpty(cfg.DisplayName)) {
GiveItem.name = cfg.DisplayName;
}
if (!GiveItem.MoveToContainer(CrateEnt.inventory)) GiveItem.Remove();
}
}
}
CrateEnt.inventory.capacity = CrateEnt.inventory.itemList.Count;
CrateEnt.inventory.MarkDirty();
CrateEnt.SendNetworkUpdate();
return CrateEnt;
}
private void StartIvent() {
if (BasePlayer.activePlayerList.Count < config.iventController.minPlayedPlayers) {
Puts("Недостаточно игроков для запуска ивента!");
GenerateIvent();
return;
}
if (RemoveHouseTime != null) RemoveHouseTime.Destroy();
if (SpawnHouseTime != null) SpawnHouseTime.Destroy();
GenerateBuilding();
}
private void StopIvent() {
foreach (BaseEntity iventEnt in HouseCobaltLab) if (!iventEnt.IsDestroyed) iventEnt?.Kill();
if (config.notiferSettings.useUiNotifi) Cui.DestroyAllPlayer();
HouseCobaltLab.Clear();
if (SpawnHouseTime != null) SpawnHouseTime.Destroy();
if (RemoveHouseTime != null) RemoveHouseTime.Destroy();
DestroyAll<NpcZones>();
DestroyAll<NPCMonitor>();
RemoveMapMarker();
GenerateIvent();
}
#region Method By OxideBro
Vector3 RandomCircle(Vector3 c
// ... [Code preview truncated due to length. Full source in attached file] ...