C#:
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Facepunch;
using Rust;
namespace Oxide.Plugins {
[Info("RandomBox", "Mercury", "0.0.1")]
[Description("Случайный подарок на карте")]
class RandomBox : RustPlugin {
[PluginReference]
Plugin IQChat;
public void SendChat(string Message, BasePlayer player, ConVar.Chat.ChatChannel channel = ConVar.Chat.ChatChannel.Global) {
if (IQChat) IQChat?.Call("API_ALERT_PLAYER", player, Message, "[КОРОБКА] ");
else player.SendConsoleCommand("chat.add", channel, 0, Message);
}
#region Configuration
private static Configuration config = new Configuration();
private class Configuration {
[JsonProperty("Shortname ящика")]
public string ShortnameBox;
[JsonProperty("Список предметов в ящике")]
public List<string> ItemForBox = new List<string>();
[JsonProperty("Раз в сколько спавнить ящик(секундны)")]
public int SecondSpawn;
[JsonProperty("Через сколько секунд после спавна ящик пропадет")]
public int SecondDeSpawn;
public static Configuration GetNewConfiguration() {
return new Configuration {
SecondSpawn = 60, SecondDeSpawn = 20, ShortnameBox = "assets/prefabs/deployable/large wood storage/box.wooden.large.prefab", ItemForBox = new List<string> {
"xmas.present.large", "xmas.present.large", "xmas.present.large", "xmas.present.large", "xmas.present.large", "xmas.present.large",
}
}
;
}
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) LoadDefaultConfig();
}
catch {
PrintWarning($"Ошибка чтения #2070 конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
LoadDefaultConfig();
}
NextTick(SaveConfig);
}
protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Hooks
private void OnServerInitialized() => EventStart();
void OnLootEntity(BasePlayer player, BaseEntity entity) {
if (entity == null || player == null) return;
if (entity.GetComponent<StorageContainer>() == null) return;
if (entity.skinID != 1337228) return;
entity.skinID = player.userID;
foreach (var p in BasePlayer.activePlayerList) SendChat(String.Format(lang.GetMessage("CREATE_FINDING", this, p.UserIDString)), p);
EventStart();
}
#endregion
#region Metods
#region EventStartMetods
void EventStart() {
timer.Once(config.SecondSpawn, () => {
Vector3 pos = GetEventPosition();
BaseEntity Item = GameManager.server.CreateEntity(config.ShortnameBox, pos);
if (Item == null) {
return;
}
Item.skinID = 1337228;
Item.Spawn();
for (int i = 0; i < config.ItemForBox.Count; i++) {
var RewardCFG = config.ItemForBox[i];
Item Reward = ItemManager.CreateByName(RewardCFG, 1);
Reward.MoveToContainer(Item.GetComponent<StorageContainer>().inventory);
}
foreach (var p in BasePlayer.activePlayerList) SendChat(String.Format(lang.GetMessage("CREATE_SPAWN", this, p.UserIDString), GetGridString(pos)), p);
EventStop(Item);
}
);
}
void EventStop(BaseEntity Item) {
timer.Once(config.SecondDeSpawn, () => {
if (Item.skinID != 1337228) return;
Item.Kill();
foreach (var p in BasePlayer.activePlayerList) SendChat(String.Format(lang.GetMessage("CREATE_NO_FINDING", this, p.UserIDString)), p);
EventStart();
}
);
}
#endregion
#region SearchCase
private string GetGridString(Vector3 position) {
Vector2 adjPosition = new Vector2((World.Size / 2f) + position.x, (World.Size / 2f) - position.z);
return $"{NumberToString((int)(adjPosition.x / 150f))}{(int)(adjPosition.y / 150f)}";
}
private string NumberToString(int number) {
bool a = number > 25;
Char c = (Char)(65 + (a ? number - 26 : number));
return a ? "A" + c : c.ToString();
}
#endregion
#region SpawnMetods
SpawnFilter filter = new SpawnFilter();
List<Vector3> monuments = new List<Vector3>();
static float GetGroundPosition(Vector3 pos) {
float y = TerrainMeta.HeightMap.GetHeight(pos);
RaycastHit hit;
if (UnityEngine.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;
}
public Vector3 RandomDropPosition() {
var vector = Vector3.zero;
float num = 1000f, x = TerrainMeta.Size.x / 3;
do {
vector = Vector3Ex.Range(-x, x);
}
while (filter.GetFactor(vector) == 0f && (num -= 1f) > 0f);
float max = TerrainMeta.Size.x / 2;
float height = TerrainMeta.HeightMap.GetHeight(vector);
vector.y = height;
return vector;
}
List<int> BlockedLayers = new List<int> {
(int)Layer.Water, (int)Layer.Construction, (int)Layer.Trigger, (int)Layer.Prevent_Building, (int)Layer.Deployed, (int)Layer.Tree
}
;
static int blockedMask = LayerMask.GetMask(new[] {
"Player (Server)", "Trigger", "Prevent Building"
}
);
public Vector3 GetSafeDropPosition(Vector3 position) {
RaycastHit hit;
position.y += 200f;
if (UnityEngine.Physics.Raycast(position, Vector3.down, out hit)) {
if (hit.collider?.gameObject == null) return Vector3.zero;
string ColName = hit.collider.name;
if (!BlockedLayers.Contains(hit.collider.gameObject.layer) && ColName != "MeshColliderBatch" && ColName != "iceberg_3" && ColName != "iceberg_2" && !ColName.Contains("rock_cliff")) {
position.y = Mathf.Max(hit.point.y, TerrainMeta.HeightMap.GetHeight(position));
var colliders = Pool.GetList<Collider>();
Vis.Colliders(position, 1, colliders, blockedMask, QueryTriggerInteraction.Collide);
bool blocked = colliders.Count > 0;
Pool.FreeList<Collider>(ref colliders);
if (!blocked) return position;
}
}
return Vector3.zero;
}
public Vector3 GetEventPosition() {
var eventPos = Vector3.zero;
int maxRetries = 100;
monuments = UnityEngine.Object.FindObjectsOfType<MonumentInfo>().Select(monument => monument.transform.position).ToList();
do {
eventPos = GetSafeDropPosition(RandomDropPosition());
foreach (var monument in monuments) {
if (Vector3.Distance(eventPos, monument) < 250f) {
eventPos = Vector3.zero;
break;
}
}
}
while (eventPos == Vector3.zero && --maxRetries > 0);
eventPos.y = GetGroundPosition(eventPos);
if (eventPos.y < 0) GetEventPosition();
return eventPos;
}
#endregion
#endregion
#region Lang
private new void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["CREATE_SPAWN"]
= "<color=#FFC040><color=#ff6040>Crate</color> with loot was created! Points: {0} </color>", ["CREATE_FINDING"] = "<color=#FFC040>Someone found a crate!</color>", ["CREATE_NO_FINDING"] = "<color=#FFC040> Oops, no one found a crate!</color>",
}
, this);
lang.RegisterMessages(new Dictionary<string, string> {
["CREATE_SPAWN"]
= "<color=#FFC040>Появилась <color=#ff6040>коробка с подарками</color>! Скорее найди ее! Место положение: {0} </color>", ["CREATE_FINDING"] = "<color=#FFC040>Кто-то нашел подарки!</color>", ["CREATE_NO_FINDING"] = "<color=#FFC040>Упс, никто не нашёл подарки!</color>",
}
, this, "ru");
PrintWarning("Языковой файл загружен успешно");
}
#endregion
}
}