C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
/*
* <----- End-User License Agreement ----->
* Copyright © 2024 Iftebinjan
* Devoloper: Iftebinjan (Contact: https://discord.gg/HFaGs8YwsH)
*
* You may not copy, modify, merge, publish, distribute, sublicense, or sell copies of This Software without the Developer’s consent
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
using System;
using System.Collections.Generic;
using System.Linq;
using Facepunch;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
namespace Oxide.Plugins {
[Info("TCUpgrades", "ifte", "1.0.4")]
[Description("Tool Cupboard Upgrade!")]
public class TCUpgrades : RustPlugin {
/*------------------------------------
*
* TCUpgrades by Ifte
* Support: https://discord.gg/cCWadjcapr
* Fiverr: https://www.fiverr.com/s/e2pkYY
* Eror404 not found
*
------------------------------------*/
/* Version: 1.0.4
* - Fixed an issue with Auth Remove BTN
* - Fixed config issue
* = Fixed on server wiped clear data
*/
/* Version: 1.0.3
* - Added new config options
* - Added default skin options
* - Added wallpaper placeableable by both side
* - Added Random color for metal skin
* - Fixed Carbon UI bugs (Showing black bars on screen)
* - Fixed some other bugs
*/
/* Version: 1.0.2
* - Updated lang files
* - Updated for the latest rust release.*/
#region Variables
[PluginReference]
private Plugin ImageLibrary, Toastify, Notify, NoEscape;
private Configuration config;
private const string PermAuthList = $"TCUpgrades.authlist";
private const string PermUpgrades = $"TCUpgrades.upgrade";
private const string PermRepair = $"TCUpgrades.repair";
private const string PermSkinBase = $"TCUpgrades.skin";
private const string PermWallpaper = $"TCUpgrades.wallpaper";
private const string PermUpgradesNoCost = $"TCUpgrades.upgrade.nocost";
private const string PermRepairNoCost = $"TCUpgrades.repair.nocost";
private const string PermWallpaperNoCost = $"TCUpgrades.wallpaper.nocost";
private const string PermDefault = $"TCUpgrades.default";
private const string PermWood = $"TCUpgrades.wood";
private const string PermStone = $"TCUpgrades.stone";
private const string PermMetal = $"TCUpgrades.metal";
private const string PermHQM = $"TCUpgrades.hqm";
private const string PermDeploy = $"TCUpgrades.deploy";
private const string ClickFX = "assets/bundled/prefabs/fx/notice/loot.drag.grab.fx.prefab";
private enum NotificationPluginType {
None, Toastify, Notify
}
;
private readonly Dictionary<ulong, string> SkinBase = new Dictionary<ulong, string>() {
{
999, "tclevels.icons.wood.normal"
}
, {
10232, "tclevels.icons.wood.frontier"
}
, {
2, "tclevels.icons.wood.ginger"
}
, {
1000, "tclevels.icons.stone.normal"
}
, {
10223, "tclevels.icons.stone.brick"
}
, {
10225, "tclevels.icons.stone.brutalist"
}
, {
10220, "tclevels.icons.stone.adobe"
}
, {
1001, "tclevels.icons.metal.normal"
}
, {
10221, "tclevels.icons.metal.container"
}
,
}
;
private readonly Dictionary<uint, string> MetalColors = new() {
[9999]
= "tclevels.icons.random", [1] = "0.38 0.56 0.74 1.0", [2] = "0.45 0.71 0.34 1.0", [3] = "0.57 0.29 0.83 1.0", [4] = "0.42 0.17 0.11 1.0", [5] = "0.82 0.46 0.13 1.0", [6] = "0.87 0.87 0.87 1.0", [7] = "0.20 0.20 0.18 1.0", [8] = "0.40 0.33 0.27 1.0", [9] = "0.20 0.22 0.34 1.0", [10] = "0.24 0.35 0.20 1.0", [11] = "0.73 0.30 0.18 1.0", [12] = "0.78 0.53 0.39 1.0", [13] = "0.84 0.66 0.22 1.0", [14] = "0.34 0.33 0.31 1.0", [15] = "0.21 0.34 0.37 1.0", [16] = "0.66 0.61 0.56 1.0"
}
;
private readonly Dictionary<BuildingGrade.Enum, HashSet<ulong>> BuildingSkins = new Dictionary<BuildingGrade.Enum, HashSet<ulong>>() {
{
BuildingGrade.Enum.Wood, new HashSet<ulong> {
999, 2, 10232
}
}
, {
BuildingGrade.Enum.Stone, new HashSet<ulong> {
1000, 10223, 10225, 10220
}
}
, {
BuildingGrade.Enum.Metal, new HashSet<ulong> {
1001, 10221
}
}
,
}
;
private readonly Dictionary<ulong, int> WallpaperSkins = new Dictionary<ulong, int>() {
{
0, -1501434104
}
, {
10246, -1501434104
}
, {
10243, -1501434104
}
, {
10242, -1501434104
}
, {
10266, -1501434104
}
, {
10263, -1501434104
}
, {
10262, -1501434104
}
, {
10261, -1501434104
}
, {
10260, -1501434104
}
, {
10259, -1501434104
}
, {
10258, -1501434104
}
, {
10257, -1501434104
}
, {
10256, -1501434104
}
, {
10255, -1501434104
}
, {
10254, -1501434104
}
, {
10253, -1501434104
}
, {
10252, -1501434104
}
, {
10251, -1501434104
}
, {
10250, -1501434104
}
, {
10249, -1501434104
}
, {
10248, -1501434104
}
, {
10247, -1501434104
}
, {
10245, -1501434104
}
, {
10244, -1501434104
}
, {
10267, -1501434104
}
, {
10268, -1501434104
}
,
}
;
private readonly Dictionary<string, string> imageList = new Dictionary<string, string>() {
{
"tclevels.icons.x", "https://i.ibb.co/K0cD7b7/x.png"
}
, {
"tclevels.icons.lock", "https://i.ibb.co/ZzkjrmQ/image.png"
}
, {
"tclevels.icons.info", "https://i.postimg.cc/qqwJym7X/info.png"
}
, {
"tclevels.icons.twig", "https://i.postimg.cc/kXgNJ00n/sticks.png"
}
, {
"tclevels.icons.wood", "https://i.postimg.cc/vm67dkB2/wood.png"
}
, {
"tclevels.icons.stone", "https://i.postimg.cc/DwNQHn2b/stones.png"
}
, {
"tclevels.icons.metal", "https://i.postimg.cc/Hkn46VCg/metal-fragments.png"
}
, {
"tclevels.icons.hqm", "https://i.postimg.cc/HsB90bRz/metal-refined.png"
}
, {
"tclevels.icons.deoply", "https://i.postimg.cc/HWcbkS67/cupboard-tool.png"
}
, {
"tclevels.icons.wood.frontier", "https://i.postimg.cc/ZKHDDc0w/frontier.png"
}
, {
"tclevels.icons.wood.ginger", "https://i.postimg.cc/X74z8hNZ/gingerbread.png"
}
, {
"tclevels.icons.stone.brick", "https://i.postimg.cc/rsLY7ZSP/brick.png"
}
, {
"tclevels.icons.stone.brutalist", "https://i.postimg.cc/tJtmbdkC/brutalist.png"
}
, {
"tclevels.icons.stone.adobe", "https://i.postimg.cc/9XGkyV25/adobe.png"
}
, {
"tclevels.icons.metal.container", "https://i.postimg.cc/gJhTSb6h/container.png"
}
, {
"tclevels.icons.wood.normal", "https://i.postimg.cc/xCnfkzXv/wood-1.png"
}
, {
"tclevels.icons.stone.normal", "https://i.postimg.cc/6Qd650p6/stone.png"
}
, {
"tclevels.icons.metal.normal", "https://i.postimg.cc/MGkKS4xr/metal.png"
}
, {
"tclevels.icons.random", "https://i.postimg.cc/43kBx8vB/dRFs4.png"
}
}
;
#endregion
#region Config
protected override void LoadConfig() {
base.LoadConfig();
config = Config.ReadObject<Configuration>();
if (config.Version < Version) UpdateConfigValues();
Config.WriteObject(config, true);
}
protected override void SaveConfig() => Config.WriteObject(config, true);
protected override void LoadDefaultConfig() => config = GetBaseConfig();
private void UpdateConfigValues() {
PrintWarning("Your config file is outdated! Updating config values...");
config.Version = Version;
PrintWarning("Config updated!");
}
private class Configuration {
[JsonProperty(PropertyName = "General Options")]
public GeneralOptions General {
get;
set;
}
[JsonProperty(PropertyName = "Features")]
public FeaturesOptions Features {
get;
set;
}
[JsonProperty(PropertyName = "Notifications")]
public Notifications notifications {
get;
set;
}
public VersionNumber Version {
get;
set;
}
}
private class GeneralOptions {
[JsonProperty("Only owner can use features of TC")]
public bool onlyOwner {
get;
set;
}
[JsonProperty("Support for NoEscape plugin")]
public bool supportNoEscape {
get;
set;
}
[JsonProperty("Support for CombatBlock plugin")]
///
public bool supportCombatBlock {
get;
set;
}
[JsonProperty("Use Automatic Upgrades on build")]
///
public bool autoUponBuild {
get;
set;
}
}
private class Options {
[JsonProperty("Enable Use")]
public bool enableUse {
get;
set;
}
[JsonProperty("Default use frequency time in sec")]
public float defaultTime {
get;
set;
}
[JsonProperty("Permissions use frequency time in sec", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> permissions {
get;
set;
}
}
private class UIOptions {
[JsonProperty("UI Buttons Default offset")]
public string btnOffsets {
get;
set;
}
}
private class Notifications {
[JsonProperty("Enable chat notifications")]
public bool EenableChatNotify {
get;
set;
}
[JsonProperty("Chat notify prefix")]
public string Prefix {
get;
set;
}
[JsonProperty("Chat notify avatarID")]
public ulong Avatarid {
get;
set;
}
[JsonProperty("Enable GameTip notify")]
public bool EenableGameTipnotify {
get;
set;
}
[JsonProperty("Notifications plugin (0 = disabled | 1 = Toastify | 2 = Notify)")]
public NotificationPluginType NotificationPlugin {
get;
set;
}
[JsonProperty("Sync your notifications ID with below keywords")]
public NotificationsType NotificationTypes {
get;
set;
}
}
private class FeaturesOptions {
[JsonProperty("Enable Auth List")]
public AuthListOptions auttOptions {
get;
set;
}
[JsonProperty("Enable auto upgrade base")]
public Options EnableAutoUpgradeBase {
get;
set;
}
[JsonProperty("Enable base skin upgrade")]
public Options EnableBaseSkinUpgrade {
get;
set;
}
[JsonProperty("Enable base wallpaper upgrade")]
public Options EnableBaseWallpaperUpgrade {
get;
set;
}
[JsonProperty("Enable base repair upgrade")]
public Options EnableBaseRepairUpgrade {
get;
set;
}
}
private class AuthListOptions {
[JsonProperty(PropertyName = "Enable Auth List")]
public bool enable {
get;
set;
}
[JsonProperty("Only owner can see the Remove BTN?")]
public bool onlyOwnerRemoveBTN {
get;
set;
}
}
private class NotificationsType {
public string Error {
get;
set;
}
public string Success {
get;
set;
}
public string Info {
get;
set;
}
}
private Configuration GetBaseConfig() {
return new Configuration() {
General = new GeneralOptions() {
onlyOwner = false, supportNoEscape = true, supportCombatBlock = false, autoUponBuild = true
}
, Features = new FeaturesOptions() {
auttOptions = new AuthListOptions() {
enable = true, onlyOwnerRemoveBTN = false
}
, EnableAutoUpgradeBase = new Options() {
enableUse = true, defaultTime = 1.5f, permissions = new Dictionary<string, float>() {
{
"tcupgrades.vip", 1.0f
}
, {
"tcupgrades.mvp", 5
}
,
}
}
, EnableBaseSkinUpgrade = new Options() {
enableUse = true, defaultTime = 1.5f, permissions = new Dictionary<string, float>() {
{
"tcupgrades.vip", 1.0f
}
, {
"tcupgrades.mvp", 5
}
,
}
}
, EnableBaseWallpaperUpgrade = new Options() {
enableUse = true, defaultTime = 1.5f, permissions = new Dictionary<string, float>() {
{
"tcupgrades.vip", 1.0f
}
, {
"tcupgrades.mvp", 5
}
,
}
}
, EnableBaseRepairUpgrade = new Options() {
enableUse = true, defaultTime = 1.5f, permissions = new Dictionary<string, float>() {
{
"tcupgrades.vip", 1.0f
}
, {
"tcupgrades.mvp", 5
}
,
}
}
,
}
, notifications = new Notifications() {
EenableChatNotify = true, Prefix = "<color=red>TC UPGRADES:</color>", Avatarid = 0, EenableGameTipnotify = true, NotificationPlugin = NotificationPluginType.None, NotificationTypes = new NotificationsType() {
Error = "error", Success = "success", Info = "info"
}
}
, Version = Version
}
;
}
#endregion
#region Data
private Hash<ulong, PlayerState> playersState = new Hash<ulong, PlayerState>();
private StoredData data = new StoredData();
private class PlayerState {
[JsonIgnore]
public ulong cupboardId;
[JsonIgnore]
public bool UIon;
[JsonIgnore]
public Coroutine upgradeCoroutine;
[JsonIgnore]
public Coroutine repairCoroutine;
[JsonIgnore]
public Coroutine skinCoroutine;
[JsonIgnore]
public Coroutine wallpaperCoroutine;
public ulong Wood = 0;
public ulong Stone = 0;
public ulong Metal = 0;
public ulong HQM = 0;
public uint MetalColor = 1;
public bool ShowEffect = true;
}
private class StoredData {
public Dictionary<ulong, PlayerState> playerData = new();
}
private void SaveData() {
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/{Name}", data);
}
private void LoadData() {
data = Interface.Oxide.DataFileSystem.ReadObject<StoredData>($"{Name}/{Name}");
if (data == null) {
data = new StoredData();
}
foreach (var d in data.playerData) {
playersState.Add(d.Key, d.Value);
}
}
#endregion
#region Lang
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string>() {
{
"AlreadyUpgrading", "There is already an upgrade processing, please wait for it to finish."
}
, {
"AlreadyRepairing", "There is already an repair processing, please wait for it to finish."
}
, {
"AlreadySkining", "There is already an base skining processing, please wait for it to finish."
}
, {
"AlreadyWallpaper", "There is already an wallpaper processing, please wait for it to finish."
}
, {
"NoResources", "Not enough resources found in tool cupboard to upgrade"
}
, {
"UpgradeComplete", "Materials upgrade completed"
}
, {
"RepairComplete", "Materials repair completed"
}
, {
"SkiningComplete", "Base skining completed"
}
, {
"WallpaperComplete", "Base wallpaper completed"
}
, {
"ProgressStatus", "Successfully updated {0} out of {1} items."
}
, {
"RaidBlocked", "You can't use this while you have Raid Block."
}
, {
"CombatBlocked", "You can't use this while you have Combat Block."
}
, {
"StopCoro", "The process has been successfully stopped."
}
, {
"NoPerm", "You don't have permission to use this."
}
, {
"AUTHBTN", "AUTHS"
}
, {
"UPGRADEBTN", "UPGRADE"
}
, {
"REPAIRBTN", "REPAIR"
}
, {
"SKINBTN", "SKIN"
}
, {
"WALLPAPERBTN", "WALLPAPER"
}
, {
"EFFECTSON", "EFFECTS ON"
}
, {
"EFFECTSOFF", "EFFECTS OFF"
}
,
}
, this);
}
#endregion
#region Commands
[ConsoleCommand("tcupgrades.cmd")]
private void ConsoleCommandThings(ConsoleSystem.Arg arg) {
BasePlayer player = arg?.Player();
if (player == null) {
return;
}
string command = arg.Args[0];
var tc = player.GetBuildingPrivilege();
SoundEffect(player, ClickFX);
switch (command) {
case "cancelProcess" : {
DestroyUI(player);
StopPlayerCoroutine(player);
SendMessage(player, "StopCoro");
SendNotification(player, "error", "StopCoro");
NextTick(() => {
OnLootEntity(player, tc);
}
);
return;
}
case "authList" : {
DestroySide(player);
AuthList(player);
return;
}
case "changeEffects" : {
CuiHelper.DestroyUi(player, "EffectBTN");
if (!playersState.TryGetValue(player.userID, out PlayerState value)) {
value = new PlayerState();
playersState.Add(player.userID, value);
}
value.ShowEffect = !value.ShowEffect;
EffectBTN(player);
return;
}
case "close_authlist" : {
CuiHelper.DestroyUi(player, "AuthList");
return;
}
case "close_UpgradeMat" : {
CuiHelper.DestroyUi(player, "UpgradeMaterial");
CuiHelper.DestroyUi(player, "EffectBTN");
return;
}
case "close_RepairBase" : {
CuiHelper.DestroyUi(player, "RepairBase");
CuiHelper.DestroyUi(player, "EffectBTN");
return;
}
case "close_SkinBase" : {
CuiHelper.DestroyUi(player, "SkinBase");
CuiHelper.DestroyUi(player, "EffectBTN");
return;
}
case "close_Wallpapers" : {
CuiHelper.DestroyUi(player, "WallpaperCg");
CuiHelper.DestroyUi(player, "ShowWallpaper");
CuiHelper.DestroyUi(player, "EffectBTN");
return;
}
case "close_WallpaperShow" : {
CuiHelper.DestroyUi(player, "WallpaperCg");
CuiHelper.DestroyUi(player, "ShowWallpaper");
CuiHelper.DestroyUi(player, "EffectBTN");
return;
}
case "removeFromAuth" : {
ulong id;
ulong playerID;
if (!ulong.TryParse(arg.Args[1], out id)) {
Puts("Failed to parse 'id' from arguments.");
return;
}
if (!ulong.TryParse(arg.Args[2], out playerID)) {
return;
}
if (tc == null) {
return;
}
if (!tc.IsAuthed(player)) {
return;
}
tc.authorizedPlayers.RemoveWhere(x => x.userid == playerID);
tc.SendNetworkUpdate();
AuthList(player);
return;
}
case "addToPromote" : {
ulong id;
ulong playerID;
if (!ulong.TryParse(arg.Args[1], out id)) {
return;
}
if (!ulong.TryParse(arg.Args[2], out playerID)) {
return;
}
return;
}
case "upgradeMaterials" : {
DestroySide(player);
UpgradeMaterial(player);
EffectBTN(player);
return;
}
case "selectToUpgrade" : {
if (!playersState.TryGetValue(player.userID, out PlayerState value)) {
value = new PlayerState();
playersState.Add(player.userID, value);
}
string material = arg.Args[1];
DestroySide(player);
UpgradeMaterial(player, material);
EffectBTN(player);
return;
}
case "upgradeTo" : {
if (IsBlocked(player)) return;
if (!playersState.TryGetValue(player.userID, out PlayerState value)) {
value = new PlayerState();
playersState.Add(player.userID, value);
}
string materialFrom = arg.Args[1];
string materialTo = arg.Args[2];
if (playersState[player.userID].upgradeCoroutine != null) {
DestroySide(player);
SendMessage(player, "AlreadyUpgrading");
SendNotification(player, "error", "AlreadyUpgrading");
return;
}
if (!ValidPermission(player, materialTo)) {
SendMessage(player, "NoPerm");
SendNotification(player, "error", "NoPerm");
return;
}
DestroySide(player);
playersState[player.userID].upgradeCoroutine = ServerMgr.Instance.StartCoroutine(UpgradeMaterialTC(player, tc, materialFrom, materialTo));
NextTick(() => {
CreateUpgradeButton(player, tc.net.ID.Value);
}
);
return;
}
case "repairBase" : {
DestroySide(player);
RepairBaseMaterial(player);
EffectBTN(player);
return;
}
case "repairBaseMat" : {
if (IsBlocked(player)) return;
if (!playersState.TryGetValue(player.userID, out PlayerState value)) {
value = new PlayerState();
playersState.Add(player.userID, value);
}
if (playersState[player.userID].repairCoroutine != null) {
DestroySide(player);
SendMessage(player, "AlreadyRepairing");
SendNotification(player, "error", "AlreadyRepairing");
return;
}
string material = arg.Args[1];
if (!ValidPermission(player, material)) {
SendMessage(player, "NoPerm");
SendNotification(player, "error", "NoPerm");
return;
}
DestroySide(player);
if (material == "deploy") {
playersState[player.userID].repairCoroutine = ServerMgr.Instance.StartCoroutine(RepairMaterialTCDeploy(player, tc, material));
}
else {
playersState[player.userID].repairCoroutine = ServerMgr.Instance.StartCoroutine(RepairMaterialTC(player, tc, material));
}
NextTick(() => {
CreateUpgradeButton(player, tc.net.ID.Value);
}
);
return;
}
case "skinBaseSelect" : {
DestroySide(player);
SkinBaseUpgrade(player);
EffectBTN(player);
return;
}
case "skinBaseStart" : {
if (IsBlocked(player)) return;
if (!playersState.TryGetValue(player.userID, out PlayerState value)) {
value = new PlayerState();
playersState.Add(player.userID, value);
}
if (playersState[player.userID].skinCoroutine != null) {
DestroySide(player);
SendMessage(player, "AlreadySkining");
SendNotification(player, "error", "AlreadySkining");
return;
}
DestroySide(player);
if (ulong.TryParse(arg.Args[1], out var skinID)) {
var skinGrade = GetBuildingGradeFromSkin(skinID);
if (skinGrade == BuildingGrade.Enum.Metal && (GetNatID(skinID) != 0)) {
DestroySide(player);
SkinBaseUpgrade(player, true);
EffectBTN(player);
}
else {
playersState[player.userID].skinCoroutine = ServerMgr.Instance.StartCoroutine(SkiningBaseTC(player, tc, skinID));
}
}
NextTick(() => {
CreateUpgradeButton(player, tc.net.ID.Value);
}
);
return;
}
case "skinBaseSetColor" : {
if (IsBlocked(player)) return;
bool random = false;
DestroySide(player);
uint color = Convert.ToUInt32(arg.Args[1]);
ulong SkinID = ulong.Parse(arg.Args[2]);
if (color == 9999) {
random = true;
color = 1;
}
SetPlayerSkinID(player, BuildingGrade.Enum.Metal, SkinID, color);
if (!playersState.TryGetValue(player.userID, out PlayerState value)) {
value = new PlayerState();
playersState.Add(player.userID, value);
}
if (playersState[player.userID].skinCoroutine != null) {
DestroySide(player);
SendMessage(player, "AlreadySkining");
SendNotification(player, "error", "AlreadySkining");
return;
}
DestroySide(player);
playersState[player.userID].skinCoroutine = ServerMgr.Instance.StartCoroutine(SkiningBaseTC(player, tc, SkinID, random));
NextTick(() => {
CreateUpgradeButton(player, tc.net.ID.Value);
}
);
return;
}
case "showWallpapersView" : {
DestroySide(player);
ChangeWallpaper(player);
EffectBTN(player);
return;
}
case "viewWallpaper" : {
DestroySide(player);
string material = arg.Args[1];
ShowWallpapers(player, material);
EffectBTN(player);
return;
}
case "changeWallpaper" : {
if (IsBlocked(player)) return;
if (!playersState.TryGetValue(player.userID, out PlayerState value)) {
value = new PlayerState();
playersState.Add(player.userID, value);
}
if (playersState[player.userID].wallpaperCoroutine != null) {
DestroySide(player);
SendMessage(player, "AlreadyWallpaper");
SendNotification(player, "error", "AlreadyWallpaper");
return;
}
ulong wallpaperID = ulong.Parse(arg.Args[1]);
string material = arg.Args[2];
if (!ValidPermission(player, material)) {
SendMessage(player, "NoPerm");
SendNotification(player, "error", "NoPerm");
return;
}
DestroySide(player);
playersState[player.userID].wallpaperCoroutine = ServerMgr.Instance.StartCoroutine(WallpaperSkinProgress(player, tc, wallpaperID, material));
NextTick(() => {
CreateUpgradeButton(player, tc.net.ID.Value);
}
);
return;
}
}
}
#endregion
#region Init
private void OnServerInitialized() {
if (ImageLibrary == null) {
Interface.Oxide.LogError("Missing ImageLibrary plugin; Download it at: https://umod.org/plugins/image-library");
Interface.Oxide.UnloadPlugin(Name);
return;
}
LoadData();
RegisterImages();
RegisterStaticPerms();
RegisterCustomPerms();
}
private void Unload() {
SaveData();
foreach (BasePlayer player in BasePlayer.activePlayerList) {
DestroyUI(player);
}
}
private void OnServerSave() {
SaveData();
}
private void OnNewSave(string filename) {
if (data != null && data.playerData != null) {
data.playerData.Clear();
SaveData();
}
}
#endregion
#region IEnumerators
private IEnumerator WallpaperSkinProgress(BasePlayer player, BuildingPrivlidge tc, ulong wallpaperID, string material) {
var Grade = BuildingGrade.Enum.Twigs;
if (material == "wood") Grade = BuildingGrade.Enum.Wood;
if (material == "stone") Grade = BuildingGrade.Enum.Stone;
if (material == "metal") Grade = BuildingGrade.Enum.Metal;
if (material == "hqm") Grade = BuildingGrade.Enum.TopTier;
var buildings = tc.GetBuilding().buildingBlocks;
yield return CoroutineEx.waitForSeconds(0.15f);
var freq = GetPlayerFrequency(player, config.Features.EnableBaseWallpaperUpgrade);
int count = 0;
for (var i = 0; i < buildings.Count; i++) {
var block = buildings[i];
if (block == null || !block.IsValid() || block.IsDestroyed || block.transform == null) {
continue;
}
if (block.SecondsSinceAttacked < 30f) {
continue;
}
if (Grade != block.grade) continue;
//Puts(block.ShortPrefabName.ToString());
if (!block.ShortPrefabName.Contains("wall")) continue;
if (block.HasWallpaper() && block.wallpaperID == wallpaperID) continue;
if (!HasPermission(player, PermWallpaperNoCost) && !HasResoucesWallpaper(player, tc)) {
SendMessage(player, "NoResources");
SendNotification(player, "error", "NoResources");
playersState[player.userID].wallpaperCoroutine = null;
CheckForUIs(player);
yield break;
}
if (!HasPermission(player, PermWallpaperNoCost)) {
TakeFromInv(tc.inventory.itemList, "cloth", 10);
}
block.RemoveWallpaper(0);
block.SetWallpaper(wallpaperID);
if (CheckWallpaper(block)) {
block.RemoveWallpaper(1);
block.SetWallpaper(wallpaperID, 1);
}
block.SendNetworkUpdate();
count++;
if (playersState[player.userID].ShowEffect) {
Effect.server.Run("assets/prefabs/deployable/repair bench/effects/skinchange_spraypaint.prefab", block.transform.position);
Effect.server.Run("assets/prefabs/deployable/research table/effects/research-success.prefab", block.transform.position);
}
yield return CoroutineEx.waitForSeconds(freq);
}
yield return CoroutineEx.waitForSeconds(0.15f);
SendMessage(player, "WallpaperComplete");
SendNotification(player, "success", "WallpaperComplete");
SendMessage(player, "ProgressStatus", count, buildings.Count.ToString());
playersState[player.userID].wallpaperCoroutine = null;
CheckForUIs(player);
yield return null;
}
private bool CheckWallpaper(BuildingBlock block) {
Construction construction = WallpaperPlanner.Settings?.GetConstruction(block);
if (!(construction == null) && !SocketMod_Inside.IsOutside(block.transform.position + construction.deployOffset.localPosition + block.transform.right * 0.2f, block.transform)) {
return true;
}
return false;
}
private ulong GetNatID(ulong id) {
if (id == 999 || id == 1000 || id == 1001) return 0;
return id;
}
private IEnumerator SkiningBaseTC(BasePlayer player, BuildingPrivlidge tc, ulong id, bool random = false) {
var buildings = tc.GetBuilding().buildingBlocks;
yield return CoroutineEx.waitForSeconds(0.15f);
var freq = GetPlayerFrequency(player, config.Features.EnableBaseSkinUpgrade);
int count = 0;
for (var i = 0; i < buildings.Count; i++) {
var block = buildings[i];
if (block == null || !block.IsValid() || block.IsDestroyed || block.transform == null) {
continue;
}
if (block.SecondsSinceAttacked < 30f) {
continue;
}
if (!BuildingSkins.TryGetValue(block.grade, out var gradeSkins)) {
continue;
}
var skinGrade = GetBuildingGradeFromSkin(id);
if (block.grade != skinGrade) {
//Puts("Block grade (" + block.grade + ") does not match skin grade (" + skinGrade + ")");
continue;
}
/*if (GetNatID(id) == block.skinID)
{
Puts("Block already has skinID: " + block.skinID);
continue;
}*/
block.skinID = GetNatID(id);
block.UpdateSkin();
// Set custom color if it's a metal block
if (block.skinID != 0 && block.grade.ToString() == "Metal") {
//Puts("block: " + block.grade.ToString() + " skin: " + block.skinID.ToString() + " id: " + id.ToString() + " bC: " + block.customColour.ToString() + " PC: " + GetPlayerMetalColorID(player, BuildingGrade.Enum.Metal));
block.SetCustomColour(GetPlayerMetalColorID(player, BuildingGrade.Enum.Metal, random));
}
// Save the player's skin ID
//Puts("block: " + block.grade.ToString() + " skin: " + block.skinID.ToString() + " id: " + id.ToString() + " bC: " + block.customColour.ToString() + " PC: " + GetPlayerMetalColorID(player, BuildingGrade.Enum.Metal));
SetPlayerSkinID(player, block.grade, id, block.customColour);
block.SendNetworkUpdateImmediate();
if (playersState[player.userID].ShowEffect) {
Effect.server.Run("assets/prefabs/deployable/repair bench/effects/skinchange_spraypaint.prefab", block.transform.position);
Effect.server.Run("assets/prefabs/deployable/research table/effects/research-success.prefab", block.transform.position);
}
count++;
yield return CoroutineEx.waitForSeconds(freq);
}
yield return CoroutineEx.waitForSeconds(0.15f);
SendMessage(player, "SkiningComplete");
SendNotification(player, "success", "SkiningComplete");
SendMessage(player, "ProgressStatus", count, buildings.Count.ToString());
playersState[player.userID].skinCoroutine = null;
CheckForUIs(player);
yield return null;
}
private IEnumerator RepairMaterialTC(BasePlayer player, BuildingPrivlidge tc, string material) {
var RepairGrade = BuildingGrade.Enum.Wood;
if (material == "wood") RepairGrade = BuildingGrade.Enum.Wood;
if (material == "stone") RepairGrade = BuildingGrade.Enum.Stone;
if (material == "metal") RepairGrade = BuildingGrade.Enum.Metal;
if (material == "hqm") RepairGrade = BuildingGrade.Enum.TopTier;
var buildings = tc.GetBuilding().buildingBlocks;
yield return CoroutineEx.waitForSeconds(0.15f);
var freq = GetPlayerFrequency(player, config.Features.EnableBaseRepairUpgrade);
int count = 0;
for (var i = 0; i < buildings.Count; i++) {
var entity = buildings[i];
if (entity == null || !entity.IsValid() || entity.IsDestroyed || entity.transform == null || !entity.repair.enabled || entity.grade != RepairGrade || entity.health == entity.MaxHealth()) continue;
var missingHealth = entity.MaxHealth() - entity.health;
var healthPercentage = missingHealth / entity.MaxHealth();
if (healthPercentage <= 0 || missingHealth <= 0) continue;
if (!HasPermission(player, PermRepairNoCost) && !HasResoucesRepair(player, tc, entity, healthPercentage)) {
SendMessage(player, "NoResources");
SendNotification(player, "error", "NoResources");
playersState[player.userID].repairCoroutine = null;
CheckForUIs(player);
yield break;
}
if (!HasPermission(player, PermRepairNoCost)) {
var list = entity.RepairCost(healthPercentage);
for (var index = 0; index < list.Count; index++) {
var check = list[index];
TakeFromInv(tc.inventory.itemList, check.itemDef.shortname, (int)check.amount);
}
}
entity.health += missingHealth;
entity.SendNetworkUpdate();
if (playersState[player.userID].ShowEffect) {
if (entity.health < entity.MaxHealth()) {
entity.OnRepair();
}
else {
entity.OnRepairFinished();
}
}
count++;
yield return CoroutineEx.waitForSeconds(freq);
}
yield return CoroutineEx.waitForSeconds(0.15f);
SendMessage(player, "RepairComplete");
SendNotification(player, "success", "RepairComplete");
SendMessage(player, "ProgressStatus", count, buildings.Count.ToString());
playersState[player.userID].repairCoroutine = null;
CheckForUIs(player);
yield return null;
}
private IEnumerator RepairMaterialTCDeploy(BasePlayer player, BuildingPrivlidge tc, string material) {
if (material != "deploy") yield break;
var buildings = tc.GetBuilding().decayEntities;
yield return CoroutineEx.waitForSeconds(0.15f);
var freq = GetPlayerFrequency(player, config.Features.EnableBaseRepairUpgrade);
int count = 0;
for (var i = 0; i < buildings.Count; i++) {
var entity = buildings[i];
if (entity == null || !entity.IsValid() || entity.IsDestroyed || entity.transform == null || !entity.repair.enabled || entity.health == entity.MaxHealth()) continue;
//Puts(entity.PrefabName);
if (IsBuildingBlock(entity)) continue;
var missingHealth = entity.MaxHealth() - entity.health;
var healthPercentage = missingHealth / entity.MaxHealth();
if (healthPercentage <= 0 || missingHeal
// ... [Code preview truncated due to length. Full source in attached file] ...