C#:
namespace Oxide.Plugins;
[Info("FGatherRates", "fufeldev", "1.0.0")]
public class FGatherRates : RustPlugin {
private const int Rate = 20;
private const int AnimalRate = 13;
private const int MetalOreLimit = 10000;
private const int HqmLimit = 20;
private readonly System.Collections.Generic.Dictionary<NetworkableId, System.Collections.Generic.Dictionary<string, int>> _metalOreGathered = new System.Collections.Generic.Dictionary<NetworkableId, System.Collections.Generic.Dictionary<string, int>>();
private object OnDispenserGather(ResourceDispenser dispenser, BasePlayer player, Item item) => Multiply(dispenser, item, true);
private object OnDispenserBonus(ResourceDispenser dispenser, BasePlayer player, Item item) => Multiply(dispenser, item, false);
private void OnCollectiblePickedup(CollectibleEntity collectible, BasePlayer player, Item item) => Multiply(item);
private void OnEntityKill(ResourceEntity entity) {
if (entity?.net == null) {
return;
}
_metalOreGathered.Remove(entity.net.ID);
}
private void Multiply(Item item) {
if (item == null) {
return;
}
item.amount *= Rate;
}
private object Multiply(ResourceDispenser dispenser, Item item, bool canBlock) {
if (item == null) {
return null;
}
if (IsAnimalDispenser(dispenser) && !IsAllowedAnimalResource(item)) {
item.amount = 0;
return canBlock ? true : null;
}
item.amount *= GetRate(dispenser, item);
if (!IsMetalOreNode(dispenser)) {
return null;
}
string key = GetLimitedKey(item);
int limit = GetLimit(key);
if (limit <= 0) {
return null;
}
BaseEntity entity = dispenser.baseEntity;
if (entity == null || entity.net == null) {
return null;
}
System.Collections.Generic.Dictionary<string, int> gathered;
if (!_metalOreGathered.TryGetValue(entity.net.ID, out gathered)) {
gathered = new System.Collections.Generic.Dictionary<string, int>();
_metalOreGathered[entity.net.ID] = gathered;
}
int current;
gathered.TryGetValue(key, out current);
int left = limit - current;
if (left <= 0) {
item.amount = 0;
return canBlock ? true : null;
}
if (item.amount > left) {
item.amount = left;
}
gathered[key] = current + item.amount;
return null;
}
private bool IsMetalOreNode(ResourceDispenser dispenser) {
BaseEntity entity = dispenser == null ? null : dispenser.baseEntity;
if (entity == null) {
return false;
}
string prefab = entity.PrefabName;
if (!string.IsNullOrEmpty(prefab) && prefab.ToLowerInvariant().Contains("/metal-ore.prefab")) {
return true;
}
string shortPrefab = entity.ShortPrefabName;
return !string.IsNullOrEmpty(shortPrefab) && shortPrefab.ToLowerInvariant() == "metal-ore";
}
private int GetRate(ResourceDispenser dispenser, Item item) {
return IsAnimalDispenser(dispenser) && IsAllowedAnimalResource(item) ? AnimalRate : Rate;
}
private bool IsAnimalDispenser(ResourceDispenser dispenser) {
BaseEntity entity = dispenser == null ? null : dispenser.baseEntity;
if (entity == null) return false;
if (entity is BaseCorpse) return true;
string prefab = entity.PrefabName;
if (!string.IsNullOrEmpty(prefab) && prefab.ToLowerInvariant().Contains("corpse")) return true;
string shortPrefab = entity.ShortPrefabName;
return !string.IsNullOrEmpty(shortPrefab) && shortPrefab.ToLowerInvariant().Contains("corpse");
}
private bool IsAllowedAnimalResource(Item item) {
string shortname = item?.info?.shortname;
if (string.IsNullOrEmpty(shortname)) return false;
return shortname == "cloth" || shortname == "fat.animal" || shortname == "leather";
}
private string GetLimitedKey(Item item) {
if (item?.info == null) {
return string.Empty;
}
if (item.info.shortname == "metal.ore") {
return "metal.ore";
}
if (item.info.shortname == "metal.refined" || item.info.shortname == "hq.metal.ore") {
return "hqm";
}
return string.Empty;
}
private int GetLimit(string key) {
if (key == "metal.ore") {
return MetalOreLimit;
}
if (key == "hqm") {
return HqmLimit;
}
return 0;
}
}