C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using System.Collections;
using UnityEngine;
using Oxide.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using System;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using System.Threading.Tasks;
using System.Text;
using System.Text.RegularExpressions;
namespace Oxide.Plugins {
[Info("Quality Crafting", "mr01sam", "2.1.2")]
[Description("Players can level crafting skills to produce higher quality items that have better stats than vanilla items.")]
partial class QualityCrafting : CovalencePlugin {
/* CHANGELOG
* - Updated for May 4th update
* - Fixed issue where storage containers would not update when moving items
* - Fixed OnInventoryNetwork update error
*/
private static QualityCrafting PLUGIN;
public const string PermissionAdmin = "qualitycrafting.admin";
[PluginReference]
private Plugin ImageLibrary;
private Guid Secret {
get;
set;
}
= Guid.NewGuid();
bool ServerInitialized {
get;
set;
}
= false;
#region Initialization
void Init() {
UnsubscribeAll();
PLUGIN = this;
permission.RegisterPermission(PermissionAdmin, this);
}
void Unload() {
SaveAll();
foreach (var basePlayer in BasePlayer.activePlayerList) {
UnloadPlayer(basePlayer);
}
}
private void OnServerInitialized(bool initial) {
try {
ImageLibrary.Call("isLoaded", null);
}
catch (Exception) {
PrintWarning($"The required dependency ImageLibary is not installed, {Name} will not work properly without it.");
return;
}
LoadImages();
LoadAll();
LoadItemImages();
foreach (var basePlayer in BasePlayer.activePlayerList) {
LoadPlayer(basePlayer);
}
SubscribeAll();
ServerInitialized = true;
}
void OnPlayerSleepEnded(BasePlayer basePlayer) {
LoadPlayer(basePlayer);
}
object OnPlayerDeath(BasePlayer basePlayer, HitInfo info) {
UnloadPlayer(basePlayer);
return null;
}
void SubscribeAll() {
Subscribe(nameof(Unload));
Subscribe(nameof(OnPlayerSleepEnded));
Subscribe(nameof(OnPlayerDeath));
Subscribe(nameof(OnItemAction));
Subscribe(nameof(OnItemCraft));
Subscribe(nameof(OnItemCraftFinished));
Subscribe(nameof(OnPlayerInput));
Subscribe(nameof(OnActiveItemChanged));
Subscribe(nameof(OnVendingShopOpened));
Subscribe(nameof(OnLootEntity));
Subscribe(nameof(OnLootEntityEnd));
Subscribe(nameof(OnInventoryNetworkUpdate));
Subscribe(nameof(OnLootNetworkUpdate));
Subscribe(nameof(OnEntityTakeDamage));
Subscribe(nameof(OnServerShutdown));
Subscribe(nameof(OnServerSave));
}
void UnsubscribeAll() {
Unsubscribe(nameof(Unload));
Unsubscribe(nameof(OnPlayerSleepEnded));
Unsubscribe(nameof(OnPlayerDeath));
Unsubscribe(nameof(OnItemAction));
Unsubscribe(nameof(OnItemCraft));
Unsubscribe(nameof(OnItemCraftFinished));
Unsubscribe(nameof(OnPlayerInput));
Unsubscribe(nameof(OnActiveItemChanged));
Unsubscribe(nameof(OnVendingShopOpened));
Unsubscribe(nameof(OnLootEntity));
Unsubscribe(nameof(OnLootEntityEnd));
Unsubscribe(nameof(OnInventoryNetworkUpdate));
Unsubscribe(nameof(OnLootNetworkUpdate));
Unsubscribe(nameof(OnEntityTakeDamage));
Unsubscribe(nameof(OnServerShutdown));
Unsubscribe(nameof(OnServerSave));
}
void LoadPlayer(BasePlayer basePlayer) {
RefreshOverlays(basePlayer);
ShowAllButtons(basePlayer);
ShowTrackingHud(basePlayer);
}
void UnloadPlayer(BasePlayer basePlayer) {
DestroyAllOverlays(basePlayer);
DestroyAllMenus(basePlayer);
DestroyAllButtons(basePlayer);
DestroyTrackingHud(basePlayer);
NotificationManager.DestroyAllNotifications(basePlayer);
}
void OnServerShutdown() {
SaveAll();
}
void OnServerSave() {
SaveAll();
}
void LoadImages() {
ImageLibrary.Call<bool>("AddImage", config.HUD.InspectButton.Icon, $"qc.inspect", 0UL);
ImageLibrary.Call<bool>("AddImage", config.Qualities.IconQualityStar, $"qc.star", 0UL);
ImageLibrary.Call<bool>("AddImage", config.Qualities.Tier1.Icon, $"qc.star.1", 0UL);
ImageLibrary.Call<bool>("AddImage", config.Qualities.Tier2.Icon, $"qc.star.2", 0UL);
ImageLibrary.Call<bool>("AddImage", config.Qualities.Tier3.Icon, $"qc.star.3", 0UL);
ImageLibrary.Call<bool>("AddImage", config.Qualities.Tier4.Icon, $"qc.star.4", 0UL);
ImageLibrary.Call<bool>("AddImage", config.Qualities.Tier5.Icon, $"qc.star.5", 0UL);
ImageLibrary.Call<bool>("AddImage", config.HUD.SkillsButton.Icon, $"qc.button.skills", 0UL);
ImageLibrary.Call<bool>("AddImage", config.HUD.InspectButton.Icon, $"qc.button.inspect", 0UL);
ImageLibrary.Call<bool>("AddImage", config.HUD.QualityButton.Icon, $"qc.button.quality", 0UL);
foreach (var category in SkillCategory.ALL) {
ImageLibrary.Call<bool>("AddImage", config.Categories[category.NameTitleCase].Icon, $"qc.category.{category.Name}", 0UL);
}
ImageLibrary.Call<bool>("AddImage", config.Images.ArrowUp, $"qc.up", 0UL);
ImageLibrary.Call<bool>("AddImage", config.Images.ArrowDown, $"qc.down", 0UL);
ImageLibrary.Call<bool>("AddImage", config.Images.Close, $"qc.close", 0UL);
ImageLibrary.Call<bool>("AddImage", config.Images.Help, $"qc.help", 0UL);
}
void LoadItemImages() {
var url = "https://rustlabs.com/img/items180/";
var itemList = ItemManager.itemList.ToDictionary(keySelector : m => m.shortname, elementSelector : m => $"{url}{m.shortname}");
ImageLibrary.Call("ImportImageList", Name, itemList, 0, false, new Action(() => {
}
));
}
void LoadAll() {
CraftingManager.Load();
TrackingManager.Load();
}
void SaveAll() {
CraftingManager.Save();
TrackingManager.Save();
}
#endregion
}
}
namespace Oxide.Plugins {
partial class QualityCrafting : CovalencePlugin {
private static readonly string PREFIX = "qc";
#region Premade Arguments
private static readonly CommandArgument SKILL_ARGUMENT = new CommandArgument {
Parameter = "skill", Validate = (given) => {
SkillCategory category;
category = SkillCategory.GetByName(given.ToLower());
if (category == null) {
category = SkillCategory.GetByItemName(given);
}
return category == null ? new ValidationResponse(ValidationStatusCode.INVALID_VALUE, given) : new ValidationResponse();
}
}
;
private static readonly CommandArgument CATEGORY_ARGUMENT = new CommandArgument {
Parameter = "category", Validate = (given) => {
SkillCategory category;
category = SkillCategory.GetByName(given.ToLower());
return category == null ? new ValidationResponse(ValidationStatusCode.INVALID_VALUE, given) : new ValidationResponse();
}
}
;
private static readonly CommandArgument QUALITY_ARGUMENT = new CommandArgument {
Parameter = "quality", Validate = (given) => {
int intValue;
if (int.TryParse(given, out intValue) && intValue >= 0 && intValue <= 5) {
return new ValidationResponse();
}
return new ValidationResponse(ValidationStatusCode.INVALID_VALUE, given);
}
}
;
private static readonly CommandArgument XP_RATE_ARGUMENT = new CommandArgument {
Parameter = "multiplier", Optional = true, Validate = (given) => {
float floatValue;
if (float.TryParse(given, out floatValue) && floatValue >= 0) {
return new ValidationResponse();
}
return new ValidationResponse(ValidationStatusCode.INVALID_VALUE, given);
}
}
;
private static readonly CommandArgument XP_ARGUMENT = new CommandArgument {
Parameter = "xp", Validate = (given) => {
int intValue;
if (int.TryParse(given, out intValue)) {
return new ValidationResponse();
}
return new ValidationResponse(ValidationStatusCode.INVALID_VALUE, given);
}
}
;
private static readonly CommandArgument LEVEL_ARGUMENT = new CommandArgument {
Parameter = "level", Validate = (given) => {
int intValue;
if (int.TryParse(given, out intValue) && intValue >= 0 && intValue <= 100) {
return new ValidationResponse();
}
return new ValidationResponse(ValidationStatusCode.INVALID_VALUE, given);
}
}
;
#endregion
#region Commands
public static readonly List<CommandInfo> Commands = new List<CommandInfo>() {
new CommandInfo() {
Command = "help", Method = "CmdHelp", Description = "Opens the plugin help menu.", Rank = 1
}
, new CommandInfo() {
Command = "skills", Method = "CmdSkills", Description = "Opens the plugin skills menu.", Rank = 2
}
, new CommandInfo() {
Command = "buttons", Method = "CmdButtons", Description = "Toggles the visibility of the HUD buttons.", Arguments = new CommandArgument[] {
new CommandArgument {
Parameter = "show/hide", AllowedValues = new string[] {
"show", "hide"
}
}
}
}
, new CommandInfo() {
Command = "wipeskills", Method = "CmdWipeSkills", Description = "Wipes all skill xp data for a specified player.", Permission = PermissionAdmin, Arguments = new CommandArgument[] {
CommandArgument.PLAYER_NAME
}
,
}
, new CommandInfo() {
Command = "grantxp", Method = "CmdGrantXp", Description = "Grants the specified player crafting xp for the given item or category.", Permission = PermissionAdmin, Arguments = new CommandArgument[] {
CommandArgument.PLAYER_NAME, SKILL_ARGUMENT, XP_ARGUMENT
}
}
, new CommandInfo() {
Command = "grantlevel", Method = "CmdGrantLevel", Description = "Advances the crafting skill level of the specified player by the given amount.", Permission = PermissionAdmin, Arguments = new CommandArgument[] {
CommandArgument.PLAYER_NAME, SKILL_ARGUMENT, LEVEL_ARGUMENT
}
}
, new CommandInfo() {
Command = "setlevel", Method = "CmdSetLevel", Description = "Sets the crafting skill level for the given item or category.", Permission = PermissionAdmin, Arguments = new CommandArgument[] {
CommandArgument.PLAYER_NAME, SKILL_ARGUMENT, LEVEL_ARGUMENT
}
}
, new CommandInfo() {
Command = "setquality", Method = "CmdSetQuality", Description = "Sets the quality level of an item.If no item id is given, the current active item will be targeted.", Permission = PermissionAdmin, Arguments = new CommandArgument[] {
CommandArgument.PLAYER_NAME, QUALITY_ARGUMENT, new CommandArgument {
Parameter = "item uid", Optional = true
}
}
}
, new CommandInfo() {
Command = "xprate", Method = "CmdSetXpMultiplier", Description = "Temporarily overrides the configured xp multiplier for the given category.If a multiplier is not given, it will be reset to the default value.", Permission = PermissionAdmin, Arguments = new CommandArgument[] {
CATEGORY_ARGUMENT, XP_RATE_ARGUMENT
}
}
, new CommandInfo() {
Command = "getlevel", Method = "CmdGetLevel", Description = "Displays the crafting skill level information for the specified player", Permission = PermissionAdmin, Arguments = new CommandArgument[] {
CommandArgument.PLAYER_NAME, SKILL_ARGUMENT
}
}
}
;
#endregion
[Command("qc")]
private void CmdController(IPlayer player, string command, string[] args) {
try {
if (args.Length == 0) {
CmdHelp(player, command, args);
return;
}
var commandInfo = Commands.FirstOrDefault(x => x.Command == args[0]);
if (commandInfo == null) {
CmdHelp(player, command, args);
return;
}
// Permission
if (!player.IsAdmin && !player.IsServer) {
foreach (var perm in commandInfo.Permissions) {
if (!permission.UserHasPermission(player.Id, perm)) {
player.Reply(Lang("no permission", player.Id));
return;
}
}
}
args = args.Skip(1).ToArray();
// Validation
var resp = commandInfo.Validate(args);
if (resp.IsValid) {
commandInfo.Execute(player, command, args);
}
else {
string message = commandInfo.Usage(player, PREFIX);
switch (resp.StatusCode) {
case ValidationStatusCode.PLAYER_NOT_FOUND : message = Lang("player not found", player.Id, resp.Data);
break;
case ValidationStatusCode.INVALID_VALUE : case ValidationStatusCode.VALUE_NOT_ALLOWED : message = Lang("invalid value", player.Id, resp.Data);
break;
case ValidationStatusCode.SUCCESS : message = "weird";
break;
}
player.Reply(message);
}
}
catch (Exception) {
Lang("command error", player.Id);
}
}
private void CmdSkills(IPlayer player, string command, string[] args) {
if (player.IsServer) {
player.Reply(Lang("command success", player.Id));
return;
}
BasePlayer basePlayer = player.Object as BasePlayer;
ShowSkillsMenu(basePlayer, false);
}
private void CmdButtons(IPlayer player, string command, string[] args) {
if (player.IsServer) {
player.Reply(Lang("command success", player.Id));
return;
}
var toggle = args[0];
BasePlayer basePlayer = player.Object as BasePlayer;
if (toggle == "show") {
ShowAllButtons(basePlayer);
}
else {
DestroyAllButtons(basePlayer);
}
player.Reply(Lang("command success", player.Id));
}
private void CmdHelp(IPlayer player, string command, string[] args) {
if (player.IsServer) {
Puts("\n" + string.Join("\n", Commands.Select(x => $"{PREFIX} {x.Command} {x.ArgString}".PadRight(60) + x.Description)));
}
else {
BasePlayer basePlayer = player.Object as BasePlayer;
ShowHelpMenu(basePlayer, false, 1);
}
}
private void CmdWipeSkills(IPlayer player, string command, string[] args) {
var name = args[0];
var target = BasePlayer.FindAwakeOrSleeping(name);
CraftingManager.Clear(target);
player.Reply(Lang("command success", player.Id));
}
private void CmdGrantXp(IPlayer player, string command, string[] args) {
var name = args[0];
var skill = args[1].ToLower();
var xp = uint.Parse(args[2]);
var target = BasePlayer.FindAwakeOrSleeping(name);
var icon = "";
var displayName = "";
var oldLevel = 0;
var newLevel = 0;
var oldXp = 0f;
var newXp = 0f;
PlayerSkillSheet skills = CraftingManager.GetSkills(target);
SkillCategory category = SkillCategory.GetByName(skill);
if (category == null) {
var itemDef = ItemManager.itemList.FirstOrDefault(x => x.displayName.translated.ToLower() == skill);
category = SkillCategory.GetByItemDefinition(itemDef);
var item = ItemManager.Create(itemDef);
oldLevel = skills.GetLevel(item);
oldXp = skills.GetLevelPercent(item);
skills.GrantXP(item, xp);
newLevel = skills.GetLevel(item);
newXp = skills.GetLevelPercent(item);
icon = item.info.shortname;
displayName = item.info.displayName.translated;
}
else {
oldLevel = skills.GetLevel(category);
oldXp = skills.GetLevelPercent(category);
skills.GrantXP(category, xp);
ShowTrackingHud(target);
newLevel = skills.GetLevel(category);
newXp = skills.GetLevelPercent(category);
icon = $"qc.category.{skill}";
displayName = category.DisplayName(target);
}
NotificationManager.AddNotifications(target, new GainedXPNotification {
Icon = icon, SkillDisplayName = displayName, OldLevel = oldLevel, NewLevel = newLevel, OldXP = oldXp, NewXP = newXp, IsLevelUp = newLevel > oldLevel, XPGained = xp
}
);
player.Reply(Lang("command success", player.Id));
}
private void CmdSetLevel(IPlayer player, string command, string[] args) {
var name = args[0];
var target = BasePlayer.FindAwakeOrSleeping(name);
var skill = args[1].ToLower();
var level = int.Parse(args[2]);
PlayerSkillSheet skills = CraftingManager.GetSkills(target);
SkillCategory category = SkillCategory.GetByName(skill);
if (category == null) {
var itemDef = ItemManager.itemList.FirstOrDefault(x => x.displayName.translated.ToLower() == skill);
category = SkillCategory.GetByItemDefinition(itemDef);
var item = ItemManager.Create(itemDef);
skills.SetLevel(item, level);
}
else {
skills.SetLevel(category, level);
ShowTrackingHud(target);
}
player.Reply(Lang("command success", player.Id));
}
private void CmdSetQuality(IPlayer player, string command, string[] args) {
var name = args[0];
var target = BasePlayer.FindAwakeOrSleeping(name);
var quality = int.Parse(args[1]);
Item item;
if (args.Length == 2) {
item = target.GetActiveItem();
}
else {
var uid = ulong.Parse(args[2]);
item = target.inventory.FindItemUID(new ItemId(uid));
}
if (item != null) {
var qi = new QualityItem(item);
BasePlayer creator = null;
if (qi.HasCreator) {
creator = BasePlayer.FindAwakeOrSleeping(qi.CreatorId.ToString());
}
QualityItemManager.SetItemQuality(item, quality, creator);
QualityItemManager.ApplyQualityModifiers(item, quality);
}
player.Reply(Lang("command success", player.Id));
}
private void CmdSetXpMultiplier(IPlayer player, string command, string[] args) {
var categoryName = args[0];
var category = SkillCategory.GetByName(categoryName);
if (args.Length == 1) {
category.TemporaryMultiplier = null;
}
else {
var multiplier = float.Parse(args[1]);
category.TemporaryMultiplier = multiplier;
}
player.Reply(Lang("command success", player.Id));
}
private void CmdGrantLevel(IPlayer player, string command, string[] args) {
var playerName = args[0];
var basePlayer = BasePlayer.FindAwakeOrSleeping(playerName);
var skillName = args[1];
var amount = int.Parse(args[2]);
var category = SkillCategory.GetByName(skillName);
var skills = CraftingManager.GetSkills(basePlayer);
int level;
if (category == null) {
var item = ItemManager.Create(ItemManager.itemList.FirstOrDefault(x => x.displayName.translated.ToLower() == skillName.ToLower()));
level = skills.GetLevel(item);
skills.SetLevel(item, Math.Min(100, level + amount));
}
else {
level = skills.GetLevel(category);
skills.SetLevel(category, Math.Min(100, level + amount));
}
player.Reply(Lang("command success", player.Id));
}
private void CmdGetLevel(IPlayer player, string command, string[] args) {
var playerName = args[0];
var basePlayer = BasePlayer.FindAwakeOrSleeping(playerName);
var skillName = args[1];
int level;
string displayName;
var skills = CraftingManager.GetSkills(basePlayer);
var category = SkillCategory.GetByName(skillName);
if (category == null) {
var item = ItemManager.Create(ItemManager.itemList.FirstOrDefault(x => x.displayName.translated.ToLower() == skillName.ToLower()));
level = skills.GetLevel(item);
displayName = item.info.displayName.translated;
}
else {
level = skills.GetLevel(category);
displayName = category.DisplayName(basePlayer);
}
player.Reply($"{basePlayer.displayName} {displayName} {level}");
}
}
}
namespace Oxide.Plugins {
partial class QualityCrafting : CovalencePlugin {
private Configuration config;
private partial class Configuration {
[JsonProperty(PropertyName = "Version")]
public VersionNumber Version {
get;
set;
}
= new VersionNumber(0, 0, 0);
[JsonProperty(PropertyName = "General")]
public GeneralConfig Settings {
get;
set;
}
= new GeneralConfig();
[JsonProperty(PropertyName = "Categories")]
public Dictionary<string, CraftingCategoryConfig> Categories {
get;
set;
}
= SkillCategory.ALL.ToDictionary(x => x.Name.TitleCase(), x => new CraftingCategoryConfig() {
Icon = x.DefaultIcon
}
);
[JsonProperty(PropertyName = "Quality Tiers")]
public QualityConfig Qualities {
get;
set;
}
= new QualityConfig();
[JsonProperty(PropertyName = "Notifications")]
public NotificationConfig Notifications = new NotificationConfig();
[JsonProperty(PropertyName = "HUD")]
public HUDConfig HUD = new HUDConfig();
[JsonProperty(PropertyName = "Colors")]
public ColorsConfig Colors = new ColorsConfig();
[JsonProperty(PropertyName = "Sounds")]
public SFXConfig SFX = new SFXConfig();
[JsonProperty(PropertyName = "UI Images")]
public ImagesConfig Images = new ImagesConfig();
}
public class GeneralConfig {
[JsonProperty(PropertyName = "Blueprint XP Gain")]
public bool BlueprintXPGain = true;
}
public class HUDConfig {
[JsonProperty(PropertyName = "Inspect Button")]
public HUDButton InspectButton = new HUDButton {
Icon = "https://i.imgur.com/tPi2qM4.png", X = 407, Y = 19, Size = 25
}
;
[JsonProperty(PropertyName = "Quality Button")]
public HUDButton QualityButton = new HUDButton {
Icon = "https://i.imgur.com/KMWMn0K.png", X = 407, Y = 52, Size = 25
}
;
[JsonProperty(PropertyName = "Skills Button")]
public HUDButton SkillsButton = new HUDButton {
Icon = "https://i.imgur.com/x0Zg12R.png", X = 830, Y = 30, Size = 32
}
;
[JsonProperty(PropertyName = "Tracked Skill")]
public HUDElement TrackedSkill = new HUDElement {
X = 890, Y = 17, Size = 160
}
;
}
public class CraftingCategoryConfig {
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Icon")]
public string Icon {
get;
set;
}
[JsonProperty(PropertyName = "Base XP Multiplier")]
public float XPMultiplier {
get;
set;
}
= 1f;
[JsonProperty(PropertyName = "Base Crafting Speed")]
public float BaseCraftingSpeed {
get;
set;
}
= 1f;
[JsonProperty(PropertyName = "Perk Increases Per Level")]
public CraftingCategoryPerkConfig PerkIncreasesPerLevel {
get;
set;
}
= new CraftingCategoryPerkConfig();
}
public class CraftingCategoryPerkConfig {
[JsonProperty(PropertyName = "Crafting Speed")]
public float CraftingSpeed {
get;
set;
}
= 0.04f;
[JsonProperty(PropertyName = "Duplicate Chance")]
public float DuplicateChance {
get;
set;
}
= 0.002f;
}
public class HUDButton {
[JsonProperty(PropertyName = "Icon")]
public string Icon {
get;
set;
}
[JsonProperty(PropertyName = "X")]
public int X {
get;
set;
}
[JsonProperty(PropertyName = "Y")]
public int Y {
get;
set;
}
[JsonProperty(PropertyName = "Size")]
public int Size {
get;
set;
}
}
public class HUDElement {
[JsonProperty(PropertyName = "X")]
public int X {
get;
set;
}
[JsonProperty(PropertyName = "Y")]
public int Y {
get;
set;
}
[JsonProperty(PropertyName = "Size")]
public int Size {
get;
set;
}
}
public class ImagesConfig {
[JsonProperty(PropertyName = "Close")]
public string Close {
get;
set;
}
= "https://i.imgur.com/AbG6hrk.png";
[JsonProperty(PropertyName = "Help")]
public string Help {
get;
set;
}
= "https://i.imgur.com/tVSQyuX.png";
[JsonProperty(PropertyName = "Arrow Up")]
public string ArrowUp {
get;
set;
}
= "https://i.imgur.com/Mgua5IP.png";
[JsonProperty(PropertyName = "Arrow Down")]
public string ArrowDown {
get;
set;
}
= "https://i.imgur.com/L5kufsD.png";
}
public class QualityConfig {
[JsonProperty(PropertyName = "Star Icon")]
public string IconQualityStar = "https://imgur.com/fbELboi.png";
[JsonProperty(PropertyName = "Tier 0")]
public QualityTierConfig Tier0 = new QualityTierConfig() {
Color = "0.9 0.9 0.9 1"
}
;
[JsonProperty(PropertyName = "Tier 1")]
public QualityTierConfig Tier1 = new QualityTierConfig() {
Icon = "https://imgur.com/BKx4Hs8.png", Color = "0.11764 1 0 1"
}
;
[JsonProperty(PropertyName = "Tier 2")]
public QualityTierConfig Tier2 = new QualityTierConfig() {
Icon = "https://imgur.com/NSZTZ4v.png", Color = "0 0.43921 1 1"
}
;
[JsonProperty(PropertyName = "Tier 3")]
public QualityTierConfig Tier3 = new QualityTierConfig() {
Icon = "https://imgur.com/XSbgf72.png", Color = "0.63921 0.20784 0.93333 1"
}
;
[JsonProperty(PropertyName = "Tier 4")]
public QualityTierConfig Tier4 = new QualityTierConfig() {
Icon = "https://imgur.com/cEZUU9F.png", Color = "0.87531 0.70196 0 1"
}
;
[JsonProperty(PropertyName = "Tier 5")]
public QualityTierConfig Tier5 = new QualityTierConfig() {
Icon = "https://imgur.com/RD7ED4R.png", Color = "1 0.29803 0.14901 1"
}
;
[JsonProperty(PropertyName = "Percent Stat Increases Per Tier")]
public ModifiersConfig Modifiers = new ModifiersConfig();
}
public class QualityTierConfig {
[JsonProperty(PropertyName = "Icon")]
public string Icon {
get;
set;
}
= null;
[JsonProperty(PropertyName = "Color")]
public string Color {
get;
set;
}
}
public class ModifiersConfig {
[JsonProperty(PropertyName = "Projectile Damage")]
public float ProjectileDamage = 0.08f;
[JsonProperty(PropertyName = "Protection")]
public float Protection = 0.01f;
[JsonProperty(PropertyName = "Melee Damage")]
public float MeleeDamage = 0.20f;
[JsonProperty(PropertyName = "Durability")]
public float Durability = 0.20f;
[JsonProperty(PropertyName = "Gather Rate")]
public float GatherRate = 0.10f;
}
public class NotificationConfig {
[JsonProperty(PropertyName = "Item Crafted Notification")]
public NotificationUIConfig ItemCraftedNotification = new NotificationUIConfig() {
Show = true, X = 480, Y = 124
}
;
[JsonProperty(PropertyName = "XP Gained Notification")]
public NotificationUIConfig LevelUpItemNotification = new NotificationUIConfig() {
Show = true, X = 480, Y = 124
}
;
}
public class NotificationUIConfig {
[JsonProperty(PropertyName = "Show")]
public bool Show;
[JsonProperty(PropertyName = "X")]
public int X;
[JsonProperty(PropertyName = "Y")]
public int Y;
}
public class ColorsConfig {
[JsonProperty(PropertyName = "HUD Background")]
public string HUDBackground {
get;
set;
}
= "0.5 0.5 0.5 0.5";
[JsonProperty(PropertyName = "Menu Background")]
public string MenuBackground {
get;
set;
}
= "0.16078 0.16078 0.12941 1";
[JsonProperty(PropertyName = "HUD Button Toggled")]
public string HUDButtonToggled {
get;
set;
}
= "1 1 1 1";
[JsonProperty(PropertyName = "HUD Button Untoggled")]
public string HUDButtonUntoggled {
get;
set;
}
= "1 1 1 0.4";
[JsonProperty(PropertyName = "XP Bar")]
public string XPBar {
get;
set;
}
= "0.5 1 0.5 1";
[JsonProperty(PropertyName = "Text")]
public string Text {
get;
set;
}
= "1 1 1 0.4";
}
public class SFXConfig {
[JsonProperty(PropertyName = "Item Crafted Normal")]
public string ItemCraftedNormal {
get;
set;
}
= "assets/bundled/prefabs/fx/notice/loot.start.fx.prefab";
[JsonProperty(PropertyName = "Item Crafted Rare")]
public string ItemCraftedRare {
get;
set;
}
= "assets/prefabs/deployable/research table/effects/research-success.prefab";
[JsonProperty(PropertyName = "Item Duplicated")]
public string ItemDuplicated {
get;
set;
}
= "assets/bundled/prefabs/fx/item_unlock.prefab";
[JsonProperty(PropertyName = "Skill Level Up")]
public string SkillLevelUp {
get;
set;
}
= "assets/prefabs/locks/keypad/effects/lock.code.updated.prefab";
}
protected override void LoadConfig() {
base.LoadConfig();
var recommended = "It is recommended to backup your current configuration file and remove it to generate a fresh one.";
var usingDefault = "Overriding configuration with default values to avoid errors.";
try {
config = Config.ReadObject<Configuration>();
if (config == null) {
throw new Exception();
}
if (config.Version.Major <= 0) {
config.Version = new VersionNumber(Version.Major, Version.Minor, Version.Patch);
}
else if (config.Version.Major > 0 && config.Version.Major != Version.Major || config.Version.Minor != Version.Minor) throw new NotSupportedException();
SaveConfig();
}
catch (NotSupportedException) {
PrintError($"Your configuration file is out of date.Your configuration file is for v{config.Version.Major}.{config.Version.Minor}.{config.Version.Patch} but the plugin is on v{Version.Major}.{Version.Minor}.{Version.Patch}.{recommended}");
PrintWarning(usingDefault);
LoadDefaultConfig();
}
catch(Exception) {
PrintError($"Your configuration file contains an error.{recommended}");
PrintWarning(usingDefault);
LoadDefaultConfig();
}
//PrintError($"DEFAULT CONFIG LOADED REMOVE!!!!");
//LoadDefaultConfig(); // TODO Comment this out
}
protected override void SaveConfig() => Config.WriteObject(config);
protected override void LoadDefaultConfig() => config = new Configuration();
}
}
namespace Oxide.Plugins {
partial class QualityCrafting : CovalencePlugin {
object OnItemAction(Item bp, string action, BasePlayer basePlayer) {
if (basePlayer != null && bp != null && bp.IsBlueprint() && action == "study" && basePlayer.blueprints != null && config.Settings.BlueprintXPGain && basePlayer.blueprints.HasUnlocked(bp.blueprintTargetDef)) {
bp.UseItem(1);
var item = ItemManager.Create(bp.blueprintTargetDef);
var category = SkillCategory.GetByItemDefinition(item.info);
var skills = CraftingManager.GetSkills(basePlayer);
int oldItemLevel = skills.GetLevel(item);
int catLevel = skills.GetLevel(category);
float catXp = skills.GetLevelPercent(category);
float oldItemXp = skills.GetLevelPercent(item);
uint xp = QualityItemManager.GetItemXpRate(item);
skills = skills.GrantXP(item, xp);
int newItemLevel = skills.GetLevel(item);
float newItemXp = skills.GetLevelPercent(item);
NotificationManager.AddNotifications(basePlayer, new GainedXPNotification {
Icon = item.info.shortname, SkillDisplayName = item.info.displayName.translated, OldLevel = oldItemLevel, NewLevel = newItemLevel, OldXP = oldItemXp, NewXP = newItemXp, IsLevelUp = newItemLevel > oldItemLevel, XPGained = xp
}
);
}
return null;
}
object OnItemCraft(ItemCraftTask task, BasePlayer basePlayer, Item item) {
if (task != null && task.blueprint != null && task.blueprint.targetItem != null && basePlayer != null) {
var category = SkillCategory.GetByItemDefinition(task.blueprint.targetItem);
if (category != null) {
var skills = CraftingManager.GetSkills(basePlayer);
if (skills != null) {
var baseSpeed = category.GetBaseCraftingSpeed();
task.blueprint = UnityEngine.Object.Instantiate(task.blueprint);
var speed = skills.GetCraftingSpeedMultiplier(category) * baseSpeed;
task.blueprint.time *= (1f / speed);
}
}
}
return null;
}
void OnItemCraftFinished(ItemCraftTask task, Item item) {
BasePlayer basePlayer = task.owner;
if (basePlayer != null && item != null) {
SkillCategory category = SkillCategory.GetByItem(item);
if (category != null) {
var skills = CraftingManager.GetSkills(basePlayer);
var duplicate = skills.GetDuplicateChance(category) >= UnityEngine.Random.Range(0, 100);
int quality = CraftingManager.GetCraftedItemQuality(item, skills);
int oldCatLevel = skills.GetLevel(category);
int oldItemLevel = skills.GetLevel(item);
float oldCatXp = skills.GetLevelPercent(category);
float oldItemXp = skills.GetLevelPercent(item);
var itemXpRate = QualityItemManager.GetItemXpRate(item);
var dupeRate = duplicate ? 2f : 1f;
var xpMult = category.GetXpMultiplier();
var itemXpGained = (uint) ((10 + (quality * 2)) * dupeRate * xpMult);
var catXpGained = (uint) (itemXpRate * dupeRate * xpMult);
skills = skills.GrantXP(category, catXpGained);
ShowTrackingHud(basePlayer);
skills = skills.GrantXP(item, itemXpGained);
int newCatLevel = skills.GetLevel(category);
int newItemLevel = skills.GetLevel(item);
float newCatXp = skills.GetLevelPercent(category);
float newItemXp = skills.GetLevelPercent(item);
QualityItemManager.SetItemQuality(item, quality, basePlayer);
QualityItemManager.ApplyQualityModifiers(item, quality);
string qualityColor = QualityItemManager.GetColorByQuality(quality);
bool isRare = QualityItemManager.IsRareQuality(quality, oldItemLevel);
if (duplicate) {
var newItem = ItemManager.CreateByItemID(item.info.itemid);
QualityItemManager.SetItemQuality(newItem, quality, basePlayer);
QualityItemManager.ApplyQualityModifiers(newItem, quality);
basePlayer.GiveItem(newItem);
}
bool catLevelUp = newCatLevel > oldCatLevel;
bool itemLevelUp = newItemLevel > oldItemLevel;
NotificationManager.AddNotifications(basePlayer, new ItemCraftedNotification {
IsItem = true, Icon = item.info.shortname, SkillDisplayName = item.info.displayName.translated, OldCategoryLevel = oldCatLevel, NewCategoryLevel = newCatLevel, OldItemLevel = oldItemLevel, NewItemLevel = newItemLevel, OldCategoryXP = oldCatXp, NewCategoryXP = newCatXp, OldItemXP = oldItemXp, NewItemXP = newItemXp, IsCategoryLevelup = catLevelUp, IsItemLevelup = itemLevelUp, CategoryXPGained = catXpGained, ItemXPGained = itemXpGained, Quality = quality, Category = category.Name, IsRare = isRare, IsDuplicated = duplicate
}
);
}
}
}
}
}
namespace Oxide.Plugins {
partial class QualityCrafting : CovalencePlugin {
[Command("qc.help")]
private void Cmdhelp(IPlayer player, string command, string[] args) {
var check = new SecurityCheck(args);
if (!check.Success) {
return;
}
else {
args = check.Args;
}
var basePlayer = player.Object as BasePlayer;
bool autoHide = bool.Parse(args[0]);
ShowHelpMenu(basePlayer, autoHide, 0);
}
[Command("qc.help.tab")]
private void CmdHelpTab(IPlayer player, string command, string[] args) {
var check = new SecurityCheck(args);
if (!check.Success) {
return;
}
else {
args = check.Args;
}
if (args.Length != 2) {
return;
}
var basePlayer = player.Object as BasePlayer;
bool autoHide = bool.Parse(args[0]);
var index = int.Parse(args[1]);
ShowHelpMenu(basePlayer, autoHide, index);
}
private void DestroyHelpMenu(BasePlayer basePlayer) {
CuiHelper.DestroyUi(basePlayer, HELP_MENU_OVERLAY);
CuiHelper.DestroyUi(basePlayer, HELP_MENU);
}
private void ShowHelpMenu(BasePlayer basePlayer, bool autoHide = true, int index = 0) {
var container = new CuiElementContainer();
int width = 800;
int height = 500;
int padding = 10;
int closeButtonSize = 15;
// Overlay
var overlay = new CuiElement {
Parent = "Overlay", Name = HELP_MENU_OVERLAY, Components = {
new CuiButtonComponent {
Command = $"qc.menu.close {Secret}", Color = "0 0 0 0.9", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat"
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1"
}
}
}
;
if (!autoHide) {
overlay.Components.Add(new CuiNeedsCursorComponent());
}
container.Add(overlay);
// Base
container.Add(new CuiElement {
Parent = "Overlay", Name = HELP_MENU, Components = {
new CuiImageComponent {
Color = config.Colors.MenuBackground, Material = "assets/scenes/test/waterlevelterrain/watertexture.png",
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = $"{-width/2} {-height/2}", OffsetMax = $"{width/2} {height/2}"
}
}
}
);
// Close Button
#region CloseBtn
container.Add(new CuiElement {
Parent = HELP_MENU, Name = $"{HELP_MENU}.close", Components = {
new CuiButtonComponent {
Command = $"qc.menu.close {Secret}", Color = "0 0 0 1"
}
, new CuiRectTransformComponent {
AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = $"{-padding - closeButtonSize} {-padding - closeButtonSize}", OffsetMax = $"{-padding} {-padding}"
}
}
}
);
container.Add(new CuiElement {
Parent = $"{HELP_MENU}.close", Components = {
new CuiImageComponent {
Png = ImageLibrary?.Call<string>("GetImage", $"qc.close"), Color = config.Colors.Text
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = $"{3} {3}", OffsetMax = $"{-3} {-3}"
}
}
}
);
#endregion
#region Return Button
container.Add(new CuiElement {
Parent = HELP_MENU, Name = $"{HELP_MENU}.return", Components = {
new CuiButtonComponent {
Command = $"qc.menu.show {Secret} {autoHide}", Color = "0 0 0 1"
}
, new CuiRectTransformComponent {
AnchorMin = "1 1", AnchorMax = "1 1
// ... [Code preview truncated due to length. Full source in attached file] ...