C#:
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using Newtonsoft.Json;
using System;
namespace Oxide.Plugins {
[Info("BuildingUp", "https://topplugin.ru/", "1.0.1")]
public class BuildingUp : RustPlugin {
#region [Vars]
private PluginConfig config;
private Dictionary<uint, int> UpPlans = new Dictionary<uint, int>();
private List<uint> UpBuildings = new List<uint>();
private Dictionary<ulong, int> broadcastchatPlayer = new Dictionary<ulong, int>();
#endregion
#region [Config]
protected override void LoadDefaultConfig() {
config = PluginConfig.DefaultConfig();
}
protected override void LoadConfig() {
base.LoadConfig();
config = Config.ReadObject<PluginConfig>();
if (config.PluginVersion < Version) UpdateConfigValues();
Config.WriteObject(config, true);
}
private void UpdateConfigValues() {
PrintWarning("Config update detected! Updating config values...");
PluginConfig baseConfig = PluginConfig.DefaultConfig();
if (config.PluginVersion < new VersionNumber(1, 0, 1)) {
}
config.PluginVersion = Version;
PrintWarning("Config update completed!");
}
protected override void SaveConfig() {
Config.WriteObject(config);
}
private class PluginConfig {
[JsonProperty("Настройки предмета для улучшения плана постройки")]
public itemUp itemUpSettings;
[JsonProperty("Настройки улучшенного плана постройки")]
public itemBuildingPlan itemBPSettings;
[JsonProperty("Настройки оповещений")]
public BroadcastSettings broadcastSettings;
[JsonProperty("Версия конфига")]
public VersionNumber PluginVersion = new VersionNumber();
public static PluginConfig DefaultConfig() {
return new PluginConfig() {
itemUpSettings = new itemUp() {
itemName = "Титаниум", itemSkinId = 2324046251, itemUpCount = 5, itemDropBarrels = 50, itemDropContainers = new Dictionary<string, int>() {
["crate_normal"]
= 50, ["crate_normal_2"] = 50, ["crate_elite"] = 50
}
}
, itemBPSettings = new itemBuildingPlan() {
itemName = "Улучшенный план постройки", itemSkinId = 2324056369, itemPercentProtect = 50
}
, broadcastSettings = new BroadcastSettings() {
broadcastUp = 2, broadcastChatAttack = true, broadcastChatAttackTime = 3, Amin = "0.678 0.021", Amax = "0.825 0.053"
}
, PluginVersion = new VersionNumber()
}
;
}
}
public class itemUp {
[JsonProperty("СкинАйди")]
public ulong itemSkinId;
[JsonProperty("Название")]
public string itemName;
[JsonProperty("Сколько построек дает 1 предмет")]
public int itemUpCount;
[JsonProperty("Процент выпадения из бочек (от 1 до 100, если 0 то выкл)")]
public int itemDropBarrels;
[JsonProperty("Процент выпадения из ящиков (от 1 до 100)")]
public Dictionary<string, int> itemDropContainers;
}
public class itemBuildingPlan {
[JsonProperty("СкинАйди")]
public ulong itemSkinId;
[JsonProperty("Название")]
public string itemName;
[JsonProperty("На сколько процентов защищать строение (от 1 до 100)")]
public int itemPercentProtect;
}
public class BroadcastSettings {
[JsonProperty("Выводить ли сообщение в чат о защищенности постройки (при нанесении по ней урона)")]
public bool broadcastChatAttack;
[JsonProperty("Задержка перед повторным сообщением в секундах (при нанесении по ней урона)")]
public int broadcastChatAttackTime;
[JsonProperty("Выводить ли информацию о количестве улучшений (0 -выкл, 1 - чат, 2 - UI)")]
public int broadcastUp;
[JsonProperty("UI Amin")]
public string Amin;
[JsonProperty("UI Amax")]
public string Amax;
}
#endregion
#region [Oxide]
private object OnLootSpawn(LootContainer container) {
if (container == null) return null;
if (config.itemUpSettings.itemDropContainers.ContainsKey(container.ShortPrefabName)) {
var rn = UnityEngine.Random.Range(1, 101);
if (rn > config.itemUpSettings.itemDropContainers[container.ShortPrefabName]) return null;
Item item = ItemManager.CreateByName("glue", 1, config.itemUpSettings.itemSkinId);
item.name = config.itemUpSettings.itemName;
item.MoveToContainer(container.inventory);
return null;
}
if (config.itemUpSettings.itemDropBarrels > 0 && container.ShortPrefabName.Contains("barrel")) {
var rn = UnityEngine.Random.Range(1, 101);
if (rn > config.itemUpSettings.itemDropBarrels) return null;
Item item = ItemManager.CreateByName("glue", 1, config.itemUpSettings.itemSkinId);
item.name = config.itemUpSettings.itemName;
item.MoveToContainer(container.inventory);
return null;
}
return null;
}
private void OnEntityKill(BaseNetworkable entity) {
if (entity == null) return;
if (entity?.net?.ID == null) return;
if (UpBuildings.Contains(entity.net.ID)) {
UpBuildings.Remove(entity.net.ID);
return;
}
if (UpPlans.ContainsKey(entity.net.ID)) UpPlans.Remove(entity.net.ID);
}
private void OnEntityBuilt(Planner plan, GameObject gameObject) {
var player = plan?.GetOwnerPlayer();
if (player == null) return;
var item = player.GetActiveItem();
if (item.info.shortname != "building.planner") return;
var netid = item.GetHeldEntity().net.ID;
if (!UpPlans.ContainsKey(netid)) return;
var buildingBlock = gameObject.GetComponent<BuildingBlock>();
if (buildingBlock == null) return;
if (UpPlans[netid] <= 0) return;
UpPlans[netid]--;
UpBuildings.Add(buildingBlock.net.ID);
if(config.broadcastSettings.broadcastUp == 1) player.ChatMessage($"Осталось <color=orange>{UpPlans[netid]}</color> улучшений");
else if(config.broadcastSettings.broadcastUp == 2) BroadcastUI(player, netid);
if(UpPlans[netid] <= 0) {
CuiHelper.DestroyUi(player, "planMain");
UpPlans.Remove(netid);
item.skin = 0;
item.name = item.info.displayName.translated;
item.MarkDirty();
}
}
private object CanCombineDroppedItem(DroppedItem drItem, DroppedItem anotherDrItem) {
if (drItem.item.info.shortname == "glue" && anotherDrItem.item.info.shortname == "glue") {
if (drItem.item.skin != anotherDrItem.item.skin) return false;
}
return null;
}
private object OnItemSplit(Item item, int split_Amount) {
if (item.info.shortname == "glue" && item.skin == config.itemBPSettings.itemSkinId || item.skin == config.itemUpSettings.itemSkinId) {
Item byItemId = ItemManager.CreateByItemID(item.info.itemid, 1, item.skin);
item.amount -= split_Amount;
byItemId.amount = split_Amount;
byItemId.name = item.name;
item.MarkDirty();
return byItemId;
}
return null;
}
private object CanStackItem(Item item, Item targetItem) {
if (item.info.shortname == "glue" && targetItem.info.shortname == "glue") {
if (targetItem.skin != item.skin) return false;
}
return null;
}
private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
if (info == null || entity == null || info?.Initiator == null) return;
if (entity?.net?.ID == null) return;
if (UpBuildings.Contains(entity.net.ID)) {
info.damageTypes.ScaleAll(1f - (config.itemBPSettings.itemPercentProtect / 100f));
if (config.broadcastSettings.broadcastChatAttack) {
var player = info.Initiator?.ToPlayer();
if (player == null) return;
if (!broadcastchatPlayer.ContainsKey(player.userID)) broadcastchatPlayer.Add(player.userID, Facepunch.Math.Epoch.Current - config.broadcastSettings.broadcastChatAttackTime);
if (Facepunch.Math.Epoch.Current - broadcastchatPlayer[player.userID] < config.broadcastSettings.broadcastChatAttackTime) return;
broadcastchatPlayer[player.userID] = Facepunch.Math.Epoch.Current;
player.ChatMessage($"Данное строение защищено на {config.itemBPSettings.itemPercentProtect}% от урона");
}
}
}
private object CanMoveItem(Item item, PlayerInventory playerLoot, uint targetContainer, int targetSlot, int amount) {
if (item == null || playerLoot == null) return null;
var player = playerLoot.GetComponent<BasePlayer>();
if (player == null) return null;
if (item.skin != config.itemUpSettings.itemSkinId) return null;
var container = playerLoot.FindContainer(targetContainer);
if (container == null) return null;
var targetItem = container.GetSlot(targetSlot);
if (targetItem == null || targetItem.info.shortname != "building.planner") return null;
Effect effect = new Effect("assets/bundled/prefabs/fx/notice/item.select.fx.prefab", player, 0, new Vector3(), new Vector3());
EffectNetwork.Send(effect, player.Connection);
if (!UpPlans.ContainsKey(targetItem.GetHeldEntity().net.ID)) {
UpPlans.Add(targetItem.GetHeldEntity().net.ID, amount * config.itemUpSettings.itemUpCount);
item.UseItem(amount);
targetItem.name = config.itemBPSettings.itemName;
targetItem.skin = config.itemBPSettings.itemSkinId;
targetItem.MarkDirty();
player.ChatMessage($"У плана постройки теперь <color=orange>{UpPlans[targetItem.GetHeldEntity().net.ID]}</color> улучшений");
return false;
}
UpPlans[targetItem.GetHeldEntity().net.ID] += amount * config.itemUpSettings.itemUpCount;
item.UseItem(amount);
player.ChatMessage($"У плана постройки теперь <color=orange>{UpPlans[targetItem.GetHeldEntity().net.ID]}</color> улучшений ");
return false;
}
private void OnActiveItemChanged(BasePlayer player, Item oldItem, Item newItem) {
if (player == null) return;
if (newItem == null) {
CuiHelper.DestroyUi(player, "planMain");
return;
}
if (newItem.GetHeldEntity()?.net?.ID == null) return;
if (UpPlans.ContainsKey(newItem.GetHeldEntity().net.ID)) BroadcastUI(player, newItem.GetHeldEntity().net.ID);
else CuiHelper.DestroyUi(player, "planMain");
return;
}
#endregion
#region [Functions]
private void GiveCrystal(BasePlayer player, int amount = 1) {
Item item = ItemManager.CreateByName("glue", amount, config.itemUpSettings.itemSkinId);
item.name = config.itemUpSettings.itemName;
player.GiveItem(item);
}
private void GiveBp(BasePlayer player, int amount = 1) {
Item item = ItemManager.CreateByName("building.planner", 1, config.itemBPSettings.itemSkinId);
item.name = config.itemBPSettings.itemName;
player.GiveItem(item);
UpPlans.Add(item.GetHeldEntity().net.ID, amount);
}
#endregion
#region [Command]
[ChatCommand("aup")]
private void AdminCommandUP(BasePlayer player, string c, string[] args) {
if (!player.IsAdmin) return;
if(args.Length < 1) {
player.ChatMessage("Ошибка ввода команды\n/aup crystal Кол-во\n/aup bp 'Кол-во Построек'");
return;
}
if(args[0] == "crystal") {
if(args.Length < 2) {
player.ChatMessage("Ошибка ввода команды\n/aup crystal Кол-во");
return;
}
GiveCrystal(player, Convert.ToInt32(args[1]));
}
if(args[0] == "bp") {
if (args.Length < 2) {
player.ChatMessage("Ошибка ввода команды\n/aup bp 'Кол-во Построек'");
return;
}
GiveBp(player, Convert.ToInt32(args[1]));
}
}
#endregion
#region [UI]
private void BroadcastUI(BasePlayer player, uint planUid) {
if (!UpPlans.ContainsKey(planUid)) return;
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Parent = "Hud", Name = "planMain", Components = {
new CuiImageComponent {
Color = "0 0 0 0", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat"
}
, new CuiRectTransformComponent {
AnchorMin = config.broadcastSettings.Amin, AnchorMax = config.broadcastSettings.Amax
}
}
}
);
UI.CreatePanel(ref container, "planMainMask", "planMain", $"0.83 0.83 0.83 0.25", "0 0", "1 1");
UI.CreateTextOutLine(ref container, "planMainMask", $"{UpPlans[planUid]} улучшений", $"1 1 1 0.75", $"0 0", $"1 1", TextAnchor.MiddleCenter, 18);
CuiHelper.DestroyUi(player, "planMain");
CuiHelper.AddUi(player, container);
}
#region [UI generator]
public class UI {
public static void CreatePanel(ref CuiElementContainer container, string name, string parent, string color, string aMin, string aMax, float Fadeout = 0f, float Fadein = 0f) {
container.Add(new CuiElement {
Name = name, Parent = parent, Components = {
new CuiImageComponent {
Color = color, FadeIn = Fadein
}
, new CuiRectTransformComponent {
AnchorMin = aMin, AnchorMax = aMax
}
}
, FadeOut = Fadeout
}
);
}
public static void CreateTextOutLine(ref CuiElementContainer container, string parent, string text, string color, string aMin, string aMax, TextAnchor align = TextAnchor.MiddleLeft, int size = 14, string name = "name", float Fadein = 0f) {
container.Add(new CuiElement {
Parent = parent, Name = name, Components = {
new CuiTextComponent() {
Color = color, Text = text, FontSize = size, Align = align, FadeIn = Fadein
}
, new CuiRectTransformComponent {
AnchorMin = aMin , AnchorMax = aMax
}
, new CuiOutlineComponent {
Color = "0 0 0 1"
}
}
}
);
}
}
#endregion
#endregion
#region [Data]
void LoadData() {
UpPlans = Interface.GetMod().DataFileSystem.ReadObject<Dictionary<uint, int>>($"BuildingUp/Plans");
UpBuildings = Interface.GetMod().DataFileSystem.ReadObject<List<uint>>("BuildingUp/Buildings");
}
void SaveData() {
Interface.Oxide.DataFileSystem.WriteObject("BuildingUp/Plans", UpPlans);
Interface.Oxide.DataFileSystem.WriteObject("BuildingUp/Buildings", UpBuildings);
}
void OnServerSave() => SaveData();
void Unload() => SaveData();
void Init() => LoadData();
void OnNewSave() {
UpPlans.Clear();
UpBuildings.Clear();
SaveData();
PrintWarning("Wipe detect! Data clearing");
}
#endregion
}
}