SickGaming Rust Server Plugins
This commit is contained in:
519
plugins/QuickSmelt.cs
Normal file
519
plugins/QuickSmelt.cs
Normal file
@@ -0,0 +1,519 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace Oxide.Plugins
|
||||
{
|
||||
[Info("Quick Smelt", "Iv Misticos", "5.1.3")]
|
||||
[Description("Increases the speed of the furnace smelting")]
|
||||
class QuickSmelt : RustPlugin
|
||||
{
|
||||
#region Variables
|
||||
|
||||
private static QuickSmelt _instance;
|
||||
|
||||
private const string PermissionUse = "quicksmelt.use";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Configuration
|
||||
|
||||
private static Configuration _config;
|
||||
|
||||
private class Configuration
|
||||
{
|
||||
[JsonProperty(PropertyName = "Use Permission")]
|
||||
public bool UsePermission = true;
|
||||
|
||||
[JsonProperty(PropertyName = "Speed Multipliers", ObjectCreationHandling = ObjectCreationHandling.Replace)]
|
||||
public Dictionary<string, float> SpeedMultipliers = new Dictionary<string, float>
|
||||
{
|
||||
{"global", 1.0f},
|
||||
{"furnace.shortname", 1.0f}
|
||||
};
|
||||
|
||||
[JsonProperty(PropertyName = "Fuel Usage Speed Multipliers",
|
||||
ObjectCreationHandling = ObjectCreationHandling.Replace)]
|
||||
public Dictionary<string, float> FuelSpeedMultipliers = new Dictionary<string, float>
|
||||
{
|
||||
{"global", 1.0f},
|
||||
{"furnace.shortname", 1.0f}
|
||||
};
|
||||
|
||||
[JsonProperty(PropertyName = "Fuel Usage Multipliers",
|
||||
ObjectCreationHandling = ObjectCreationHandling.Replace)]
|
||||
public Dictionary<string, int> FuelUsageMultipliers = new Dictionary<string, int>
|
||||
{
|
||||
{"global", 1},
|
||||
{"furnace.shortname", 1}
|
||||
};
|
||||
|
||||
[JsonProperty(PropertyName = "Output Multipliers", ObjectCreationHandling = ObjectCreationHandling.Replace)]
|
||||
public Dictionary<string, Dictionary<string, float>> OutputMultipliers =
|
||||
new Dictionary<string, Dictionary<string, float>>
|
||||
{
|
||||
{
|
||||
"global", new Dictionary<string, float>
|
||||
{
|
||||
{"global", 1.0f}
|
||||
}
|
||||
},
|
||||
{
|
||||
"furnace.shortname", new Dictionary<string, float>
|
||||
{
|
||||
{"item.shortname", 1.0f}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[JsonProperty(PropertyName = "Whitelist", ObjectCreationHandling = ObjectCreationHandling.Replace)]
|
||||
public Dictionary<string, List<string>> Whitelist = new Dictionary<string, List<string>>
|
||||
{
|
||||
{
|
||||
"global", new List<string>
|
||||
{
|
||||
"item.shortname"
|
||||
}
|
||||
},
|
||||
{
|
||||
"furnace.shortname", new List<string>
|
||||
{
|
||||
"item.shortname"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[JsonProperty(PropertyName = "Blacklist", ObjectCreationHandling = ObjectCreationHandling.Replace)]
|
||||
public Dictionary<string, List<string>> Blacklist = new Dictionary<string, List<string>>
|
||||
{
|
||||
{
|
||||
"global", new List<string>
|
||||
{
|
||||
"item.shortname"
|
||||
}
|
||||
},
|
||||
{
|
||||
"furnace.shortname", new List<string>
|
||||
{
|
||||
"item.shortname"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[JsonProperty(PropertyName = "Smelting Frequencies (Smelt items every N smelting ticks)",
|
||||
ObjectCreationHandling = ObjectCreationHandling.Replace)]
|
||||
public Dictionary<string, int> SmeltingFrequencies = new Dictionary<string, int>
|
||||
{
|
||||
{"global", 1},
|
||||
{"furnace.shortname", 1}
|
||||
};
|
||||
|
||||
[JsonProperty(PropertyName = "Debug")]
|
||||
public bool Debug = false;
|
||||
}
|
||||
|
||||
protected override void LoadConfig()
|
||||
{
|
||||
base.LoadConfig();
|
||||
try
|
||||
{
|
||||
_config = Config.ReadObject<Configuration>();
|
||||
if (_config == null) throw new Exception();
|
||||
}
|
||||
catch
|
||||
{
|
||||
PrintError("Your configuration file contains an error. Using default configuration values.");
|
||||
LoadDefaultConfig();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadDefaultConfig() => _config = new Configuration();
|
||||
|
||||
protected override void SaveConfig() => Config.WriteObject(_config);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Hooks
|
||||
|
||||
private void Unload()
|
||||
{
|
||||
var ovens = UnityEngine.Object.FindObjectsOfType<BaseOven>();
|
||||
PrintDebug($"Processing BaseOven(s).. Amount: {ovens.Length}.");
|
||||
|
||||
for (var i = 0; i < ovens.Length; i++)
|
||||
{
|
||||
var oven = ovens[i];
|
||||
var component = oven.GetComponent<FurnaceController>();
|
||||
|
||||
if (oven.IsOn())
|
||||
{
|
||||
PrintDebug("Oven is on. Restarted cooking");
|
||||
component.StopCooking();
|
||||
oven.StartCooking();
|
||||
}
|
||||
|
||||
UnityEngine.Object.Destroy(component);
|
||||
}
|
||||
|
||||
PrintDebug("Done.");
|
||||
}
|
||||
|
||||
private void OnServerInitialized()
|
||||
{
|
||||
_instance = this;
|
||||
permission.RegisterPermission(PermissionUse, this);
|
||||
|
||||
var ovens = UnityEngine.Object.FindObjectsOfType<BaseOven>();
|
||||
PrintDebug($"Processing BaseOven(s).. Amount: {ovens.Length}.");
|
||||
|
||||
for (var i = 0; i < ovens.Length; i++)
|
||||
{
|
||||
var oven = ovens[i];
|
||||
|
||||
OnEntitySpawned(oven);
|
||||
}
|
||||
|
||||
timer.Once(1f, () =>
|
||||
{
|
||||
for (var i = 0; i < ovens.Length; i++)
|
||||
{
|
||||
var oven = ovens[i];
|
||||
var component = oven.gameObject.GetComponent<FurnaceController>();
|
||||
|
||||
if (oven == null || oven.IsDestroyed || !oven.IsOn() || !CanUse(oven.OwnerID))
|
||||
continue;
|
||||
|
||||
component.StartCooking();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void OnEntitySpawned(BaseNetworkable entity)
|
||||
{
|
||||
var oven = entity as BaseOven;
|
||||
if (oven == null)
|
||||
return;
|
||||
|
||||
oven.gameObject.AddComponent<FurnaceController>();
|
||||
}
|
||||
|
||||
private object OnOvenToggle(StorageContainer oven, BasePlayer player)
|
||||
{
|
||||
if (oven is BaseFuelLightSource || oven.needsBuildingPrivilegeToUse && !player.CanBuild())
|
||||
return null;
|
||||
|
||||
PrintDebug("OnOvenToggle called");
|
||||
var component = oven.gameObject.GetComponent<FurnaceController>();
|
||||
var canUse = CanUse(oven.OwnerID) || CanUse(player.userID);
|
||||
if (oven.IsOn())
|
||||
{
|
||||
component.StopCooking();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (canUse)
|
||||
component.StartCooking();
|
||||
else
|
||||
{
|
||||
PrintDebug($"No permission ({player.userID})");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
|
||||
private bool CanUse(ulong id) =>
|
||||
!_config.UsePermission || permission.UserHasPermission(id.ToString(), PermissionUse);
|
||||
|
||||
private static void PrintDebug(string message)
|
||||
{
|
||||
if (_config.Debug)
|
||||
Debug.Log($"DEBUG ({_instance.Name}) > " + message);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Controller
|
||||
|
||||
public class FurnaceController : FacepunchBehaviour
|
||||
{
|
||||
private int _ticks;
|
||||
|
||||
private BaseOven _oven;
|
||||
|
||||
private BaseOven Furnace
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_oven == null)
|
||||
_oven = GetComponent<BaseOven>();
|
||||
|
||||
return _oven;
|
||||
}
|
||||
}
|
||||
|
||||
private float _speedMultiplier;
|
||||
|
||||
private float _fuelSpeedMultiplier;
|
||||
|
||||
private int _fuelUsageMultiplier;
|
||||
|
||||
private int _smeltingFrequency;
|
||||
|
||||
private Dictionary<string, float> _outputModifiers;
|
||||
|
||||
private float OutputMultiplier(string shortname)
|
||||
{
|
||||
float modifier;
|
||||
if (_outputModifiers == null || !_outputModifiers.TryGetValue(shortname, out modifier) &&
|
||||
!_outputModifiers.TryGetValue("global", out modifier))
|
||||
modifier = 1.0f;
|
||||
|
||||
PrintDebug($"{shortname} modifier: {modifier}");
|
||||
return modifier;
|
||||
}
|
||||
|
||||
private List<string> _blacklist;
|
||||
private List<string> _whitelist;
|
||||
|
||||
private bool? IsAllowed(string shortname)
|
||||
{
|
||||
if (_blacklist != null && _blacklist.Contains(shortname))
|
||||
return false;
|
||||
|
||||
if (_whitelist != null && _whitelist.Contains(shortname))
|
||||
return true;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Well, sorry for my complicated code. But that should work faster! :)
|
||||
|
||||
float modifierF; // float modifier
|
||||
int modifierI; // int modifier
|
||||
|
||||
if (!_config.SpeedMultipliers.TryGetValue(Furnace.ShortPrefabName, out modifierF) &&
|
||||
!_config.SpeedMultipliers.TryGetValue("global", out modifierF))
|
||||
modifierF = 1.0f;
|
||||
|
||||
_speedMultiplier = 0.5f / modifierF;
|
||||
|
||||
if (!_config.FuelSpeedMultipliers.TryGetValue(Furnace.ShortPrefabName, out modifierF) &&
|
||||
!_config.FuelSpeedMultipliers.TryGetValue("global", out modifierF))
|
||||
modifierF = 1.0f;
|
||||
|
||||
_fuelSpeedMultiplier = modifierF;
|
||||
|
||||
if (!_config.FuelUsageMultipliers.TryGetValue(Furnace.ShortPrefabName, out modifierI) &&
|
||||
!_config.FuelUsageMultipliers.TryGetValue("global", out modifierI))
|
||||
modifierI = 1;
|
||||
|
||||
_fuelUsageMultiplier = modifierI;
|
||||
|
||||
if (!_config.SmeltingFrequencies.TryGetValue(Furnace.ShortPrefabName, out modifierI) &&
|
||||
!_config.SmeltingFrequencies.TryGetValue("global", out modifierI))
|
||||
modifierI = 1;
|
||||
|
||||
_smeltingFrequency = modifierI;
|
||||
|
||||
if (!_config.OutputMultipliers.TryGetValue(Furnace.ShortPrefabName, out _outputModifiers) && !_config.OutputMultipliers.TryGetValue("global", out _outputModifiers))
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if ((!_config.Blacklist.TryGetValue(Furnace.ShortPrefabName, out _blacklist) &&
|
||||
!_config.Blacklist.TryGetValue("global", out _blacklist)) &
|
||||
(!_config.Whitelist.TryGetValue(Furnace.ShortPrefabName, out _whitelist) &&
|
||||
!_config.Whitelist.TryGetValue("global", out _whitelist)))
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private Item FindBurnable()
|
||||
{
|
||||
if (Furnace.inventory == null)
|
||||
return null;
|
||||
|
||||
foreach (var item in Furnace.inventory.itemList)
|
||||
{
|
||||
var component = item.info.GetComponent<ItemModBurnable>();
|
||||
if (component && (Furnace.fuelType == null || item.info == Furnace.fuelType))
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Cook()
|
||||
{
|
||||
var item = FindBurnable();
|
||||
if (item == null)
|
||||
{
|
||||
StopCooking();
|
||||
return;
|
||||
}
|
||||
|
||||
SmeltItems();
|
||||
var slot = Furnace.GetSlot(BaseEntity.Slot.FireMod);
|
||||
if (slot)
|
||||
{
|
||||
slot.SendMessage("Cook", 0.5f, SendMessageOptions.DontRequireReceiver);
|
||||
}
|
||||
|
||||
var component = item.info.GetComponent<ItemModBurnable>();
|
||||
item.fuel -= 0.5f * (Furnace.cookingTemperature / 200f) * _fuelSpeedMultiplier;
|
||||
if (!item.HasFlag(global::Item.Flag.OnFire))
|
||||
{
|
||||
item.SetFlag(global::Item.Flag.OnFire, true);
|
||||
item.MarkDirty();
|
||||
}
|
||||
|
||||
if (item.fuel <= 0f)
|
||||
{
|
||||
ConsumeFuel(item, component);
|
||||
}
|
||||
|
||||
_ticks++;
|
||||
}
|
||||
|
||||
private void ConsumeFuel(Item fuel, ItemModBurnable burnable)
|
||||
{
|
||||
if (Furnace.allowByproductCreation && burnable.byproductItem != null && Random.Range(0f, 1f) > burnable.byproductChance)
|
||||
{
|
||||
var def = burnable.byproductItem;
|
||||
var item = ItemManager.Create(def, (int) (burnable.byproductAmount * OutputMultiplier(def.shortname))); // It's fuel multiplier
|
||||
if (!item.MoveToContainer(Furnace.inventory))
|
||||
{
|
||||
StopCooking();
|
||||
item.Drop(Furnace.inventory.dropPosition, Furnace.inventory.dropVelocity);
|
||||
}
|
||||
}
|
||||
|
||||
if (fuel.amount <= 1)
|
||||
{
|
||||
fuel.Remove();
|
||||
return;
|
||||
}
|
||||
|
||||
fuel.amount -= _fuelUsageMultiplier;
|
||||
fuel.fuel = burnable.fuelAmount;
|
||||
fuel.MarkDirty();
|
||||
}
|
||||
|
||||
private void SmeltItems()
|
||||
{
|
||||
if (_ticks % _smeltingFrequency != 0)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < Furnace.inventory.itemList.Count; i++)
|
||||
{
|
||||
// Getting item and checking if it's valid
|
||||
var item = Furnace.inventory.itemList[i];
|
||||
if (item == null || !item.IsValid())
|
||||
continue;
|
||||
|
||||
// Getting cookable
|
||||
var cookable = item.info.GetComponent<ItemModCookable>();
|
||||
if (cookable == null)
|
||||
continue;
|
||||
|
||||
// Checking if item's cooking is allowed
|
||||
var isAllowed = IsAllowed(item.info.shortname);
|
||||
if (isAllowed != null && !isAllowed.Value) // Allowed is false? Okay, no problem. Don't cook this item
|
||||
continue;
|
||||
|
||||
// What about temperature?
|
||||
// This lets us deny cooking, for example, meat in furnaces
|
||||
var temperature = item.temperature;
|
||||
if ((temperature < cookable.lowTemp || temperature > cookable.highTemp) && isAllowed == null) // Not allowed, not denied? That's our case! Because if it's allowed, this function won't be executed :P
|
||||
{
|
||||
if (!cookable.setCookingFlag || !item.HasFlag(global::Item.Flag.Cooking)) continue;
|
||||
item.SetFlag(global::Item.Flag.Cooking, false);
|
||||
item.MarkDirty();
|
||||
continue;
|
||||
}
|
||||
|
||||
// So, so.. what about items' cooking speed (time)?
|
||||
if (cookable.cookTime > 0 && _ticks * 1f / _smeltingFrequency % cookable.cookTime > 0)
|
||||
continue;
|
||||
|
||||
// Setting cooking flag
|
||||
if (cookable.setCookingFlag && !item.HasFlag(global::Item.Flag.Cooking))
|
||||
{
|
||||
item.SetFlag(global::Item.Flag.Cooking, true);
|
||||
item.MarkDirty();
|
||||
}
|
||||
|
||||
// Changing amount
|
||||
var position = item.position;
|
||||
if (item.amount > 1)
|
||||
{
|
||||
item.amount--;
|
||||
item.MarkDirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Remove();
|
||||
}
|
||||
|
||||
// What if nothing is produced?
|
||||
if (cookable.becomeOnCooked == null) continue;
|
||||
|
||||
// Let's create an item!
|
||||
var item2 = ItemManager.Create(cookable.becomeOnCooked,
|
||||
(int) (cookable.amountOfBecome * OutputMultiplier(cookable.becomeOnCooked.shortname))); // It's an another one output multiplier, but not for fuel
|
||||
|
||||
// Some checks
|
||||
if (item2 == null || item2.MoveToContainer(item.parent, position) ||
|
||||
item2.MoveToContainer(item.parent))
|
||||
continue;
|
||||
|
||||
// Dropping item and stopping cooking if oven is full
|
||||
item2.Drop(item.parent.dropPosition, item.parent.dropVelocity);
|
||||
if (!item.parent.entityOwner) continue;
|
||||
StopCooking();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartCooking()
|
||||
{
|
||||
if (FindBurnable() == null)
|
||||
{
|
||||
PrintDebug("No burnable.");
|
||||
return;
|
||||
}
|
||||
|
||||
StopCooking();
|
||||
|
||||
PrintDebug("Starting cooking..");
|
||||
Furnace.inventory.temperature = Furnace.cookingTemperature;
|
||||
Furnace.UpdateAttachmentTemperature();
|
||||
|
||||
PrintDebug($"Speed Multiplier: {_speedMultiplier}");
|
||||
Furnace.InvokeRepeating(Cook, _speedMultiplier, _speedMultiplier);
|
||||
Furnace.SetFlag(BaseEntity.Flags.On, true);
|
||||
}
|
||||
|
||||
public void StopCooking()
|
||||
{
|
||||
PrintDebug("Stopping cooking..");
|
||||
Furnace.CancelInvoke(Cook);
|
||||
Furnace.StopCooking();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user