C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using Oxide.Core.Libraries;
using Newtonsoft.Json;
using Rust;
using System.Globalization;
using Network;
using System;
using Oxide.Plugins.XDCobaltLaboratoryExtensionMethods;
using System.Text;
using Oxide.Game.Rust.Cui;
using Random = Oxide.Core.Random;
using UnityEngine;
using System.Collections;
using Oxide.Core.Plugins;
using Facepunch;
using Oxide.Core;
using Newtonsoft.Json.Linq;
namespace Oxide.Plugins.XDCobaltLaboratoryExtensionMethods {
public static class ExtensionMethods {
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
if (predicate(enumerator.Current)) {
return true;
}
}
}
return false;
}
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
if (predicate(enumerator.Current)) {
return enumerator.Current;
}
}
}
return default(TSource);
}
public static HashSet<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> predicate) {
HashSet<TResult> result = new HashSet<TResult>();
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
result.Add(predicate(enumerator.Current));
}
}
return result;
}
public static List<TResult> Select<TSource, TResult>(this IList<TSource> source, Func<TSource, TResult> predicate) {
List<TResult> result = new List<TResult>();
for (int i = 0; i < source.Count; i++) {
TSource element = source[i];
result.Add(predicate(element));
}
return result;
}
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
List<TSource> result = new List<TSource>();
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
result.Add(enumerator.Current);
}
}
return result;
}
public static TSource Min<TSource>(this IEnumerable<TSource> source, Func<TSource, float> predicate) {
TSource result = source.ElementAt(0);
float resultValue = predicate(result);
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
TSource element = enumerator.Current;
float elementValue = predicate(element);
if (elementValue < resultValue) {
result = element;
resultValue = elementValue;
}
}
}
return result;
}
public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index) {
int movements = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
if (movements == index) {
return enumerator.Current;
}
movements++;
}
}
return default(TSource);
}
}
}
namespace Oxide.Plugins {
[Info("XDCobaltLaboratory", "DezLife", "2.5.7")]
internal class XDCobaltLaboratory : RustPlugin {
private NpcZones npcZones = null;
private Timer SpawnHouseTime;
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) {
throw new Exception();
}
SaveConfig();
}
catch {
for (int i = 0; i < 3; i++) {
PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");
}
LoadDefaultConfig();
}
ValidateConfig();
SaveConfig();
}
private List<BaseEntity> HouseCobaltLab = new List<BaseEntity>();
private BaseEntity CrateHackableLocked(BaseEntity box) {
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.hackSeconds = HackableLockedCrate.requiredHackSeconds - config.boxSetting.UnlockTime;
if (config.boxSetting.TypeLootTable == 1) {
NextTick(() => {
for (int i = CrateEnt.inventory.itemList.Count - 1; i >= 0; i--) {
Item item = CrateEnt.inventory.itemList[i];
item.RemoveFromContainer();
item.Remove();
}
AddToContainerItem(CrateEnt.inventory, config.boxSetting.OwnLootTable);
}
);
}
return CrateEnt;
}
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["XD_IVENT_START"]
= "<color=#008000>[Cobalt Lab Event] </color>Ученые разбили на этом острове свою лабораторию под названием Кобальт, скорее всего там находятся ценные вещи, ведь она охраняется!\nКвадрат: <color=#00FF00>{0}</color>", ["XD_IVENT_STARTUI"] = "Ученые развернули свою Кобальтовую лабораторию!\nКвадрат : {0}", ["XD_IVENT_NOPLAYER"] = "<color=#008000>[Cobalt Lab Event] </color>Ученые закончили свой эксперимент и успешно покинули остров без происшествий", ["XD_IVENT_CRATEHACK"] = "<color=#008000>[Cobalt Lab Event] </color>В лаборатории кобальт <color=#FFD700>{0}</color> начал взлом секретного ящика в квадрате <color=#00FF00>{1}</color>", ["XD_IVENT_CRATEHACKHELP"] = "<color=#008000>[Cobalt Lab Event] </color>В лаборатории кобальт <color=#FFD700>{0}</color> начал взлом секретного ящика в квадрате <color=#00FF00>{1}</color>\nНа это место уже прибыла подмога! Будте осторожней", ["XD_IVENT_CRATEHACKEND"] = "<color=#008000>[Cobalt Lab Event] </color>В лаборатории кобальт был взломан секретный ящик, ученые начинают эвакуацию с острова, у вас осталось <color=#9ACD32>{0} минут</color>, чтобы забрать его!", ["XD_IVENT_CRATELOOTFOUND"] = " <color=#008000>[Cobalt Lab Event] </color>В лаборатории кобальт никто не успел залутать взломанный ящик, лаборатория была эвакуирована и постройка разрушена", ["XD_IVENT_CRATELOOTPLAYER"] = "<color=#008000>[Cobalt Lab Event] </color><color=#FFD700>{0}</color> успешно ограбил лабораторию кобальт и забрал ценные вещи с секретного ящика", ["XD_IVENT_HOUSECOBALT"] = "Cobalt laboratory", ["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} успешно ограбил лабораторию кобальт и забрал ценные вещи с секретного ящика", ["XD_IVENT_CL_ITEM_SYNTAX"] = "Используйте:\n/cl.items add - добавить лут к существующему\n/cl.items reset - заменить старый лут на новый", ["XD_IVENT_CL_ITEM_ADDED"] = "Вы успешно добавили новые предметы для ящика.\nОбязательно настройте их в конфиге", ["XD_IVENT_CL_ITEM_REPLACED"] = "Вы успешно заменили все предметы на новые.\nОбязательно настройте их в конфиге", ["XD_IVENT_CLBOT_ITEM_SYNTAX"] = "Используйте:\n/cl.botitems add \"названия присета\" - добавить лут к существующему\n/cl.botitems reset - заменить старый лут на новый", ["XD_IVENT_CLBOT_ITEM_ADDED"] = "Вы успешно добавили новые предметы для npc.\nОбязательно настройте их в конфиге", ["XD_IVENT_CLBOT_ITEM__PRESET_NOTFOUND"] = "Присета с именем `{0}`, не существует.", ["XD_IVENT_CLBOT_ITEM_REPLACED"] = "Вы успешно заменили все предметы на новые.\nОбязательно настройте их в конфиге", ["XD_IVENT_CLCONTROLLER_SYNTAX"] = "Используйте:\n/cl start - Запуск ивента досрочно\n/cl stop - отменить ивент досрочно", ["XD_IVENT_CLCONTROLLER_ACTIVE"] = "Ивент уже активен!", ["XD_IVENT_CLCONTROLLER_STOPADMIN"] = "Ивент окончен досрочно администратором!", ["XD_IVENT_CLCONTROLLER_NOT_ACTIVE"] = "Нет активных ивентов", ["XD_IVENT_CLCONTROLLER_NOT_ENOUGH_PLAYERS"] = "Недостаточно игроков для запуска ивента!", ["XD_IVENT_CLCONTROLLER_BUILDING_ERROR"] = "Ошибка #1 \nПостройка не смогла заспавнится\nОбратитесь к разработчику\nDezLife#1480\nvk.com/dezlife", ["XD_IVENT_CLCONTROLLER_NOT_BUILDING_BOX"] = "Ошибка #3, В постройке не найден ящик", ["XD_IVENT_CLCONTROLLER_THE_POINTS_ARE_ENDED"] = "Все точки закончены!\nНачинаем генерировать новые...", ["XD_IVENT_CLCONTROLLER_ENTER_PVP"] = "Вы <color=#ce3f27>вошли</color> в PVP зону, теперь другие игроки <color=#ce3f27>могут</color> наносить вам урон!", ["XD_IVENT_CLCONTROLLER_EXIT_PVP"] = "Вы <color=#738d43>вышли</color> из PVP зоны, теперь другие игроки <color=#738d43>не могут</color> наносить вам урон!", ["XD_IVENT_CLCONTROLLER_NOT_NPSSPAWN"] = "У вас отсутсвует плагин NpcSpawn.Пожалуйста установите его для коректной работы", ["XD_EVENT_BUILDING_NOTFOUND"] = "Не найден файл постройки : {0}.Переместите файл с постройкой в папку `/oxide/data/copypaste`",
}
, this, "ru");
lang.RegisterMessages(new Dictionary<string, string> {
["XD_IVENT_START"]
= "<color=#008000>[Cobalt Lab Event] </color>Scientists have set up their laboratory on this island called Cobalt, most likely there are valuable things there, because it is protected!\nGrid: <color=#00FF00>{0}</color>", ["XD_IVENT_STARTUI"] = "Scientists have deployed their Cobalt Lab!\nGrid : {0}", ["XD_IVENT_NOPLAYER"] = "<color=#008000>[Cobalt Lab Event] </color>The scientists completed their experiment and successfully left the island without incident", ["XD_IVENT_CRATEHACK"] = "<color=#008000>[Cobalt Lab Event] </color>In the cobalt lab <color=#FFD700>{0}</color> started hacking a secret crate in the grid <color=#00FF00>{1}</color>", ["XD_IVENT_CRATEHACKHELP"] = "<color=#008000>[Cobalt Lab Event] </color>In the cobalt lab <color=#FFD700>{0}</color> started hacking a secret crate in the grid <color=#00FF00>{1}</color>\nHelp has already arrived at this place! Be careful", ["XD_IVENT_CRATEHACKEND"] = "<color=#008000>[Cobalt Lab Event] </color>A secret crate has been hacked in the cobalt lab, scientists are beginning to evacuate the island, you have <color=#9ACD32>{0} minutes</color> left to pick it up!", ["XD_IVENT_CRATELOOTFOUND"] = " <color=#008000>[Cobalt Lab Event] </color>In the cobalt laboratory, no one had time to hack the secret crate, the laboratory was evacuated and the building was destroyed", ["XD_IVENT_CRATELOOTPLAYER"] = "<color=#008000>[Cobalt Lab Event] </color><color=#FFD700>{0}</color> successfully robbed the cobalt lab and took valuables from a secret crate", ["XD_IVENT_HOUSECOBALT"] = "Cobalt laboratory", ["XD_IVENT_START_DISCORD"] = "Scientists have set up their laboratory on this island called Cobalt, most likely there are valuable things there, because it is guarded!\nКвадрат : {0}", ["XD_IVENT_NOPLAYER_DISCORD"] = "Scientists finished their experiment and successfully left the island without incident.", ["XD_IVENT_CRATEHACK_DISCORD"] = "In the laboratory, cobalt {0} started breaking into a secret box in square {1}\nGather your strength and fight it off", ["XD_IVENT_CRATEHACKHELP_DISCORD"] = "In the laboratory, cobalt {0} started breaking into a secret box in square {1}\nGather your strength and fight it off\nHelp has already arrived at this place! Be careful", ["XD_IVENT_CRATEHACKEND_DISCORD"] = "A secret box has been broken in the cobalt laboratory, scientists are starting to evacuate the island, you have {0} minutes left to pick it up!", ["XD_IVENT_CRATELOOTFOUND_DISCORD"] = " In the cobalt laboratory, no one had time to patch up the cracked box, the laboratory was evacuated and the building was destroyed", ["XD_IVENT_CRATELOOTPLAYER_DISCORD"] = "{0} successfully robbed the cobalt laboratory and took valuable items from the secret box", ["XD_IVENT_CL_ITEM_SYNTAX"] = "Use:\n/cl.items add - add loot to the existing one\n/cl.items reset - replace old loot with a new one", ["XD_IVENT_CL_ITEM_ADDED"] = "You have successfully added new items to the crate.\nBe sure to configure them in the config", ["XD_IVENT_CL_ITEM_REPLACED"] = "You have successfully replaced all items with new ones.\nBe sure to configure them in the config", ["XD_IVENT_CLBOT_ITEM_SYNTAX"] = "Use:\n/cl.botitems add \"preset name\" - add loot to the existing one\n/cl.botitems reset - replace old loot with a new one", ["XD_IVENT_CLBOT_ITEM_ADDED"] = "You have successfully added new items for the npc.\nBe sure to configure them in the config", ["XD_IVENT_CLBOT_ITEM__PRESET_NOTFOUND"] = "There is no preset named `{0}`.", ["XD_IVENT_CLBOT_ITEM_REPLACED"] = "You have successfully replaced all items with new ones.\nBe sure to configure them in the config", ["XD_IVENT_CLCONTROLLER_SYNTAX"] = "Use:\n/cl start - Launching the event ahead of schedule\n/cl stop - cancel the event ahead of schedule", ["XD_IVENT_CLCONTROLLER_ACTIVE"] = "The event is already active!", ["XD_IVENT_CLCONTROLLER_STOPADMIN"] = "Event ended ahead of schedule by the administrator!", ["XD_IVENT_CLCONTROLLER_NOT_ACTIVE"] = "No active events", ["XD_IVENT_CLCONTROLLER_NOT_ENOUGH_PLAYERS"] = "Not enough players to start the event!", ["XD_IVENT_CLCONTROLLER_BUILDING_ERROR"] = "Error #1 \nThe building could not spawn\nContact the developer\nDezLife#1480\nvk.com/dezlife", ["XD_IVENT_CLCONTROLLER_NOT_BUILDING_BOX"] = "Error #3,No crate found in the building", ["XD_IVENT_CLCONTROLLER_THE_POINTS_ARE_ENDED"] = "All points are completed!\nWe start generating new...", ["XD_IVENT_CLCONTROLLER_ENTER_PVP"] = "You <color=#ce3f27>entered</color> In the PVP zone, now other players <color=#ce3f27>can</color> do damage to you!", ["XD_IVENT_CLCONTROLLER_EXIT_PVP"] = "You <color=#738d43>exited</color> from the PVP zone, now other players <color=#738d43>can not</color> do damage to you!", ["XD_IVENT_CLCONTROLLER_NOT_NPSSPAWN"] = "You are missing the Npc Spawn plugin.Please install it to work correctly", ["XD_EVENT_BUILDING_NOTFOUND"] = "The construction file was not found : {0}.Move the file with the building to the folder `/oxide/data/copypaste`",
}
, this);
}
object OnBotReSpawnCrateDropped(HackableLockedCrate crate) {
if (crate == CrateEnt) {
return true;
}
else {
return null;
}
}
private bool IsAlive(BaseNetworkable entity) {
return entity != null && !entity.IsDestroyed;
}
private IEnumerator GenerateSpawnPoints() //cywka
{
int maxRadius = 1500;
int checks = 0;
for (int i = 0; i < 100; i++) {
float angle = Random.Range(0f, 360f);
float distance = Random.Range(500f, maxRadius);
Vector3 pos = new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad) * distance, 0f, Mathf.Sin(angle * Mathf.Deg2Rad) * distance );
pos.y = GetSpawnHeight(pos);
// Проверка, чтобы точка была на суше
if (TerrainMeta.HeightMap.GetHeight(pos) > TerrainMeta.WaterMap.GetHeight(pos)) {
PosValidation(pos);
}
if (++checks >= 10) {
checks = 0;
yield return CoroutineEx.waitForSeconds(0.05f);
}
}
PrintWarning($"{busyPoints3D.Count} POINTS FOUND!");
ServerMgr.Instance.StopCoroutine(FindPositions);
FindPositions = null;
}
//cywka
private List<Vector3>[] patternPositionsAboveWater = new List<Vector3>[MaxRadius];
private void Request(string url, string payload, Action<int> callback = null) {
Dictionary<string, string> header = new Dictionary<string, string> {
{
"Content-Type", "application/json"
}
}
;
webrequest.Enqueue(url, payload, (code, response) => {
if (code != 200 && code != 204) {
if (response != null) {
try {
JObject json = JObject.Parse(response);
if (code == 429) {
float seconds = float.Parse(Math.Ceiling((double)(int)json["retry_after"] / 1000).ToString());
}
else {
PrintWarning($" Discord rejected that payload! Responded with \"{json["message"]}\" Code: {code}");
}
}
catch {
PrintWarning($"Failed to get a valid response from discord! Error: \"{response}\" Code: {code}");
}
}
else {
PrintWarning($"Discord didn't respond (down?) Code: {code}");
}
}
try {
callback?.Invoke(code);
}
catch (Exception) {
}
}
, this, RequestMethod.POST, header);
}
private const int MaxRadius = 7;
protected override void SaveConfig() {
Config.WriteObject(config);
}
[ChatCommand("cl.botitems")]
void NpcLootCommand(BasePlayer player, string cmd, string[] Args) {
if (Args == null || Args.Length < 2) {
SendChatPlayer(GetLang("XD_IVENT_CLBOT_ITEM_SYNTAX", player.UserIDString), player);
return;
}
switch (Args[0]) {
case "add" : {
foreach (Configuration.BuildingPasteSettings.PasteBuild preset in config.pasteSettings.pasteBuilds) {
Configuration.BuildingPasteSettings.PresetConfig presets = preset.NpcPressets.FirstOrDefault(x => x.Config.Name == Args[1]);
if (presets != null) {
foreach (Item item in player.inventory.containerMain.itemList) {
presets.OwnLootTable.Items.Add(new Configuration.ItemConfig {
IsBluePrint = item.IsBlueprint(), ShortName = item.IsBlueprint() ? item.blueprintTargetDef.shortname : item.info.shortname, SkinID = item.skin, Name = string.Empty, Chance = 30, MinAmount = 1, MaxAmount = 1, lootWipePlus = false
}
);
}
SendChatPlayer(GetLang("XD_IVENT_CLBOT_ITEM_ADDED", player.UserIDString), player);
SaveConfig();
}
else {
SendChatPlayer(GetLang("XD_IVENT_CLBOT_ITEM__PRESET_NOTFOUND", player.UserIDString, Args[1]), player);
}
}
break;
}
case "reset" : {
foreach (Configuration.BuildingPasteSettings.PasteBuild preset in config.pasteSettings.pasteBuilds) {
Configuration.BuildingPasteSettings.PresetConfig presets = preset.NpcPressets.FirstOrDefault(x => x.Config.Name == Args[1]);
if (presets != null) {
presets.OwnLootTable.Items.Clear();
foreach (Item item in player.inventory.containerMain.itemList) {
presets.OwnLootTable.Items.Add(new Configuration.ItemConfig {
IsBluePrint = item.IsBlueprint(), ShortName = item.IsBlueprint() ? item.blueprintTargetDef.shortname : item.info.shortname, SkinID = item.skin, Name = string.Empty, Chance = 30, MinAmount = 1, MaxAmount = 1, lootWipePlus = false
}
);
}
SendChatPlayer(GetLang("XD_IVENT_CLBOT_ITEM_REPLACED", player.UserIDString), player);
SaveConfig();
}
else {
SendChatPlayer(GetLang("XD_IVENT_CLBOT_ITEM__PRESET_NOTFOUND", player.UserIDString, Args[1]), player);
}
}
break;
}
}
}
static float GetGroundPosition(Vector3 pos) {
float y = TerrainMeta.HeightMap.GetHeight(pos);
RaycastHit hit;
if (Physics.Raycast(new Vector3(pos.x, pos.y + 200f, pos.z), Vector3.down, out hit, Mathf.Infinity, LayerMask.GetMask(new[] {
"Terrain", "World", "Default", "Construction", "Deployed"
}
)) && !hit.collider.name.Contains("rock_cliff")) {
return Mathf.Max(hit.point.y, y);
}
return y;
}
private void DestroyZone() {
if (npcZones != null) {
UnityEngine.Object.Destroy(npcZones.gameObject);
}
}
private bool IsAsset(string value) {
foreach (string asset in assets) {
if (value.Contains(asset)) {
return true;
}
}
return false;
}
void OnCrateHackEnd(HackableLockedCrate crate) {
if (crate == CrateEnt) {
if (RemoveHouseTime != null) {
RemoveHouseTime.Destroy();
}
SendChatAll("XD_IVENT_CRATEHACKEND", (config.iventController.timeRemoveHouse2 / 60));
RemoveHouseTime = timer.Once(config.iventController.timeRemoveHouse2, () => {
SendChatAll("XD_IVENT_CRATELOOTFOUND");
StopIvent();
}
);
}
}
private bool Is3DPointValid(Vector3 point, int layer) {
List<Collider> colliders = Pool.GetList<Collider>();
Vis.Colliders(point, 25f, colliders, layer, QueryTriggerInteraction.Collide);
int count = colliders.Count;
foreach (Collider collider in colliders) {
if (collider == null || collider.transform == null) {
count--;
continue;
}
if (collider.name.Contains("SafeZone")) {
count = int.MaxValue;
continue;
}
BaseEntity e = collider.ToBaseEntity();
if (IsAsset(collider.name) && (e == null || e.name.Contains("/treessource/"))) {
count = int.MaxValue;
break;
}
if (e.IsValid()) {
if (e is BasePlayer) {
BasePlayer player = e as BasePlayer;
if (player.IsSleeping()) {
count--;
}
else if (player.IsNpc || player.IsFlying) {
count--;
}
else {
count = int.MaxValue;
break;
}
}
else if (e.OwnerID.IsSteamId()) {
count--;
}
else if (e.IsNpc || e is SleepingBag) {
count--;
}
else if (e is BaseOven) {
if (e.bounds.size.Max() > 1.6f) {
count = int.MaxValue;
break;
}
else {
count--;
}
}
else if (e is PlayerCorpse) {
PlayerCorpse corpse = e as PlayerCorpse;
if (corpse.playerSteamID == 0 || corpse.playerSteamID.IsSteamId()) {
count = int.MaxValue;
break;
}
else {
count--;
}
}
else if (e is DroppedItemContainer && e.prefabID != 545786656) {
DroppedItemContainer backpack = e as DroppedItemContainer;
if (backpack.playerSteamID == 0 || backpack.playerSteamID.IsSteamId()) {
count = int.MaxValue;
break;
}
else {
count--;
}
}
else if (e.OwnerID == 0) {
if (e is BuildingBlock) {
count = int.MaxValue;
break;
}
else {
count--;
}
}
else {
count = int.MaxValue;
break;
}
}
else if (collider.gameObject.layer == (int)Layer.World) {
if (collider.name.Contains("rock_") || collider.name.Contains("formation_", CompareOptions.OrdinalIgnoreCase)) {
float height = GetRockHeight(collider.transform.position);
if (height > 2f) {
count = int.MaxValue;
break;
}
else {
count--;
}
}
else if (!config.spawnPositionGenerateSetting.spawnOnRoad && collider.name.StartsWith("road_")) {
count = int.MaxValue;
break;
}
else if (collider.name.StartsWith("ice_sheet")) {
count = int.MaxValue;
break;
}
else {
count--;
}
}
else if (collider.gameObject.layer == (int)Layer.Water) {
if (!config.spawnPositionGenerateSetting.spawnOnRiver && collider.name.StartsWith("River Mesh")) {
count = int.MaxValue;
break;
}
count--;
}
else {
count--;
}
}
Pool.FreeList(ref colliders);
return count == 0;
}
private Coroutine setupBuildingRoutine {
get;
set;
}
= null;
private Configuration.BuildingPasteSettings.PasteBuild labIndex = null;
private HackableLockedCrate CrateEnt;
object CanCh47SpawnNpc(HackableLockedCrate crate) {
if (crate == CrateEnt) {
return true;
}
else {
return null;
}
}
private static bool ContainsTopology(TerrainTopology.Enum mask, Vector3 position, float radius) {
return (TerrainMeta.TopologyMap.GetTopology(position, radius) & (int)mask) != 0;
}
private readonly List<string> assets = new List<string> {
"/props/", "/structures/", "/building/", "train_", "powerline_", "dune", "candy-cane", "assets/content/nature/", "walkway", "invisible_collider"
}
;
private Timer RemoveHouseTime;
private float GetRockHeight(Vector3 a) {
RaycastHit hit;
if (Physics.Raycast(a + new Vector3(0f, 50f, 0f), Vector3.down, out hit, a.y + 51f, Layers.Mask.World, QueryTriggerInteraction.Ignore)) {
return Mathf.Abs(hit.point.y - a.y);
}
return 0f;
}
private HashSet<Vector3> busyPoints3D = new HashSet<Vector3>();
private void AddToContainerItem(ItemContainer container, Configuration.LootTableConfig lootTable) {
if (lootTable.UseCount) {
int count = Random.Range(lootTable.Min, lootTable.Max + 1);
HashSet<int> indexMove = new HashSet<int>();
while (indexMove.Count < count) {
foreach (Configuration.ItemConfig item in lootTable.Items) {
if (indexMove.Contains(lootTable.Items.IndexOf(item))) {
continue;
}
if (Random.Range(0.0f, 100.0f) <= item.Chance) {
Item newItem = item.IsBluePrint ? ItemManager.CreateByName("blueprintbase") : ItemManager.CreateByName(item.ShortName, Random.Range(item.MinAmount, item.MaxAmount + 1), item.SkinID);
if (newItem == null) {
PrintWarning($"Failed to create item! ({item.ShortName})");
continue;
}
if (item.IsBluePrint) {
newItem.blueprintTarget = ItemManager.FindItemDefinition(item.ShortName).itemid;
}
if (!string.IsNullOrEmpty(item.Name)) {
newItem.name = item.Name;
}
if (container.capacity < container.itemList.Count + 1) {
container.capacity++;
}
if (!newItem.MoveToContainer(container)) {
newItem.Remove();
}
else {
indexMove.Add(lootTable.Items.IndexOf(item));
if (indexMove.Count == count) {
return;
}
}
}
}
}
}
else {
HashSet<int> indexMove = new HashSet<int>();
foreach (Configuration.ItemConfig item in lootTable.Items) {
if (indexMove.Contains(lootTable.Items.IndexOf(item))) {
continue;
}
if (Random.Range(0.0f, 100.0f) <= item.Chance) {
Item newItem = item.IsBluePrint ? ItemManager.CreateByName("blueprintbase") : ItemManager.CreateByName(item.ShortName, Random.Range(item.MinAmount, item.MaxAmount + 1), item.SkinID);
if (newItem == null) {
PrintWarning($"Failed to create item! ({item.ShortName})");
continue;
}
if (item.IsBluePrint) {
newItem.blueprintTarget = ItemManager.FindItemDefinition(item.ShortName).itemid;
}
if (!string.IsNullOrEmpty(item.Name)) {
newItem.name = item.Name;
}
if (container.capacity < container.itemList.Count + 1) {
container.capacity++;
}
if (!newItem.MoveToContainer(container)) {
newItem.Remove();
}
else {
indexMove.Add(lootTable.Items.IndexOf(item));
}
}
}
}
}
private void StartIvent() {
if (!NpcSpawn) {
PrintError(GetLang("XD_IVENT_CLCONTROLLER_NOT_NPSSPAWN"));
Interface.Oxide.UnloadPlugin(Name);
return;
}
if (BasePlayer.activePlayerList.Count < config.iventController.minPlayedPlayers) {
Puts(GetLang("XD_IVENT_CLCONTROLLER_NOT_ENOUGH_PLAYERS"));
GenerateIvent();
return;
}
if (RemoveHouseTime != null) {
RemoveHouseTime.Destroy();
}
if (SpawnHouseTime != null) {
SpawnHouseTime.Destroy();
}
Subscribes();
labIndex = config.pasteSettings.pasteBuilds[0];
if (config.pasteSettings.pasteBuilds.Count > 1) {
labIndex = config.pasteSettings.pasteBuilds.GetRandom();
}
GenerateBuilding(labIndex);
}
private static string GetGridString(Vector3 position) {
return MapHelper.GridToString(MapHelper.PositionToGrid(position));
}
private void OnCrateHack(HackableLockedCrate crate) {
bool helpSpawn = false;
if (crate == CrateEnt) {
if (RemoveHouseTime != null) {
RemoveHouseTime.Destroy();
}
if (config.boxSetting.signaling) {
BaseEntity 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);
BaseEntity 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);
}
foreach (Configuration.BuildingPasteSettings.PresetConfig presset in labIndex.NpcPressets) {
if (presset.helpBot && presset.helpCount > 0) {
SpawnPreset(presset, crate.transform.position, true);
helpSpawn = true;
}
}
SendChatAll(helpSpawn ? "XD_IVENT_CRATEHACKHELP" : "XD_IVENT_CRATEHACK", PlayerHaked?.displayName, PosIvent);
Interface.CallHook("OnHackCobaltCrate", PlayerHaked);
}
}
private void LoadDataCopyPaste() {
foreach (var building in config.pasteSettings.pasteBuilds) {
if (!Interface.Oxide.DataFileSystem.ExistsDatafile("copypaste/" + building.housepath)) {
PrintError(GetLang("XD_EVENT_BUILDING_NOTFOUND", null, building.housepath));
NextTick(() => {
Interface.Oxide.UnloadPlugin(Name);
}
);
return;
}
}
}
private static XDCobaltLaboratory _;
private List<uint> Light = new List<uint> {
3887352222, 1889323056, 630866573, 172822834, 4027991414, 1392608348, 1748062128
}
;
private Vector3 GetCenterFromMultiplePoints(List<Vector3> foundations) {
if (foundations.Count <= 1) {
return Vector3.zero;
}
float x = 0f;
float z = 0f;
foreach (Vector3 position in foundations) {
x += position.x;
z += position.z;
}
Vector3 vector = new Vector3(x / foundations.Count, 0f, z / foundations.Count);
vector.y = GetSpawnHeight(vector);
return vector;
}
[ConsoleCommand("HideUi")]
void CMDHideUi(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (Player != null) {
if (!HideUIUser.Contains(player.userID.Get())) {
HideUIUser.Add(player.userID.Get());
CuiHelper.DestroyUi(player, "CobaltPanel");
}
else {
HideUIUser.Remove(player.userID.Get());
Cui.MainUI(player);
}
}
}
private readonly Quaternion[] directions = {
Quaternion.Euler(90, 0, 0), Quaternion.Euler(0, 0, 90), Quaternion.Euler(0, 0, 180)
}
;
private void ClearArea(ref Vector3 pos) {
List<ResourceEntity> ResourceList = new List<ResourceEntity>();
Vis.Entities(pos, 25f, ResourceList);
foreach (ResourceEntity item in ResourceList) {
item?.KillMessage();
}
}
public class Fields {
public string name {
get;
set;
}
public string value {
get;
set;
}
public bool inline {
get;
set;
}
public Fields(string name, string value, bool inline) {
this.name = name;
this.value = value;
this.inline = inline;
}
}
void Unsubscribes() {
foreach (string hook in hooks) {
Unsubscribe(hook);
}
}
object CanUILootSpawn(LootContainer container) {
if (container == null || CrateEnt == null) {
return null;
}
if (container == CrateEnt) {
if (config.boxSetting.TypeLootTable == 3) {
return null;
}
else {
return true;
}
}
else {
return null;
}
}
void OnEntityMounted(BaseMountable entity, BasePlayer player) {
if (HouseCobaltLab.Contains(entity?.GetParentEntity())) {
HouseCobaltLab.Remove(entity.GetParentEntity());
}
}
private List<ScientistNPC> npcs = new List<ScientistNPC>();
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 + MaxElevation, pPos.z + position.z);
Vector3 resultUnderPos = new Vector3(pPos.x + position.x, position.y - MaxElevation, pPos.z + position.z);
if (resultAbovePos.y >= TerrainMeta.HeightMap.GetHeight(resultAbovePos) && resultUnderPos.y <= TerrainMeta.HeightMap.GetHeight(resultUnderPos)) {
}
else {
return false;
}
}
}
return true;
}
private void RemoveMapMarker() {
if (config.mapMarkers.MapUse) {
Interface.CallHook("API_RemoveMarker", "xdcobaltlab");
}
}
private BasePlayer PlayerHaked;
private object GetSpawnPoints() {
if (busyPoints3D.ToList().Count <= 3) {
if (FindPositions == null) {
PrintWarning(GetLang("XD_IVENT_CLCONTROLLER_THE_POINTS_ARE_ENDED"));
busyPoints3D.Clear();
FindPositions = ServerMgr.Instance.StartCoroutine(GenerateSpawnPoints());
GenerateIvent();
}
return Vector3.zero;
}
Vector3 targetPos = busyPoints3D.ToList().GetRandom();
if (targetPos == Vector3.zero) {
busyPoints3D.Remove(targetPos);
return GetSpawnPoints();
}
bool valid = Is3DPointValid(targetPos, 1 << 8 | 1 << 9 | 1 << 17 | 1 << 21);
if (!valid || !HasBuildingPrivilege(targetPos, config.spawnPositionGenerateSetting.buildingBlockFindRadius)) {
busyPoints3D.Remove(targetPos);
return GetSpawnPoints();
}
busyPoints3D.Remove(targetPos);
ClearArea(ref targetPos);
return targetPos;
}
[ChatCommand("cl")]
void CLCommand(BasePlayer player, string cmd, string[] Args) {
if (!player.IsAdmin) {
return;
}
if (Args == null || Args.Length == 0) {
SendChatPlayer(GetLang("XD_IVENT_CLCONTROLLER_SYNTAX", player.UserIDString), player);
return;
}
switch (Args[0]) {
case "start" : {
if (SpawnHouseTime.Destroyed) {
PrintToChat(player, GetLang("XD_IVENT_CLCONTROLLER_ACTIVE", player.UserIDString));
}
else {
SpawnHouseTime.Destroy();
StartIvent();
}
break;
}
case "stop" : {
if (SpawnHouseTime.Destroyed) {
StopIvent();
SendChatAll(GetLang("XD_IVENT_CLCONTROLLER_STOPADMIN", player.UserIDString));
}
else {
SendChatPlayer(GetLang("XD_IVENT_CLCONTROLLER_NOT_ACTIVE", player.UserIDString), player);
}
break;
}
}
}
private void SendChatAll(string Message, params object[] args) {
if (!string.IsNullOrEmpty(config.notiferSettings.weebHook)) {
string msg = GetLang(Message, null, args);
SendDiscordMsg(GetLang(Message + "_DISCORD", null, args));
}
foreach (BasePlayer player in BasePlayer.activePlayerList) {
SendChatPlayer(GetLang(Message, player.UserIDString, args), player);
}
}
void Unload() {
StopIvent(true);
_ = null;
}
private Coroutine FindPositions;
private const float MaxElevation = 2.5f;
void OnEntityDeath(BasePlayer player, HitInfo info) {
if (player == null || info == null) {
return;
}
else if (npcZones != null && npcZones.playersInZone.Contains(player)) {
npcZones.playersInZone.Remove(player);
}
}
protected override void LoadDefaultConfig() {
config = new Configuration();
}
private IEnumerator SetupBuilding() {
BaseEntity box = null;
List<CCTV_RC> cam = new List<CCTV_RC>();
List<Vector3> foundations = new List<Vector3>();
ComputerStation comp = null;
foreach (BaseEntity ent in HouseCobaltLab.ToArray()) {
if (!CanSetupEntity(ent)) {
yield return CoroutineEx.waitForSeconds(0.01f);
continue;
}
if (ent is BaseCombatEntity) {
(ent as BaseCombatEntity).pickup.enabled = false;
}
if (ent is Minicopter) {
if (Random.Range(0, 100) >= (100 - labIndex.copterChance)) {
Minicopter copter = (ent as Minicopter);
copter.GetFuelSystem().AddFuel(50);
copter.transform.position = new Vector3(copter.transform.position.x, copter.transform.position.y, copter.transform.position.z);
}
else {
NextTick(() => {
HouseCobaltLab.Remove(ent);
ent.Kill();
}
);
}
continue;
}
ent.OwnerID = 342968945867;
if (Light.Contains(ent.prefabID)) {
ent.SetFlag(BaseEntity.Flags.On, true);
}
if (ent.skinID == 22848) {
BaseEntity CrateEnt = GameManager.server.CreateEntity("assets/prefabs/io/electric/lights/sirenlightorange.prefab", ent.transform.position, ent.transform.rotation, true);
CrateEnt.Spawn();
if (CrateEnt is IOEntity) {
CrateEnt.SetFlag(BaseEntity.Flags.Reserved8, true);
CrateEnt.SetFlag(BaseEntity.Flags.On, true);
}
NextTick(() => {
HouseCobaltLab.Remove(ent);
ent.Kill();
HouseCobaltLab.Add(CrateEnt);
}
);
}
// ... [Code preview truncated due to length. Full source in attached file] ...