C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using Network;
namespace Oxide.Plugins {
[Info("VirtualQuarries", "ThePitereq", "2.2.1")]
public class VirtualQuarries : RustPlugin {
[PluginReference]
private readonly Plugin ImageLibrary, PopUpAPI, ServerRewards, Economics, IQEconomic, BankSystem;
private static VirtualQuarries _plugin;
private readonly Dictionary<ulong, CachedSurvey> cachedSurveys = new Dictionary<ulong, CachedSurvey>();
private readonly Dictionary<ulong, List<RequiredItem>> cachedRequirements = new Dictionary<ulong, List<RequiredItem>>();
private readonly Dictionary<ulong, string> cachedSort = new Dictionary<ulong, string>();
private readonly Dictionary<ulong, int> cachedPage = new Dictionary<ulong, int>();
private readonly Dictionary<ulong, Dictionary<string, int>> cachedQuarryCount = new Dictionary<ulong, Dictionary<string, int>>();
private readonly Dictionary<ulong, string> cachedSurveyType = new Dictionary<ulong, string>();
private readonly Dictionary<ulong, uint> cachedInventories = new Dictionary<ulong, uint>();
private string imagePrefix = "";
private class CachedSurvey {
public string profile = string.Empty;
public List<QuarryResource> resources = new List<QuarryResource>();
}
private void Init() {
_plugin = this;
config = Config.ReadObject<PluginConfig>();
Config.WriteObject(config);
LoadData();
LoadMessages();
}
private void OnServerInitialized() {
if (config.economyPlugin == 1 && Economics == null) PrintWarning("Economics plugin not found! You will not be able to upgrade your quarries with server currency!");
else if (config.economyPlugin == 2 && ServerRewards == null) PrintWarning("ServerRewards plugin not found! You will not be able to upgrade your quarries with server currency!");
else if (config.economyPlugin == 3 && IQEconomic == null) PrintWarning("IQEconomic plugin not found! You will not be able to upgrade your quarries with server currency!");
else if (config.economyPlugin == 4 && BankSystem == null) PrintWarning("BankSystem plugin not found! You will not be able to upgrade your quarries with server currency!");
if (ImageLibrary == null) PrintWarning("ImageLibrary plugin not found! It is required for all images to work!");
if (PopUpAPI == null) PrintWarning("PopUpAPI plugin not found! The Pop-Up messages will not display!");
if (config.surveyThrow) Unsubscribe(nameof(OnExplosiveThrown));
if (config.overrideIcons) imagePrefix = "custom_";
AddImage("https://images.pvrust.eu/ui_icons/VirtualQuarries/arrow_right_0.png", "UI_VirtualQuarries_arrow_right_0", 0);
AddImage("https://images.pvrust.eu/ui_icons/VirtualQuarries/arrow_left_0.png", "UI_VirtualQuarries_arrow_left_0", 0);
AddImage("https://images.pvrust.eu/ui_icons/VirtualQuarries/shared_0.png", "UI_VirtualQuarries_shared_0", 0);
AddImage("https://images.pvrust.eu/ui_icons/VirtualQuarries/search_0.png", "UI_VirtualQuarries_search_0", 0);
if (config.requirePermission) permission.RegisterPermission("virtualquarries.use", this);
if (config.sharingRequirePermission) permission.RegisterPermission("virtualquarries.share", this);
if (config.quarryPerm) permission.RegisterPermission("virtualquarries.static.quarry", this);
if (config.pumpJackPerm) permission.RegisterPermission("virtualquarries.static.pumpjack", this);
foreach (var permissionKey in config.permissions.Keys) permission.RegisterPermission(permissionKey, this);
foreach (var permissionKey in config.surveys.Values) if (permissionKey.permission != string.Empty) permission.RegisterPermission(permissionKey.permission, this);
foreach (var permissionKey in config.quarryProfiles.Values) {
if (permissionKey.permission != string.Empty) permission.RegisterPermission(permissionKey.permission, this);
foreach (var resourceKey in permissionKey.resources.Values) if (resourceKey.permission != string.Empty) permission.RegisterPermission(resourceKey.permission, this);
}
if (config.storeContainers) timer.Every(config.containerSaveInterval, () => SaveContainers());
foreach (var command in config.commandList) cmd.AddChatCommand(command, this, nameof(VirtualQuarriesCommand));
foreach (var profile in config.quarryProfiles.Values) {
if (profile.icon.iconUrl != "") AddImage(profile.icon.iconUrl, $"{imagePrefix}{profile.icon.shortname}", profile.icon.skin);
foreach (var resource in profile.resources) {
if (resource.Value.iconUrl != "") AddImage(resource.Value.iconUrl, $"{imagePrefix}{resource.Value.shortname}", resource.Value.skin);
foreach (var additional in resource.Value.additionalItems) if (additional.iconUrl != "") AddImage(additional.iconUrl, $"{imagePrefix}{additional.shortname}", additional.skin);
}
foreach (var upgrade in profile.upgrades) foreach (var item in upgrade.requiredItems) if (item.iconUrl != "") AddImage(item.iconUrl, $"{imagePrefix}{item.shortname}", item.skin);
}
foreach (var survey in config.surveys.Values) if (survey.surveyItem.iconUrl != "") AddImage(survey.surveyItem.iconUrl, $"{imagePrefix}{survey.surveyItem.shortname}", survey.surveyItem.skin);
if (config.staticQuarries) {
foreach (var quarry in BaseNetworkable.serverEntities.OfType<MiningQuarry>()) {
quarry.SetOn(false);
quarry.CancelInvoke();
quarry.engineSwitchPrefab.instance.SetFlag(BaseEntity.Flags.On, true);
quarry.SetFlag(BaseEntity.Flags.On, true);
quarry.SendNetworkUpdate();
}
foreach (var quarry in data.staticQuarries.ToList()) {
MiningQuarry quarryEnt = BaseNetworkable.serverEntities.Find(quarry.Key) as MiningQuarry;
if (quarryEnt == null) {
foreach (var user in quarry.Value) {
BoxStorage storage = BaseNetworkable.serverEntities.Find(user.Value) as BoxStorage;
storage?.Kill();
}
data.staticQuarries.Remove(quarry.Key);
continue;
}
foreach (var user in quarry.Value) {
BoxStorage storage = BaseNetworkable.serverEntities.Find(user.Value) as BoxStorage;
if (storage == null) continue;
GroundWatch gw = storage.GetComponent<GroundWatch>();
if (gw != null) GameObject.Destroy(gw);
DestroyOnGroundMissing dogm = storage.GetComponent<DestroyOnGroundMissing>();
if (dogm != null) GameObject.Destroy(dogm);
BoxStorage fuelStorage = storage.children[0] as BoxStorage;
if (fuelStorage != null) {
gw = fuelStorage.GetComponent<GroundWatch>();
if (gw != null) GameObject.Destroy(gw);
dogm = fuelStorage.GetComponent<DestroyOnGroundMissing>();
if (dogm != null) GameObject.Destroy(dogm);
}
VirtualQuarry vQuarry = storage.GetComponent<VirtualQuarry>();
if (vQuarry == null) {
storage.gameObject.AddComponent<VirtualQuarry>();
vQuarry = storage.GetComponent<VirtualQuarry>();
}
vQuarry.staticQuarry = quarryEnt;
NextTick(() => vQuarry.SetupQuarry());
}
}
}
else {
Unsubscribe(nameof(OnQuarryToggled));
Unsubscribe(nameof(CanLootEntity));
}
foreach (var quarry in data.quarries) {
cachedQuarryCount.TryAdd(quarry.Value.owner, new Dictionary<string, int>());
cachedQuarryCount[quarry.Value.owner].TryAdd(quarry.Value.profile, 0);
cachedQuarryCount[quarry.Value.owner][quarry.Value.profile]++;
BoxStorage storage = BaseNetworkable.serverEntities.Find(quarry.Value.netId) as BoxStorage;
VirtualQuarry vQuarry = storage?.GetComponent<VirtualQuarry>();
if (storage == null) {
SpawnQuarry(quarry.Value.owner, quarry.Key);
storage = BaseNetworkable.serverEntities.Find(quarry.Value.netId) as BoxStorage;
}
else {
GroundWatch gw = storage.GetComponent<GroundWatch>();
if (gw != null) GameObject.Destroy(gw);
DestroyOnGroundMissing dogm = storage.GetComponent<DestroyOnGroundMissing>();
if (dogm != null) GameObject.Destroy(dogm);
BoxStorage fuelStorage = storage.children[0] as BoxStorage;
if (fuelStorage != null) {
gw = fuelStorage.GetComponent<GroundWatch>();
if (gw != null) GameObject.Destroy(gw);
dogm = fuelStorage.GetComponent<DestroyOnGroundMissing>();
if (dogm != null) GameObject.Destroy(dogm);
}
if (vQuarry == null) {
storage.gameObject.AddComponent<VirtualQuarry>();
vQuarry = storage.GetComponent<VirtualQuarry>();
}
if (!config.quarryProfiles.ContainsKey(quarry.Value.profile)) {
PrintWarning($"There is a quarry with profile '{quarry.Value.profile}' but it is missing in the configuration!");
continue;
}
List<UpgradeConfig> upgrades = config.quarryProfiles[quarry.Value.profile].upgrades;
(storage.children[0] as BoxStorage).inventory.capacity = 6;
if (quarry.Value.level < upgrades.Count) storage.inventory.capacity = upgrades[quarry.Value.level].capacity;
else PrintWarning($"Quarry with ID {quarry.Key} have more upgrades than is added to config! You need to add more levels or remove this quarry from data, or plugin will print errors!");
}
vQuarry = storage.GetComponent<VirtualQuarry>();
vQuarry.dataId = quarry.Key;
if (storage != null) NextTick(() => vQuarry.SetupQuarry());
}
foreach (var player in BasePlayer.activePlayerList) {
playerCache.TryAdd(player.userID, player.displayName);
playerCache[player.userID] = player.displayName;
}
}
private void Unload() {
if (config.storeContainers) SaveContainers();
SaveData();
foreach (var player in BasePlayer.activePlayerList) {
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Main");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_New");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_NewCursor");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Back");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Players");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Levels");
if (cachedInventories.ContainsKey(player.userID)) player.EndLooting();
}
foreach (var netId in data.quarries.Values) {
BoxStorage quarry = BaseNetworkable.serverEntities.Find(netId.netId) as BoxStorage;
if (quarry != null) GameObject.Destroy(quarry.GetComponent<VirtualQuarry>());
}
foreach (var quarryId in data.staticQuarries) {
foreach (var player in quarryId.Value) {
BoxStorage quarry = BaseNetworkable.serverEntities.Find(player.Value) as BoxStorage;
if (quarry != null) GameObject.Destroy(quarry.GetComponent<VirtualQuarry>());
}
}
}
private void OnNewSave() {
config = Config.ReadObject<PluginConfig>();
Config.WriteObject(config);
if (config.wipeData) {
LoadData();
data = new PluginData();
SaveData();
if (config.consoleLogs) Puts("Plugin data has been wiped successfully!");
}
}
private void OnPlayerConnected(BasePlayer player) {
playerCache.TryAdd(player.userID, player.displayName);
playerCache[player.userID] = player.displayName;
}
private void OnLootEntityEnd(BasePlayer player) {
if (cachedInventories.ContainsKey(player.userID)) {
NextTick(() => {
if (cachedInventories[player.userID] != 0) {
BaseEntity entity = BaseNetworkable.serverEntities.Find(cachedInventories[player.userID]) as BaseEntity;
if (entity != null && !entity.IsDestroyed) entity.Kill();
}
cachedInventories.Remove(player.userID);
}
);
}
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Back");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Levels");
}
private void OnExplosiveThrown(BasePlayer player, BaseEntity entity, ThrownWeapon item) {
if (item.ShortPrefabName.Contains("survey_charge") && item.skinID == 0) {
entity.Kill();
Item survey = ItemManager.CreateByName("surveycharge");
NextTick(() => player.GiveItem(survey));
PopUpAPI?.Call("API_ShowPopup", player, Lang("NoSurveyThrow", player.UserIDString, config.commandList[0]));
}
}
private object OnEntityTakeDamage(BoxStorage entity) {
if (entity.transform.position.y < -390) return false;
return null;
}
private void OnQuarryToggled(MiningQuarry quarry, BasePlayer player) {
quarry.SetOn(false);
quarry.CancelInvoke();
quarry.engineSwitchPrefab.instance.SetFlag(BaseEntity.Flags.On, true);
quarry.SetFlag(BaseEntity.Flags.On, true);
quarry.SendNetworkUpdate();
}
private object CanLootEntity(BasePlayer player, ResourceExtractorFuelStorage quarryStorage) {
MiningQuarry quarry = quarryStorage.GetParentEntity() as MiningQuarry;
{
if (config.quarryPerm && quarry.ShortPrefabName == "mininquarry_static" && !permission.UserHasPermission(player.UserIDString, "virtualquarries.static.quarry")) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("NoPermissionQuarry", player.UserIDString));
return false;
}
else if (config.pumpJackPerm && quarry.ShortPrefabName == "pumpjack-static" && !permission.UserHasPermission(player.UserIDString, "virtualquarries.static.pumpjack")) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("NoPermissionPumpJack", player.UserIDString));
return false;
}
}
data.staticQuarries.TryAdd(quarry.net.ID, new Dictionary<ulong, uint>());
if (!data.staticQuarries[quarry.net.ID].ContainsKey(player.userID)) {
int worldSize = Convert.ToInt32(World.Size);
float startX = -worldSize / 1.5f;
float startZ = worldSize / 1.5f;
Vector3 newLocation = new Vector3(startX + Core.Random.Range(-50, 50), -400, startZ + Core.Random.Range(-50, 50));
BoxStorage resourceStorage = GameManager.server.CreateEntity(config.storagePrefab, newLocation) as BoxStorage;
resourceStorage.Spawn();
resourceStorage.inventory.capacity = config.staticResourceSize;
data.staticQuarries[quarry.net.ID].Add(player.userID, resourceStorage.net.ID);
BoxStorage fuelStorage = GameManager.server.CreateEntity(config.storagePrefab, newLocation) as BoxStorage;
fuelStorage.Spawn();
GameObject.Destroy(resourceStorage.GetComponent<GroundWatch>());
GameObject.Destroy(resourceStorage.GetComponent<DestroyOnGroundMissing>());
GameObject.Destroy(fuelStorage.GetComponent<GroundWatch>());
GameObject.Destroy(fuelStorage.GetComponent<DestroyOnGroundMissing>());
fuelStorage.SetParent(resourceStorage);
fuelStorage.transform.position = newLocation + new Vector3(0, 0.7f, 0);
fuelStorage.inventory.capacity = 6;
VirtualQuarry vQuarry = resourceStorage.GetComponent<VirtualQuarry>();
if (vQuarry == null) {
resourceStorage.gameObject.AddComponent<VirtualQuarry>();
vQuarry = resourceStorage.GetComponent<VirtualQuarry>();
}
vQuarry.staticQuarry = quarry;
NextTick(() => {
vQuarry.SetupQuarry();
OpenStaticQuarry(player, quarryStorage, quarry);
}
);
}
else OpenStaticQuarry(player, quarryStorage, quarry);
return false;
}
[ConsoleCommand("UI_VirtualQuarries")]
private void VirtualQuarriesConsoleCommand(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (config.requirePermission && !permission.UserHasPermission(player.UserIDString, "virtualquarries.use")) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("NoPermission", player.UserIDString));
return;
}
switch (arg.Args[0]) {
case "close" : CuiHelper.DestroyUi(player, "VirtualQuarriesUI_NewCursor");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_New");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Main");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Players");
break;
case "new" : CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Main");
SelectSurveyTypeUI(player);
break;
case "back" : CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Main");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_NewCursor");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_New");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Back");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Players");
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Levels");
player.EndLooting();
if (arg.Args.Length == 1) ShowQuarryMenuUI(player);
else ShowQuarryMenuUI(player, 1, Convert.ToInt32(arg.Args[1]));
break;
case "throw_open" : cachedSurveyType.TryAdd(player.userID, "");
cachedSurveyType[player.userID] = arg.Args[1];
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_New");
ShowNewQuarryUI(player, true);
break;
case "throw" : TrySurveyThrow(player);
break;
case "place" : TryPlaceQuarry(player);
break;
case "view" : ShowQuarryMenuUI(player, Convert.ToInt32(arg.Args[1]), Convert.ToInt32(arg.Args[2]));
break;
case "engine" : TryStartQuarry(player, Convert.ToInt32(arg.Args[1]));
break;
case "fuel" : TryOpenFuelContainer(player, Convert.ToInt32(arg.Args[1]));
break;
case "storage" : TryOpenResourceContainer(player, Convert.ToInt32(arg.Args[1]));
break;
case "delete" : TryRemoveQuarry(player, Convert.ToInt32(arg.Args[1]));
break;
case "sortOwned" : ChangeSort(player, "owned");
break;
case "sortShared" : ChangeSort(player, "shared");
break;
case "sortDisable" : ChangeSort(player, "disable");
break;
case "page" : int page = Convert.ToInt32(arg.Args[1]);
cachedPage.TryAdd(player.userID, page);
cachedPage[player.userID] = page;
ShowQuarryMenuUI(player, page);
break;
case "action" : CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Main");
if (arg.Args.Length == 2) ManageQuarryPlayersUI(player, arg.Args[1]);
else if (arg.Args.Length == 3) ManageQuarryPlayersUI(player, arg.Args[1], Convert.ToInt32(arg.Args[2]));
else if (arg.Args.Length == 4) ManageQuarryPlayersUI(player, arg.Args[1], Convert.ToInt32(arg.Args[2]), Convert.ToInt32(arg.Args[3]));
else if (arg.Args.Length >= 5) ManageQuarryPlayersUI(player, arg.Args[1], Convert.ToInt32(arg.Args[2]), Convert.ToInt32(arg.Args[3]), arg.Args[4]);
break;
case "doAction" : ManageQuarryUser(player, arg.Args[1], Convert.ToInt32(arg.Args[2]), Convert.ToUInt64(arg.Args[3]));
break;
case "list" : ShowQuarryAccessList(player, Convert.ToInt32(arg.Args[1]));
break;
case "upgrade" : TryUpgradeQuarry(player, Convert.ToInt32(arg.Args[1]), arg.Args[2]);
break;
default : ShowQuarryMenuUI(player);
break;
}
}
private void VirtualQuarriesCommand(BasePlayer player) => ShowQuarryMenuUI(player);
private void ShowQuarryAccessList(BasePlayer player, int quarryId) {
if (data.quarries[quarryId].owner != player.userID && !data.quarries[quarryId].authPlayers.Contains(player.userID)) return;
string accessList = Lang("AccessListStart", player.UserIDString);
foreach (var playerId in data.quarries[quarryId].authPlayers) accessList += Lang("AccessListList", player.UserIDString, playerCache[playerId]);
if (accessList == Lang("AccessListStart", player.UserIDString)) accessList += Lang("AccessListNoAdded", player.UserIDString);
PopUpAPI?.Call("API_ShowPopup", player, accessList, 10f, "Hud.Menu", 12);
}
private void TryUpgradeQuarry(BasePlayer player, int quarryId, string type) {
if (data.quarries[quarryId].owner != player.userID && !data.quarries[quarryId].authPlayers.Contains(player.userID)) return;
QuarryData quarry = data.quarries[quarryId];
List<UpgradeConfig> upgrades = config.quarryProfiles[quarry.profile].upgrades;
if (type == "currency") {
if (config.economyPlugin == 1) {
if (Economics.Call<double>("Balance", player.userID) >= upgrades[quarry.level + 1].requiredRp) {
Economics.Call("Withdraw", player.userID, Convert.ToDouble(upgrades[quarry.level + 1].requiredRp));
UpgradeQuarry(player, quarryId);
}
else PopUpAPI?.Call("API_ShowPopup", player, Lang("NotEnoughCurrency", player.UserIDString));
}
else if (config.economyPlugin == 2) {
if (ServerRewards.Call<int>("CheckPoints", player.userID) >= upgrades[quarry.level + 1].requiredRp) {
ServerRewards.Call("TakePoints", player.userID, upgrades[quarry.level + 1].requiredRp);
UpgradeQuarry(player, quarryId);
}
else PopUpAPI?.Call("API_ShowPopup", player, Lang("NotEnoughCurrency", player.UserIDString));
}
else if (config.economyPlugin == 3) {
if (IQEconomic.Call<int>("API_GET_BALANCE", player.userID) >= upgrades[quarry.level + 1].requiredRp) {
IQEconomic.Call("API_REMOVE_BALANCE", player.userID, upgrades[quarry.level + 1].requiredRp);
UpgradeQuarry(player, quarryId);
}
else PopUpAPI?.Call("API_ShowPopup", player, Lang("NotEnoughCurrency", player.UserIDString));
}
else if (config.economyPlugin == 4) {
if (BankSystem.Call<int>("Balance", player.userID) >= upgrades[quarry.level + 1].requiredRp) {
BankSystem.Call("Withdraw", player.userID, upgrades[quarry.level + 1].requiredRp);
UpgradeQuarry(player, quarryId);
}
else PopUpAPI?.Call("API_ShowPopup", player, Lang("NotEnoughCurrency", player.UserIDString));
}
}
else {
if (!TakeResources(player, upgrades[quarry.level + 1].requiredItems)) PopUpAPI?.Call("API_ShowPopup", player, Lang("NotEnoughItems", player.UserIDString));
else UpgradeQuarry(player, quarryId);
}
}
private void UpgradeQuarry(BasePlayer player, int quarryId) {
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Levels");
QuarryData quarry = data.quarries[quarryId];
quarry.level++;
List<UpgradeConfig> upgrades = config.quarryProfiles[quarry.profile].upgrades;
BoxStorage storage = BaseNetworkable.serverEntities.Find(quarry.netId) as BoxStorage;
if (storage == null) return;
storage.inventory.capacity = upgrades[quarry.level].capacity;
storage.SendNetworkUpdate();
storage.GetComponent<VirtualQuarry>().SetupQuarry();
Effect.server.Run("assets/prefabs/deployable/quarry/effects/mining-quarry-deploy.prefab", player.transform.position);
Effect.server.Run("assets/bundled/prefabs/fx/build/promote_toptier.prefab", player.transform.position);
Interface.CallHook("OnQuarryUpgraded", player, quarry.level, quarry.profile);
player.EndLooting();
timer.Once(0.2f, () => TryOpenResourceContainer(player, quarryId));
if (config.consoleLogs) Puts($"Player {player.displayName} ({player.userID}) upgraded his quarry with ID {quarryId} to level {quarry.level + 1}.");
}
private void ManageQuarryUser(BasePlayer player, string type, int quarryId, ulong userId) {
if (quarryId != 0 && !data.quarries.ContainsKey(quarryId)) return;
if (quarryId != 0 && data.quarries[quarryId].owner != player.userID && !data.quarries[quarryId].authPlayers.Contains(player.userID)) return;
if (type.Contains("addAll")) {
foreach (var quarry in data.quarries.Values) if (quarry.owner == player.userID && !quarry.authPlayers.Contains(userId)) quarry.authPlayers.Add(userId);
return;
}
else if (type == "remove") data.quarries[quarryId].authPlayers.Remove(userId);
else if (type.Contains("add")) data.quarries[quarryId].authPlayers.Add(userId);
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Players");
ShowQuarryMenuUI(player, 1, quarryId);
}
private void ChangeSort(BasePlayer player, string type) {
cachedSort.Remove(player.userID);
if (type == "owned") cachedSort.TryAdd(player.userID, "owned");
else if (type == "shared") cachedSort.TryAdd(player.userID, "shared");
ShowQuarryMenuUI(player);
}
private void TryRemoveQuarry(BasePlayer player, int quarryId) {
if (data.quarries[quarryId].owner != player.userID) return;
if (!player.serverInput.IsDown(BUTTON.SPRINT)) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("NoSprintButton", player.UserIDString));
return;
}
BoxStorage quarry = GetQuarry(quarryId);
if (config.refundRemove) {
List<RequiredItem> refundItems1 = config.quarryProfiles[data.quarries[quarryId].profile].requiredItems;
foreach (var refundItem in refundItems1) {
Item item = ItemManager.CreateByName(refundItem.shortname, refundItem.amount, refundItem.skin);
if (refundItem.displayName != null && refundItem.displayName != "") item.name = refundItem.displayName;
if (!item.MoveToContainer(player.inventory.containerMain)) item.Drop(player.eyes.position, Vector3.zero);
}
Dictionary<string, ResourceConfig> refundItems2 = config.quarryProfiles[data.quarries[quarryId].profile].resources;
foreach (var resource in data.quarries[quarryId].resources) {
foreach (var refundItem in refundItems2[resource.configKey].additionalItems) {
Item item = ItemManager.CreateByName(refundItem.shortname, refundItem.amount, refundItem.skin);
if (refundItem.displayName != null && refundItem.displayName != "") item.name = refundItem.displayName;
if (!item.MoveToContainer(player.inventory.containerMain)) item.Drop(player.eyes.position, Vector3.zero);
}
}
foreach (var item in quarry.inventory.itemList.ToList()) if (!item.MoveToContainer(player.inventory.containerMain)) item.Drop(player.eyes.position, Vector3.zero);
BoxStorage fuelStorage = quarry.children[0] as BoxStorage;
if (fuelStorage != null) foreach (var item in fuelStorage.inventory.itemList.ToList()) if (!item.MoveToContainer(player.inventory.containerMain)) item.Drop(player.eyes.position, Vector3.zero);
PopUpAPI?.Call("API_ShowPopup", player, Lang("QuarryRemovedRefund", player.UserIDString), 5f, "Overlay");
}
else PopUpAPI?.Call("API_ShowPopup", player, Lang("QuarryRemoved", player.UserIDString), 5f, "Overlay");
cachedQuarryCount[player.userID][data.quarries[quarryId].profile]--;
Interface.CallHook("OnQuarryRemoved", player, data.quarries[quarryId].profile);
if (quarry != null) quarry.Kill();
if (config.consoleLogs) Puts($"Player {player.displayName} ({player.userID}) removed quarry with ID {quarryId} with level {data.quarries[quarryId].level}.");
data.quarries.Remove(quarryId);
ShowQuarryMenuUI(player);
}
private void TrySurveyThrow(BasePlayer player) {
if (!cachedSurveyType.ContainsKey(player.userID)) return;
if (config.surveys[cachedSurveyType[player.userID]].permission != "" && !permission.UserHasPermission(player.UserIDString, config.surveys[cachedSurveyType[player.userID]].permission)) return;
List<RequiredItem> requiredSurvey = new List<RequiredItem>() {
config.surveys[cachedSurveyType[player.userID]].surveyItem
}
;
if (!TakeResources(player, requiredSurvey)) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("NoRequiredSurvey", player.UserIDString, Lang(config.surveys[cachedSurveyType[player.userID]].surveyTranslation, player.UserIDString)));
return;
}
if (config.surveys[cachedSurveyType[player.userID]].effectPath != "") EffectNetwork.Send(new Effect(config.surveys[cachedSurveyType[player.userID]].effectPath, player, 0, Vector3.zero, Vector3.up), player.net.connection);
cachedSurveys.TryAdd(player.userID, new CachedSurvey());
cachedRequirements.TryAdd(player.userID, new List<RequiredItem>());
cachedSurveys[player.userID] = new CachedSurvey();
cachedRequirements[player.userID] = new List<RequiredItem>();
if (Core.Random.Range(1, 101) > config.surveys[cachedSurveyType[player.userID]].resourceChance) {
ShowNewQuarryUI(player);
return;
}
int sumChance = 0;
foreach (var profile in config.quarryProfiles.Values) {
if (profile.surveyType != cachedSurveyType[player.userID]) continue;
if (profile.permission == string.Empty || permission.UserHasPermission(player.UserIDString, profile.permission)) sumChance += profile.chance;
}
int rolledProfile = Core.Random.Range(0, sumChance + 1);
sumChance = 0;
string profileKey = string.Empty;
foreach (var profile in config.quarryProfiles) {
if (profile.Value.surveyType != cachedSurveyType[player.userID]) continue;
if (profile.Value.permission == string.Empty || permission.UserHasPermission(player.UserIDString, profile.Value.permission)) {
sumChance += profile.Value.chance;
if (sumChance >= rolledProfile) {
cachedSurveys[player.userID].profile = profile.Key;
profileKey = profile.Key;
break;
}
}
}
Dictionary<string, ResourceConfig> resources = config.quarryProfiles[profileKey].resources;
cachedRequirements[player.userID].AddRange(config.quarryProfiles[profileKey].requiredItems);
foreach (var resource in resources) if (resource.Value.alwaysInclude) {
if (resource.Value.permission != string.Empty && !permission.UserHasPermission(player.UserIDString, resource.Value.permission)) continue;
cachedSurveys[player.userID].resources.Add(new QuarryResource() {
configKey = resource.Key, work = Core.Random.Range(resource.Value.outputMin, resource.Value.outputMax)
}
);
cachedRequirements[player.userID].AddRange(resource.Value.additionalItems);
}
List<ResourceConfig> resourceList = new List<ResourceConfig>();
int loopCount = Core.Random.Range(config.quarryProfiles[profileKey].minPerNode, config.quarryProfiles[profileKey].maxPerNode + 1) - cachedSurveys[player.userID].resources.Count;
for (int i = 0; i < loopCount; i++) {
int chance = 0;
foreach (var resource in resources) if (!resource.Value.alwaysInclude && !resourceList.Contains(resource.Value)) chance += resource.Value.chance;
int rolledItem = Core.Random.Range(0, chance + 1);
chance = 0;
foreach (var resource in resources) {
if (resource.Value.alwaysInclude || resourceList.Contains(resource.Value)) continue;
if (resource.Value.permission != string.Empty && !permission.UserHasPermission(player.UserIDString, resource.Value.permission)) continue;
chance += resource.Value.chance;
if (chance >= rolledItem) {
cachedSurveys[player.userID].resources.Add(new QuarryResource() {
configKey = resource.Key, work = Core.Random.Range(resource.Value.outputMin, resource.Value.outputMax)
}
);
cachedRequirements[player.userID].AddRange(resource.Value.additionalItems);
resourceList.Add(resource.Value);
break;
}
}
}
Interface.CallHook("OnCustomSurveyThrow", player, profileKey);
ShowNewQuarryUI(player);
}
private void TryPlaceQuarry(BasePlayer player) {
if (!cachedSurveys.ContainsKey(player.userID) || cachedSurveys[player.userID].resources.Count == 0) return;
Dictionary<string, int> playerPerm = null;
foreach (var configPerm in config.permissions) if (permission.UserHasPermission(player.UserIDString, configPerm.Key)) playerPerm = configPerm.Value;
if (playerPerm == null) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("NotAllowedToPlace", player.UserIDString));
return;
}
cachedQuarryCount.TryAdd(player.userID, new Dictionary<string, int>());
cachedQuarryCount[player.userID].TryAdd(cachedSurveys[player.userID].profile, 0);
if (playerPerm.ContainsKey(cachedSurveys[player.userID].profile) && playerPerm[cachedSurveys[player.userID].profile] <= cachedQuarryCount[player.userID][cachedSurveys[player.userID].profile]) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("TooManyQuarries", player.UserIDString));
return;
}
if (!TakeResources(player, cachedRequirements[player.userID])) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("NoRequiredItems", player.UserIDString));
return;
}
cachedQuarryCount[player.userID][cachedSurveys[player.userID].profile]++;
Effect.server.Run("assets/prefabs/deployable/quarry/effects/mining-quarry-deploy.prefab", player.transform.position);
Interface.CallHook("OnQuarryPlaced", player, cachedSurveys[player.userID].profile);
SpawnQuarry(player.userID);
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_NewCursor");
ShowQuarryMenuUI(player, 1, data.quarryCount - 1);
}
private void TryStartQuarry(BasePlayer player, int quarryId) {
if (data.quarries[quarryId].owner != player.userID && !data.quarries[quarryId].authPlayers.Contains(player.userID)) return;
BoxStorage quarry = GetQuarry(quarryId);
if (quarry == null) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("ErrorOccured", player.UserIDString));
return;
}
VirtualQuarry virtualQuarry = quarry.GetComponent<VirtualQuarry>();
bool oldStatus = data.quarries[quarryId].isRunning;
virtualQuarry.TryRun();
ShowQuarryMenuUI(player, 1, quarryId);
if (oldStatus == false && data.quarries[quarryId].isRunning == false) {
RequiredItem fuelItem = config.quarryProfiles[data.quarries[quarryId].profile].fuelItem;
string displayedFuelName = fuelItem.skin == 0 ? Lang($"Fuel_{fuelItem.shortname}", player.UserIDString) : Lang($"Fuel_{fuelItem.skin}", player.UserIDString);
PopUpAPI?.Call("API_ShowPopup", player, Lang("NoFuelHint", player.UserIDString, fuelItem.amount, displayedFuelName));
}
else if (oldStatus == false && config.startSound != "") EffectNetwork.Send(new Effect(config.startSound, player, 0, new Vector3(0, 1.7f, 0), Vector3.up), player.net.connection);
else if (oldStatus == true && config.stopSound != "") EffectNetwork.Send(new Effect(config.stopSound, player, 0, new Vector3(0, 1.7f, 0), Vector3.up), player.net.connection);
}
private void TryOpenFuelContainer(BasePlayer player, int quarryId) {
if (data.quarries[quarryId].owner != player.userID && !data.quarries[quarryId].authPlayers.Contains(player.userID)) return;
BoxStorage quarry = GetQuarry(quarryId);
if (quarry == null) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("ErrorOccured", player.UserIDString));
return;
}
player.EndLooting();
BaseEntity entity = GameManager.server.CreateEntity("assets/bundled/prefabs/modding/lootables/invisible/invisible_lootable_prefabs/invisible_crate_basic.prefab", player.transform.position + new Vector3(0, -400, 0)) as BaseEntity;
entity.Spawn();
cachedInventories.Remove(player.userID);
cachedInventories.Add(player.userID, entity.net.ID);
BoxStorage fuelStorage = quarry.children[0] as BoxStorage;
fuelStorage.inventory.canAcceptItem = (item, i) => IsFuel(item, data.quarries[quarryId].profile);
player.inventory.loot.AddContainer(fuelStorage.inventory);
player.inventory.loot.entitySource = entity;
player.inventory.loot.PositionChecks = false;
player.inventory.loot.MarkDirty();
player.inventory.loot.SendImmediate();
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Main");
player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", "generic_resizable");
Interface.CallHook("OnLootEntity", player, fuelStorage);
AddBackButtonUI(player, quarryId);
}
private void TryOpenResourceContainer(BasePlayer player, int quarryId) {
if (data.quarries[quarryId].owner != player.userID && !data.quarries[quarryId].authPlayers.Contains(player.userID)) return;
BoxStorage quarry = GetQuarry(quarryId);
if (quarry == null) {
PopUpAPI?.Call("API_ShowPopup", player, Lang("ErrorOccured", player.UserIDString));
return;
}
player.EndLooting();
if (!cachedInventories.ContainsKey(player.userID)) cachedInventories.Add(player.userID, 0);
quarry.inventory.canAcceptItem = (item, i) => IsResourceOutput(item);
player.inventory.loot.AddContainer(quarry.inventory);
player.inventory.loot.entitySource = quarry;
player.inventory.loot.PositionChecks = false;
player.inventory.loot.MarkDirty();
player.inventory.loot.SendImmediate();
CuiHelper.DestroyUi(player, "VirtualQuarriesUI_Main");
player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", "generic_resizable");
Interface.CallHook("OnLootEntity", player, quarry);
AddQuarryLevelsUI(player, quarryId);
AddBackButtonUI(player, quarryId);
}
private void OpenStaticQuarry(BasePlayer player, ResourceExtractorFuelStorage quarryStorage, MiningQuarry quarry) {
uint storageId = data.staticQuarries[quarry.net.ID][player.userID];
BoxStorage storage = BaseNetworkable.serverEntities.Find(storageId) as BoxStorage;
if (storage == null) return;
if (quarryStorage.ShortPrefabName == "fuelstorage") storage = storage.children[0] as BoxStorage;
player.EndLooting();
if (quarryStorage.ShortPrefabName == "fuelstorage") storage.inventory.canAcceptItem = (item, i) => IsStaticFuel(item);
else storage.inventory.canAcceptItem = (item, i) => IsResourceOutput(item);
player.inventory.loot.AddContainer(storage.inventory);
player.inventory.loot.entitySource = storage;
player.inventory.loot.PositionChecks = false;
player.inventory.loot.MarkDirty();
player.inventory.loot.SendImmediate();
player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", "generic_resizable");
Interface.CallHook("OnLootEntity", player, storage);
PopUpAPI?.Call("API_ShowPopup", player, Lang("PrivateInventoryInfo", player.UserIDString));
}
private bool IsFuel(Item item, string profile) {
if (item.info.shortname == config.quarryProfiles[profile].fuelItem.shortname && item.skin == config.quarryProfiles[profile].fuelItem.skin) return true;
else return false;
}
private bool IsStaticFuel(Item item) {
if (item.info.shortname == config.staticFuelItem.shortname && item.skin == config.staticFuelItem.skin) return true;
else return false;
}
private static bool IsResourceOutput(Item item) {
if (item.GetOwnerPlayer() != null) return false;
return true;
}
private void SaveContainers() {
if (config.consoleLogs) Puts("Saving quarry containers...");
int containerCount = 0;
foreach (var quarry in data.quarries) {
BoxStorage resources = BaseNetworkable.serverEntities.Find(quarry.Value.netId) as BoxStorage;
if (resources == null) continue;
SaveItems(resources, quarry.Key, "resource");
BoxStorage fuel = resources.children[0] as BoxStorage;
if (fuel == null) continue;
SaveItems(fuel, quarry.Key, "fuel");
containerCount++;
}
if (config.consoleLogs) Puts($"Successfully saved {containerCount} quarry containers!");
}
private void SaveItems(BoxStorage storage, int quarryId, string dataType) {
storageCache.TryAdd(quarryId, new StorageData());
if (dataType == "resource") {
storageCache[quarryId].resource = new List<RequiredItem>();
foreach (var item in storage.inventory.itemList.ToList()) {
string name = item.name == null || item.name == "" ? null : item.name;
storageCache[quarryId].resource.Add(new RequiredItem() {
shortname = item.info.shortname, skin = item.skin, amount = item.amount, displayName = name
}
);
}
}
else {
storageCache[quarryId].fuel = new List<RequiredItem>();
foreach (var item in storage.inventory.itemList.ToList()) {
string name = item.name == null || item.name == "" ? null : item.name;
storageCache[quarryId].fuel.Add(new RequiredItem() {
shortname = item.info.shortname, skin = item.skin, amount = item.amount, displayName = name
}
);
}
}
}
private BoxStorage GetQuarry(int quarryId) {
if (!data.quarries.ContainsKey(quarryId)) return null;
BoxStorage storage = BaseNetworkable.serverEntities.Find(data.quarries[quarryId].netId) as BoxStorage;
if (storage != null) return storage;
SpawnQuarry(0, quarryId);
storage = BaseNetworkable.serverEntities.Find(data.quarries[quarryId].netId) as BoxStorage;
if (storage != null) return storage;
else return null;
}
private void SpawnQuarry(ulong playerId = 0, int restoreId = -1) {
if (restoreId == -1 && (!cachedSurveys.ContainsKey(playerId) || (cachedSurveys.ContainsKey(playerId) && cachedSurveys[playerId].resources.Count == 0))) return;
int worldSize = Convert.ToInt32(World.Size);
float startX = -worldSize / 1.5f;
float star
// ... [Code preview truncated due to length. Full source in attached file] ...