C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
/* Documentation =>
* Commands:
* quarry.give «SteamID» «SkinID» => give to player the quarry with specified skin from config
* quarry.giveme => give all quarries from config to self
* Permissions:
* aQuarry.admin => allows to use commands from in-game console
*
* Copyright © 2022-2024 AvG Лаймон (Email: alias.dev@ya.ru | Discord: avglimon | Alias™ development team: https://discord.gg/MWeNJV5e7F) */
using Newtonsoft.Json;
using Oxide.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Oxide.Game.Rust.Cui;
using static Oxide.Game.Rust.Cui.CuiHelper;
using static MiningQuarry;
using static ConsoleSystem;
namespace Oxide.Plugins {
[Info("aQuarry", "AvG Лаймон", "2.0.2")]
class aQuarry : RustPlugin {
#region [Initialization]
private static aQuarry instance;
private const bool Rus = false;
private const string adminPerm = "aQuarry.admin";
private void Init() {
UnsubscribeAll();
instance = this;
}
private void OnServerInitialized() {
LoadConfigData();
LoadLangFiles();
RegisterPermissions();
GenerateUI();
timer.In(1f, LoadCustomQuarries);
}
private void Unload() {
DestroyCustomQuarries();
foreach(BasePlayer player in BasePlayer.activePlayerList) CloseUI(player, true);
instance = null;
}
#endregion
#region [Library]
private static readonly float[] protection = new float[25] {
0.9f, 0, 0, 0, 0, 0.95f, 0, 0, 0, 0.99f, 0.99f, 0.99f, 0, 1, 1, 0.99f, 0.5f, 0, 0, 0, 0, 1, 1, 1, 0
}
;
private Dictionary<QuarryType, ulong> staticSkins = new Dictionary<QuarryType, ulong> {
[QuarryType.None]
= 3969321, [QuarryType.Basic] = 3969322, [QuarryType.Sulfur] = 3969323, [QuarryType.HQM] = 3969324
}
;
#endregion
#region [Data]
private Dictionary<ulong, LimitsData> limitsData = new Dictionary<ulong, LimitsData>();
private class LimitsData : BuildLimits {
internal int placedQuarries = 0;
internal int placedJacks = 0;
internal void Sum(BuildLimits limit) {
this.limitQuarries += limit.limitQuarries;
this.limitJacks += limit.limitJacks;
}
internal void Reset() {
limitQuarries = 0;
limitJacks = 0;
}
}
private Dictionary<ulong, QuarryCash> quarryCash = new Dictionary<ulong, QuarryCash>();
private class QuarryCash {
public bool isOn;
public float hp;
public float pendingWork = 0;
public float workDone = 0;
public int fuelID = 0;
public ulong fuelSkin = 0;
}
#endregion
#region [Configuration]
private Configuration DefaultConfig() {
Configuration config = new Configuration();
config.Limit.permissions.Add("aQuarry.default", new BuildLimits());
config.Limit.permissions.Add("aQuarry.vip", new BuildLimits {
priority = 1, limitQuarries = 4, limitJacks = 2
}
);
config.Limit.permissions.Add("aQuarry.admin", new BuildLimits {
priority = 999, limitQuarries = 999, limitJacks = 999
}
);
config.Rates.permissions.Add("aQuarry.vip", 0.2f);
config.Rates.permissions.Add("aQuarry.admin", 1f);
return config;
}
protected override void LoadDefaultConfig() {
PrintWarning(Rus ? "Создание базовой конфигурации..." : "Creating a default config...");
config = DefaultConfig();
config.PluginVersion = Version;
Interface.Oxide.DataFileSystem.GetFile("aQuarry/StaticQuarries/test").WriteObject("");
Interface.Oxide.DataFileSystem.DeleteDataFile("aQuarry/StaticQuarries/test");
Interface.Oxide.DataFileSystem.GetFile("aQuarry/PersonalQuarries/test").WriteObject("");
Interface.Oxide.DataFileSystem.DeleteDataFile("aQuarry/PersonalQuarries/test");
PrintWarning(Rus ? "Создание базовой конфигурации завершено!" : "Default config has been created!");
}
protected override void LoadConfig() {
base.LoadConfig();
config = Config.ReadObject<Configuration>();
}
private void UpdateConfigValues() {
PrintWarning(Rus ? "Обнаружено обновление плагина! Автоматическое обновление конфигурации..." : "Config update detected! Updating config values...");
if (config.PluginVersion < new VersionNumber(2, 0, 0)) {
PrintWarning("Old configuration file will not work! Removing...");
LoadDefaultConfig();
}
else if (config.PluginVersion < new VersionNumber(2, 0, 2)) {
PrintWarning("Updating Data files...");
}
config.PluginVersion = Version;
PrintWarning(Rus ? "Обновление конфигурации успешно!" : "Config update completed!");
}
private bool ValidateConfig() {
bool update = false;
if (config.PluginVersion < Version) {
update = true;
UpdateConfigValues();
}
if (config.plugins.aHomeManager) config.optimization.disableLimits = true;
SaveConfig();
return update;
}
private void DefaultStaticData(int index) {
string[] fileNames = new string[4] {
"StaticPumpjack", "StaticStoneQuarry", "StaticSulfurQuarry", "StaticHQMQuarry"
}
;
string[] shortNames = new string[4] {
"lowgradefuel", "stones", "sulfur.ore", "hq.metal.ore"
}
;
BaseQuarry quarry = new BaseQuarry();
quarry.Production.fuelList.Add(new FuelProduction {
shortname = "diesel_barrel", amount = 1, resources = new List<ResourceItem> {
new ResourceItem {
shortname = shortNames[index]
}
}
}
);
Interface.Oxide.DataFileSystem.GetFile($"aQuarry/StaticQuarries/{fileNames[index]}").WriteObject(quarry);
}
private void DefaultPersonalData() {
ulong[] quarrySkins = new ulong[6] {
3187637123, 3185891808, 3185893553, 3185893848, 3185894100, 3185894375
}
;
QRepair repair = new QRepair {
allow = true, blockTime = 30f, repair = 100f, needCost = true, Cost = new List<CustomItem> {
new CustomItem {
shortname = "metal.fragments", skin = 0, amount = 500
}
}
}
;
string[] upgradeShortnames = new string[10] {
"wood", "stones", "metal.fragments", "metal.refined", "leather", "carburetor3", "scrap", "rope", "sheetmetal", "tarp"
}
;
int[] upgradeAmountsBase = new int[10] {
10000, 5000, 0, 0, 0, 1, 500, 5, 5, 5
}
;
int[] upgradeAmountsPerLvl = new int[10] {
2000, 1000, 500, 10, 100, 0, 150, 0, 0, 0
}
;
for (int lvl = 0; lvl < quarrySkins.Length; lvl++) {
PersonalQuarry quarry = new PersonalQuarry();
quarry.skin = quarrySkins[lvl];
quarry.enable = true;
quarry.name = lvl == 0 ? "Personal Quarry" : $"Personal Quarry Lvl {lvl}";
quarry.Structure.health = 2500f + 500f * lvl;
quarry.Structure.protection = 10f * lvl;
quarry.Remove.itemList.Add(new NamedItem {
name = quarry.name, shortname = "furnace.large", amount = 1, skin = quarry.skin
}
);
if (lvl + 1 < quarrySkins.Length) quarry.Upgrade.newSkin = quarrySkins[lvl + 1];
for (int item = 0; item < upgradeShortnames.Length; item++) {
if (lvl == quarrySkins.Length - 1) break;
int amount = upgradeAmountsBase[item] + upgradeAmountsPerLvl[item] * (lvl + 1);
if (amount > 0) quarry.Upgrade.Cost.Add(new CustomItem {
shortname = upgradeShortnames[item], amount = amount
}
);
}
quarry.Inventory.lootSize = 6 + 6 * lvl;
quarry.Inventory.fuelSize = 1 + 1 * lvl;
quarry.Repair = repair;
quarry.Production.fuelList.Add(new FuelProduction {
shortname = "lowgradefuel", skin = 0, amount = 50, fuelTimer = 60, productionTimer = 60
}
);
quarry.Production.fuelList[0].resources.Add(new ResourceItem {
shortname = "stones", amount = 100 + 10 * lvl, amountMax = 100 + 10 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[0].resources.Add(new ResourceItem {
shortname = "metal.ore", amount = 70 + 7 * lvl, amountMax = 70 + 7 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[0].resources.Add(new ResourceItem {
shortname = "sulfur.ore", amount = 50 + 5 * lvl, amountMax = 50 + 5 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[0].resources.Add(new ResourceItem {
shortname = "hq.metal.ore", amount = 10 + 1 * lvl, amountMax = 10 + 1 * lvl, skin = 0, chance = 10f
}
);
quarry.Production.fuelList.Add(new FuelProduction {
shortname = "crude.oil", skin = 0, amount = 30, fuelTimer = 120, productionTimer = 60
}
);
quarry.Production.fuelList[1].resources.Add(new ResourceItem {
shortname = "stones", amount = 100 + 10 * lvl, amountMax = 100 + 10 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[1].resources.Add(new ResourceItem {
shortname = "metal.ore", amount = 70 + 7 * lvl, amountMax = 70 + 7 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[1].resources.Add(new ResourceItem {
shortname = "sulfur.ore", amount = 50 + 5 * lvl, amountMax = 50 + 5 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[1].resources.Add(new ResourceItem {
shortname = "charcoal", amount = 30 + 3 * lvl, amountMax = 30 + 3 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[1].resources.Add(new ResourceItem {
shortname = "hq.metal.ore", amount = 10 + 1 * lvl, amountMax = 10 + 1 * lvl, skin = 0, chance = 10f
}
);
quarry.Production.fuelList.Add(new FuelProduction {
shortname = "diesel_barrel", skin = 0, amount = 1, fuelTimer = 600, productionTimer = 120
}
);
quarry.Production.fuelList[2].resources.Add(new ResourceItem {
shortname = "stones", amount = 400 + 40 * lvl, amountMax = 400 + 40 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[2].resources.Add(new ResourceItem {
shortname = "metal.ore", amount = 280 + 28 * lvl, amountMax = 280 + 28 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[2].resources.Add(new ResourceItem {
shortname = "sulfur.ore", amount = 200 + 20 * lvl, amountMax = 200 + 20 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[2].resources.Add(new ResourceItem {
shortname = "charcoal", amount = 120 + 12 * lvl, amountMax = 120 + 12 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[2].resources.Add(new ResourceItem {
shortname = "hq.metal.ore", amount = 40 + 4 * lvl, amountMax = 40 + 4 * lvl, skin = 0, chance = 20f
}
);
quarry.Production.fuelList.Add(new FuelProduction {
shortname = "glue", skin = 3188057178, amount = 5, fuelTimer = 180, productionTimer = 90
}
);
quarry.Production.fuelList[3].resources.Add(new ResourceItem {
shortname = "gunpowder", amount = 150 + 15 * lvl, amountMax = 150 + 15 * lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[3].resources.Add(new ResourceItem {
shortname = "hq.metal.ore", amount = 10 + lvl, amountMax = 10 + lvl, skin = 0, chance = 50f
}
);
quarry.Production.fuelList[3].resources.Add(new ResourceItem {
shortname = "explosives", amount = 1, amountMax = 1, skin = 0, chance = 10f + (float)lvl / 2, disableRate = true
}
);
Interface.Oxide.DataFileSystem.GetFile($"aQuarry/PersonalQuarries/Quarry{(lvl == 0 ? "00" : $"0 {
lvl
}
")}").WriteObject(quarry);
}
quarrySkins = new ulong[6] {
3188075788, 3185901475, 3185901854, 3185902403, 3185902634, 3185902821
}
;
upgradeShortnames = new string[10] {
"wood", "stones", "metal.fragments", "metal.refined", "leather", "carburetor3", "scrap", "rope", "sheetmetal", "tarp"
}
;
upgradeAmountsBase = new int[10] {
10000, 5000, 1000, 50, 500, 1, 0, 2, 2, 2
}
;
upgradeAmountsPerLvl = new int[10] {
2000, 500, 300, 15, 50, 0, 100, 0, 0, 0
}
;
for (int lvl = 0; lvl < quarrySkins.Length; lvl++) {
PersonalQuarry quarry = new PersonalQuarry();
quarry.skin = quarrySkins[lvl];
quarry.enable = true;
quarry.name = lvl == 0 ? "Personal Pumpjack" : $"Personal Pumpjack Lvl {lvl}";
quarry.Structure.health = 2500f + 500f * lvl;
quarry.Structure.protection = 10f * lvl;
quarry.Remove.itemList.Add(new NamedItem {
name = quarry.name, shortname = "furnace.large", amount = 1, skin = quarry.skin
}
);
if (lvl + 1 < quarrySkins.Length) quarry.Upgrade.newSkin = quarrySkins[lvl + 1];
for (int item = 0; item < upgradeShortnames.Length; item++) {
if (lvl == quarrySkins.Length - 1) break;
int amount = upgradeAmountsBase[item] + upgradeAmountsPerLvl[item] * (lvl + 1);
if (amount > 0) quarry.Upgrade.Cost.Add(new CustomItem {
shortname = upgradeShortnames[item], amount = amount
}
);
}
quarry.Inventory.lootSize = 6 + 6 * lvl;
quarry.Inventory.fuelSize = 1 + 1 * lvl;
quarry.Repair = repair;
quarry.Prefab.quarry = false;
quarry.Production.fuelList.Add(new FuelProduction {
shortname = "crude.oil", skin = 0, amount = 50, fuelTimer = 60, productionTimer = 60
}
);
quarry.Production.fuelList[0].resources.Add(new ResourceItem {
shortname = "lowgradefuel", amount = 150 + lvl, amountMax = 150 + lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList.Add(new FuelProduction {
shortname = "diesel_barrel", skin = 0, amount = 1, fuelTimer = 600, productionTimer = 300
}
);
quarry.Production.fuelList[1].resources.Add(new ResourceItem {
shortname = "lowgradefuel", amount = 110 + lvl * 3, amountMax = 110 + lvl * 3, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[1].resources.Add(new ResourceItem {
shortname = "crude.oil", amount = 50 + lvl, amountMax = 50 + lvl, skin = 0, chance = 100f
}
);
quarry.Production.fuelList[1].resources.Add(new ResourceItem {
shortname = "glue", amount = 30, amountMax = 50, skin = 3188057178, chance = 5f + (float)lvl / 2, name = "Top Quality Fuel"
}
);
Interface.Oxide.DataFileSystem.GetFile($"aQuarry/PersonalQuarries/Pumpjack{(lvl == 0 ? "00" : $"0 {
lvl
}
")}").WriteObject(quarry);
}
}
private void LoadConfigData() {
bool needUpdate = ValidateConfig();
DataFileSystem fileSystem = Interface.Oxide.DataFileSystem;
string[] fileName = new string[4] {
"StaticPumpjack", "StaticStoneQuarry", "StaticSulfurQuarry", "StaticHQMQuarry"
}
;
for (int i = 0; i < fileName.Length; i++) if (!fileSystem.ExistsDatafile($"aQuarry/StaticQuarries/{fileName[i]}")) DefaultStaticData(i);
string[] files = fileSystem.GetFiles("aQuarry/PersonalQuarries/");
if (files.Length == 0) DefaultPersonalData();
for (int i = 0; i < fileName.Length; i++) {
BaseQuarry quarry = fileSystem.GetFile($"aQuarry/StaticQuarries/{fileName[i]}").ReadObject<BaseQuarry>();
if (!quarry.enable) continue;
quarry.Production.fuelList.ForEach(x => x.ValidateProduction());
statics.Add((QuarryType)i, quarry);
fileSystem.GetFile($"aQuarry/StaticQuarries/{fileName[i]}").WriteObject(quarry);
}
foreach (string path in files) {
string name = path.Split('/').Last().Replace(".json", "");
PersonalQuarry quarry = fileSystem.GetFile($"aQuarry/PersonalQuarries/{name}").ReadObject<PersonalQuarry>();
if (!quarry.enable) continue;
if (quarry.skin == 0) {
PrintWarning($"{name} can not be loaded because it has no skinID.Skipping..");
continue;
}
if (personal.ContainsKey(quarry.skin)) {
PrintWarning($"{name} can not be loaded because skinID '{quarry.skin}' already exists.Skipping..");
continue;
}
if (quarry.Remove.allow) canBeRemoved.Add(quarry.skin);
if (quarry.Upgrade.newSkin > 0) canBeUpgraded.Add(quarry.skin);
quarry.Remove.itemList.ForEach(x => x.ValidateItem());
quarry.Upgrade.Cost.ForEach(x => x.ValidateItem());
quarry.Repair.Cost.ForEach(x => x.ValidateItem());
quarry.Production.fuelList.ForEach(x => x.ValidateProduction());
personal.Add(quarry.skin, quarry);
if (needUpdate) quarry.skinID = quarry.skin;
fileSystem.GetFile($"aQuarry/PersonalQuarries/{name}").WriteObject(quarry);
}
foreach (PersonalQuarry x in personal.Values) {
if (x.Upgrade.newSkin > 0 && !personal.ContainsKey(x.Upgrade.newSkin)) {
PrintWarning($"{x.name}'s upgrade settings are using skin '{x.Upgrade.newSkin}' which are not exist in the plugin or it's config disabled.Disabling upgrade for this quarry...");
x.Upgrade.newSkin = 0;
}
}
if (needUpdate) PrintWarning("All Data files successfully updated! You can now install 2.0.3 version.");
}
protected override void SaveConfig() => Config.WriteObject(config);
private Dictionary<QuarryType, BaseQuarry> statics = new Dictionary<QuarryType, BaseQuarry>();
private Dictionary<ulong, PersonalQuarry> personal = new Dictionary<ulong, PersonalQuarry>();
private Configuration config;
private Dictionary<ulong, UISettings> ui = new Dictionary<ulong, UISettings>();
private class UISettings {
internal UI main;
internal UI upgrade;
internal UI remove;
internal void CalculateOffset() {
if (upgrade != null) {
if (upgrade.height > main.height) main.height = upgrade.height;
else if (main.height > upgrade.height) upgrade.height = main.height;
upgrade.offset = new Offset($"20 -{upgrade.height / 2}", $"410 {upgrade.height / 2}");
main.offset = new Offset($"-410 -{main.height / 2}", $"-20 {main.height / 2}");
}
else main.offset = new Offset($"-205 -{main.height / 2}", $"185 {main.height / 2}");
if (remove != null) remove.offset = new Offset($"-205 -{remove.height / 2}", $"185 {remove.height / 2}");
}
}
private class UI {
internal bool isStatic = false;
internal int itemID = 0;
internal QuarryType type = QuarryType.None;
internal float[] stats = new float[4];
internal ulong skin = 0;
internal ulong parent = 0;
internal string name = "";
internal string sprite = "";
internal string langKey = "";
internal float height = 270f;
internal Offset offset;
internal Offset fuel;
internal Offset production;
internal Offset upgrade;
internal List<Offset> fuelList;
internal List<List<Offset>> productionList = new List<List<Offset>>();
internal List<Offset> upgradeList;
internal UI(ulong skin, ulong parent, string sprite, string langKey) {
this.skin = skin;
this.parent = parent;
this.sprite = sprite;
this.langKey = langKey;
}
}
private class Offset {
internal string min;
internal string max;
internal Offset(string min, string max) {
this.min = min;
this.max = max;
}
}
private void GenerateUI() {
foreach (KeyValuePair<ulong, PersonalQuarry> x in personal) {
ui.Add(x.Key, new UISettings());
UISettings set = ui[x.Key];
set.main = new UI(x.Key, x.Key, "assets/icons/gear.png", "UI.ControlButton");
set.main.name = x.Value.name;
set.main.itemID = x.Value.Prefab.quarry ? 1052926200 : -1130709577;
set.main.stats[0] = x.Value.Structure.health;
set.main.stats[1] = x.Value.Structure.protection;
set.main.stats[2] = x.Value.Inventory.lootSize;
set.main.stats[3] = x.Value.Inventory.fuelSize;
GenerateUISettings(x.Value.Production.fuelList, set.main);
if (x.Value.Upgrade.newSkin > 0) {
var quarry = personal[x.Value.Upgrade.newSkin];
set.upgrade = new UI(quarry.skin, x.Key, "assets/icons/upgrade.png", "UI.Upgrade");
set.upgrade.name = quarry.name;
set.upgrade.itemID = quarry.Prefab.quarry ? 1052926200 : -1130709577;
set.upgrade.stats[0] = quarry.Structure.health;
set.upgrade.stats[1] = quarry.Structure.protection;
set.upgrade.stats[2] = quarry.Inventory.lootSize;
set.upgrade.stats[3] = quarry.Inventory.fuelSize;
GenerateUISettings(quarry.Production.fuelList, set.upgrade, x.Value.Upgrade.Cost);
}
if (x.Value.Remove.allow) {
set.remove = new UI(x.Key, x.Key, "assets/icons/level_metal.png", "UI.Remove");
GenerateRemoveUI(set.remove, x.Value.Remove.refund ? x.Value.Remove.itemList.Count : 0);
}
set.CalculateOffset();
}
foreach (KeyValuePair<QuarryType, BaseQuarry> x in statics) {
ulong skin = staticSkins[x.Key];
ui.Add(skin, new UISettings());
UISettings set = ui[skin];
set.main = new UI(skin, skin, "assets/icons/gear.png", "UI.ControlButton");
set.main.isStatic = true;
set.main.type = x.Key;
set.main.itemID = x.Key == QuarryType.None ? -1130709577 : 1052926200;
set.main.stats[0] = 2500f;
set.main.stats[1] = 100f;
set.main.stats[2] = x.Value.Inventory.lootSize;
set.main.stats[3] = x.Value.Inventory.fuelSize;
GenerateUISettings(x.Value.Production.fuelList, set.main);
set.main.offset = new Offset($"-205 -{set.main.height / 2}", $"185 {set.main.height / 2}");
}
}
private void GenerateUISettings(List<FuelProduction> fuelList, UI ui, List<CustomItem> upgrade = null) {
float fuelHeight = CalculateHeight(ui, fuelList.Count);
int itemsProduction = 0;
for (int i = 0; i < fuelList.Count; i++) if (fuelList[i].resources.Count > itemsProduction) itemsProduction = fuelList[i].resources.Count;
float prodHeight = 25f + CalculateHeight(ui, itemsProduction);
float upgradeHeight = upgrade != null ? CalculateHeight(ui, upgrade.Count) : 0f;
ui.fuel = new Offset($"5 -{150 + fuelHeight}", $"-5 -150");
ui.fuelList = CalculateItemsOffsets(fuelList.Count);
ui.production = new Offset($"5 -{175 + fuelHeight + prodHeight}", $"-5 -{175 + fuelHeight}");
for (int i = 0; i < fuelList.Count; i++) {
ui.productionList.Add(new List<Offset>());
ui.productionList[i] = CalculateItemsOffsets(fuelList[i].resources.Count);
}
if (upgradeHeight > 0) {
ui.height += 25f;
ui.upgrade = new Offset($"5 -{200 + fuelHeight + prodHeight + upgradeHeight}", $"-5 -{200 + fuelHeight + prodHeight}");
ui.upgradeList = CalculateItemsOffsets(upgrade.Count);
}
}
private void GenerateRemoveUI(UI ui, int items) {
ui.height = 114f;
float itemsHeight = items > 0 ? CalculateHeight(ui, items) : 0f;
if (itemsHeight > 0) {
ui.fuel = new Offset($"5 -{50 + itemsHeight}", $"-5 -50");
ui.fuelList = CalculateItemsOffsets(items);
}
}
private float CalculateHeight(UI ui, int items) {
float result = 65f;
while (items > 6) {
result += 60f;
items -= 6;
}
ui.height += result;
return result;
}
private List<Offset> CalculateItemsOffsets(int items) {
List<Offset> result = new List<Offset>();
int first = 0;
int second = 0;
for (int i = 0; i < items; i++) {
int count = items - 6 * second > 6 ? 6 : items - 6 * second;
float distance = 5f;
float size = 55f;
float formula = -((size + distance) / 2) * count + (size + distance) * first + distance / 2;
float formula2 = -(distance + size * second + distance * second);
result.Add(new Offset($"{formula} {formula2 - size}", $"{formula + size} {formula2}"));
first++;
if (first == count) {
second++;
first = 0;
}
}
return result;
}
private class Configuration {
[JsonProperty(Rus ? "Оптимизация" : "Optimization")]
internal Optimization optimization = new Optimization();
[JsonProperty(Rus ? "Совместная работа с другими плагинами" : "Compatibility with other plugins")]
internal Plugins plugins = new Plugins();
[JsonProperty(Rus ? "SteamID аватарки для чата" : "Avatar SteamID for chat")]
internal ulong chatid = 0;
[JsonProperty(Rus ? "Формат для количества добываемых ресурсов в UI где есть рандом" : "Format of the resources amount in the UI where they can be randomized")]
internal string format = "x{0}-{1}";
[JsonProperty(Rus ? "Логировать полученные игроками карьеры?" : "Log the quarries received by players?")]
internal bool log = false;
[JsonProperty(Rus ? "Лимиты" : "Limits")]
internal Limits Limit = new Limits();
[JsonProperty(Rus ? "Рейты" : "Rates")]
internal QRates Rates = new QRates();
[JsonProperty(Rus ? "Версия плагина" : "Plugin Version")]
internal VersionNumber PluginVersion = new VersionNumber();
}
private class Optimization {
[JsonProperty(Rus ? "Отключить функционал запрета лутания карьеров другими игроками" : "Disable loot protection from other players")]
internal bool disableLoot = false;
[JsonProperty(Rus ? "Отключить лимиты" : "Disable limits")]
internal bool disableLimits = false;
[JsonProperty(Rus ? "Отключить проверки расстояния при установке" : "Disable distance checks during installing")]
internal bool disableDistance = false;
[JsonProperty(Rus ? "Отключить ремонт карьеров киянкой" : "Disable quarry repair with hammer")]
internal bool disableRepair = false;
[JsonProperty(Rus ? "Отключить пермишены" : "Disable permissions")]
internal bool disablePermissions = false;
[JsonProperty(Rus ? "Повторная попытка выдачи карьера игроку если инвентарь переполнен через X секунд" : "Anouther attempt to give quarry to player if his inventory is full in X seconds")]
internal int GiveSec = 15;
}
private class Plugins {
[JsonProperty(Rus ? "Включить поддержку aHomeManager? (см.документацию)" : "Enable aHomeManager support? (see the documentation)")]
internal bool aHomeManager = false;
}
private class Limits {
[JsonProperty(Rus ? "Суммировать лимиты со всех пермишенов у игрока?" : "Sum up the limits from all players permissions?")]
internal bool sumAll = true;
[JsonProperty(Rus ? "Лимиты по пермишенам" : "Limits by permissions")]
internal Dictionary<string, BuildLimits> permissions = new Dictionary<string, BuildLimits>();
}
private class BuildLimits {
[JsonProperty(Rus ? "Приоритет" : "Priority")]
internal int priority = 0;
[JsonProperty(Rus ? "Карьеры" : "Quarries")]
internal int limitQuarries = 3;
[JsonProperty(Rus ? "Нефтекачки" : "Pumpjacks")]
internal int limitJacks = 1;
}
private class QRates {
[JsonProperty(Rus ? "Суммировать рейты со всех пермишенов у игрока?" : "Sum up the rates from all player's permissions?")]
internal bool sumAll = true;
[JsonProperty(Rus ? "Рейты по пермишенам (1.0 = +100%)" : "Rates by permissions (1.0 = +100%)")]
internal Dictionary<string, float> permissions = new Dictionary<string, float>();
}
private class BaseQuarry {
[JsonProperty(PropertyName = Rus ? "Включить этот карьер?" : "Enable this quarry?", Order = 1)]
internal bool enable = false;
[JsonProperty(PropertyName = Rus ? "Инвентарь" : "Inventory", Order = 7)]
internal QInventory Inventory = new QInventory();
[JsonProperty(PropertyName = Rus ? "Производство" : "Production", Order = 11)]
internal QProduction Production = new QProduction();
}
//private class StaticQuarry : BaseQuarry
//{
// [JsonProperty(PropertyName = Rus ? "Защита лута" : "Loot Protection", Order = 8)] internal SProtection Protection = new SProtection();
//}
private class PersonalQuarry : BaseQuarry {
[JsonProperty(PropertyName = Rus ? "Название карьера" : "Quarry custom name", Order = 2)]
internal string name = "Custom Name";
[JsonProperty(PropertyName = "SkinID карьера", Order = 3)]
internal ulong skin = 0;
[JsonProperty(PropertyName = Rus ? "SkinID карьерa" : "Quarry SkinID", Order = 3)]
internal ulong skinID = 0;
[JsonProperty(PropertyName = Rus ? "Структура" : "Structure", Order = 4)]
internal QStructure Structure = new QStructure();
[JsonProperty(PropertyName = Rus ? "Ремув" : "Remove", Order = 5)]
internal QRemove Remove = new QRemove();
[JsonProperty(PropertyName = Rus ? "Улучшениe" : "Upgrade", Order = 6)]
internal QUpgrade Upgrade = new QUpgrade();
[JsonProperty(PropertyName = Rus ? "Защита от других игроков" : "Protection from other players", Order = 8)]
internal QProtection Protection = new QProtection();
[JsonProperty(PropertyName = Rus ? "Ремонт" : "Repair", Order = 9)]
internal QRepair Repair = new QRepair();
[JsonProperty(PropertyName = Rus ? "Подмена префаба" : "Prefab substitution", Order = 10)]
internal QPrefab Prefab = new QPrefab();
}
private class QStructure {
[JsonProperty(Rus ? "Прочность (очки здоровья)" : "Health points")]
internal float health = 2500f;
[JsonProperty(Rus ? "Снижение получаемого урона на % [0.0-100.0] (100 = неуязвимый)" : "Protection percentage [0.0-100.0] (100 = immortal)")]
internal float protection = 0f;
}
private class QRemove {
[JsonProperty(Rus ? "Разрешить удаление карьера?" : "Enable remove?")]
internal bool allow = true;
[JsonProperty(Rus ? "Возвращать предметы?" : "Enable refund?")]
internal bool refund = true;
[JsonProperty(Rus ? "Список возвращаемых предметов" : "Refund item list")]
internal List<NamedItem> itemList = new List<NamedItem>();
}
private class QUpgrade {
[JsonProperty(Rus ? "SkinID улучшенного карьера (0 = отключить улучшение)" : "SkinID of the upgraded quarry (0 = disable upgrades)")]
internal ulong newSkin = 0;
[JsonProperty(Rus ? "Стоимость улучшения" : "Upgrade cost")]
internal List<CustomItem> Cost = new List<CustomItem>();
}
private class QInventory {
[JsonProperty(Rus ? "Количество слотов в ресурсном отсеке" : "Resource container capacity")]
internal int lootSize = 18;
[JsonProperty(Rus ? "Количество слотов в топливном отсеке" : "Fuel container capacity")]
internal int fuelSize = 6;
}
//private class SProtection
//{
// [JsonProperty(Rus ? "Включить функционал защиты лута?" : "Enable loot protection functionality?")] internal bool enable = true;
//}
private class QProtection {
[JsonProperty(Rus ? "Только владелец карьера может его включать/выключать?" : "Only owner can toggle?")]
internal bool toggle = true;
[JsonProperty(Rus ? "Только владелец карьера может его лутать?" : "Only owner can loot?")]
internal bool loot = true;
[JsonProperty(Rus ? "Включая команду владельца?" : "Include his team?")]
internal bool team = true;
}
private class QRepair {
[JsonProperty(Rus ? "Разрешить ремонт киянкой?" : "Allow repair with hammer hit?")]
internal bool allow = false;
[JsonProperty(Rus ? "Нельзя ремонтировать в течении Х секунд после получения урона" : "Unable to repair X seconds after taking damage")]
internal float blockTime = 0f;
[JsonProperty(Rus ? "Восстановление прочности за удар" : "Repair amount for hit")]
internal float repair = 100f;
[JsonProperty(Rus ? "Требовать плату?" : "Enable cost?")]
internal bool needCost = false;
[JsonProperty(Rus ? "Стоимость ремонта" : "Repair cost")]
internal List<CustomItem> Cost = new List<CustomItem>();
}
private class QPrefab {
[JsonProperty(Rus ? "Использовать подмену префаба?" : "Use prefab substitution?")]
internal bool custom = true;
[JsonProperty(Rus ? "Это карьер (true) или нефтекачка (false) ?" : "This is a quarry (true) or pumpjack (false) ?")]
internal bool quarry = true;
[JsonProperty(Rus ? "ShortName предмета из которого создаем карьер" : "ShortName of the item from which we create a quarry")]
internal string prefab = "furnace.large";
[JsonProperty(Rus ? "Минимальное расстояние от игрока до карьера (при установке)" : "Minimum distance from player to quarry (when installed)")]
internal float distance1 = 3f;
[JsonProperty(Rus ? "Минимальное расстояние от карьера до строений (при установке)" : "Minimum distance from quarry to constructions (when installed)")]
internal float distance2 = 17f;
[JsonProperty(Rus ? "Дополнительная настройка высоты (при установке)" : "Additional height setting (when installed)")]
internal float height = -2f;
}
private class QProduction {
[JsonProperty(Rus ? "Список используемого топлива и его настройки добычи" : "List of the fuel used and its production settings")]
internal List<FuelProduction> fuelList = new List<FuelProduction>();
}
private class FuelProduction : CustomItem {
[JsonProperty(PropertyName = Rus ? "Сколько секунд карьер может работать на одном поглощении этого топлива?" : "How many seconds can quarry work on one consume of this fuel?", Order = 5)]
internal float fuelTimer = 5f;
[JsonProperty(PropertyName = Rus ? "Интервал производства ресурсов на этом топливе (секунды)" : "Resource production interval on this fuel (seconds)", Order = 6)]
internal float productionTimer = 5f;
[JsonProperty(PropertyName = Rus ? "Добываемые ресурсы на этом топливе" : "Gathering resources on this fuel", Order = 7)]
internal List<ResourceItem> resources = new List<ResourceItem>();
internal void ValidateProduction() {
if (fuelTimer < productionTimer) {
instance.PrintError($"Configuration Error! Work per fuel can not be less than production interval.Fixing...");
fuelTimer = productionTimer;
}
ValidateItem();
resources.ForEach(x => x.ValidateItem());
}
}
private class CustomItem {
[JsonIgnore]
internal int itemID = 0;
[JsonProperty(PropertyName = "ShortName", Order = 2)]
internal string shortname = "stones";
[JsonProperty(PropertyName = "SkinID", Order = 3)]
internal ulong skin = 0;
[JsonProperty(PropertyName = Rus ? "Количество" : "Amount", Order = 4)]
internal int amount = 1000;
internal void ValidateItem() {
ItemDefinition def = ItemManager.FindItemDefinition(shortname);
if (def == null) instance.PrintError($"Configuration Error! Invalid shortname: '{shortname}'");
else itemID = def.itemid;
}
}
private class NamedItem : CustomItem {
[JsonProperty(PropertyName = Rus ? "Название (пусто = не менять)" : "Custom name (empty = default)", Order = 1)]
internal string name = "";
}
private class ResourceItem : NamedItem {
[JsonProperty(PropertyName = Rus ? "Максимальное количество" : "Amount max", Order = 5)]
internal int amountMax = 1000;
[JsonProperty(PropertyName = Rus ? "Шанс появления предмета [0.0-100.0]" : "Probability [0.0-100.0]", Order = 6)]
internal float chance = 100f;
[JsonProperty(PropertyName = Rus ? "Не учитывать рейты по пермишенам" : "Do not use permission rates", Order = 7)]
internal bool disableRate = false;
}
#endregion
#region [Unity]
private class CustomQuarry : FacepunchBehaviour {
internal MiningQuarry quarry;
private BaseEntity engine;
private ItemContainer lootContainer;
private List<Item> fuelContainer;
private ulong fuelContainerId;
private List<FuelProduction> quarryConfig;
private Item currentFuel;
private FuelProduction config;
internal float rate = 1f;
internal bool isEnabled = false;
private float pendingWork = 0;
private float workDone = 0;
private float lastProdTime;
internal List<BasePlayer> looters = new List<BasePlayer>();
private void Awake() {
quarry = GetComponent<MiningQuarry>();
engine = quarry.engineSwitchPrefab.instance;
lootContainer = quarry.hopperPrefab.instance.GetComponent<StorageContainer>().inventory;
fuelContainer = quarry.fuelStoragePrefab.instance.GetComponent<StorageContainer>().inventory.itemList;
fuelContainerId = quarry.fuelStoragePrefab.instance.GetComponent<StorageContainer>().inventory.uid.Value;
instance.CustomQuarries.Add(quarry.net.ID.Value, this);
}
internal void UpdateSettings(bool isStatic = false) {
StorageContainer lootStorage = quarry.hopperPrefab.instance.GetComponent<StorageContainer>();
StorageContainer fuelStorage = quarry.fuelStoragePrefab.instance.GetComponent<StorageContainer>();
quarry.isStatic = isStatic;
if (isStatic) {
BaseQuarry settings = instance.statics[quarry.staticType];
fuelStorage.inventory.capacity = settings.Inventory.fuelSize;
fuelStorage.skinID = instance.staticSkins[quarry.staticType];
lootStorage.inventory.capacity = settings.Inventory.lootSize;
lootStorage.skinID = instance.staticSkins[quarry.staticType];
quarryConfig = settings.Production.fuelList;
}
else {
PersonalQuarry settings = instance.personal[quarry.skinID];
fuelStorage.inventory.capacity = settings.Inventory.fuelSize;
fuelStorage.skinID = quarry.skinID;
fuelStorage.OwnerID = quarry.OwnerID;
lootStorage.inventory.capacity = settings.Inventory.lootSize;
lootStorage.skinID = quarry.skinID;
lootStorage.OwnerID = quarry.OwnerID;
quarryConfig = settings.Production.fuelList;
quarry._maxHealth = settings.Structure.health;
quarry._health = settings.Structure.health;
quarry.repair.enabled = !instance.config.optimization.disableRepair && settings.Repair.allow;
rate = instance.GetPlayerRates(quarry.OwnerID.ToString());
quarry.baseProtection.amounts = protection;
if (settings.Structure.protection != 0) {
float[] amounts = quarry.baseProtection.amounts;
float protection = settings.Structure.protection;
for (int i = 0; i < amounts.Length; i++) {
amounts[i] += (1f - amounts[i]) * (protection / 100f);
if (amounts[i] > 1f) amounts[i] = 1f;
}
}
}
List<ItemDefinition> definitions = new List<ItemDefinition>();
List<int> itemIds = new List<int>();
for (int i = 0; i < quarryConfig.Count; i++) {
if (itemIds.Contains(quarryConfig[i].itemID)) continue;
itemIds.Add(quarryConfig[i].itemID);
definitions.Add(ItemManager.FindItemDefinition(quarryConfig[i].itemID));
}
fuelStorage.inventory.onlyAllowedItems = definitions.ToArray();
fuelStorage.inventory.canAcceptItem = null;
quarry._linkedDeposit = null;
quarry.pendingWork = 604800f;
quarry.processRate = 3600f;
bool isOn = quarry.HasFlag(BaseEntity.Flags.On);
if (instance.quarryCash.ContainsKey(quarry.net.ID.Value)) {
QuarryCash cash = instance.quarryCash[quarry.net.ID.Value];
quarry._health = cash.hp;
pendingWork = cash.pendingWork;
workDone = cash.workDone;
if (cash.fuelID > 0) foreach (FuelProduction x in quarryConfig) if (cash.fuelID == x.itemID && cash.fuelSkin == x.skin) config = x;
if (cash.isOn) isOn = true;
}
else {
pendingWork = 0;
workDone = 0;
config = null;
}
if (isOn) Toggle();
else quarry.SendNetworkUpdate();
}
internal void Upgrade() {
EndLoot();
SetOn(false);
quarry.skinID = instance.personal[quarry.skinID].Upgrade.newSkin;
UpdateSettings();
}
internal void Toggle() {
if (!isEnabled && CheckFuel()) SetOn(true);
else SetOn(false);
}
private void SetOn(bool enable) {
if (isEnabled == enable) return;
isEnabled = enable;
quarry.SetFlag(BaseEntity.Flags.On, enable);
engine.SetFlag(BaseEntity.Flags.On, enable);
quarry.SendNetworkUpdate();
// ... [Code preview truncated due to length. Full source in attached file] ...