C#:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Oxide.Plugins
{
[Info("Pick Up Water Catcher", "Eraknelo", "1.0.0")]
[Description("Allows picking up water catchers by hitting it with a hammer")]
public class PickUpWaterCatcher : RustPlugin
{
private const int HitsBeforePickup = 5;
private static readonly TimeSpan HitCooldown = TimeSpan.FromSeconds(3);
private readonly Dictionary<string, DestroyableItem> _destroyableItems = new Dictionary<string, DestroyableItem>();
private readonly Dictionary<int, EntityHitData> _entityHitData = new Dictionary<int, EntityHitData>();
void Init()
{
var itemDefinitions = ItemManager.GetItemDefinitions();
RegisterDestroyableItem(itemDefinitions, "water.catcher.small");
RegisterDestroyableItem(itemDefinitions, "water.catcher.large");
Subscribe(nameof(OnHammerHit));
}
private void RegisterDestroyableItem(List<ItemDefinition> itemDefinitions, string shortName)
{
var itemDefinition = itemDefinitions.FirstOrDefault(i => i.shortname == shortName);
if (itemDefinition == null)
{
Puts($"Warning: Can't find item definition for short name {shortName}");
return;
}
var destroyableItem = new DestroyableItem
{
ShortName = shortName,
ItemId = itemDefinition.itemid,
DisplayName = itemDefinition.displayName.translated
};
_destroyableItems.Add(destroyableItem.ShortPrefabName, destroyableItem);
}
private void Unload()
{
Unsubscribe(nameof(OnHammerHit));
_destroyableItems.Clear();
_entityHitData.Clear();
}
private object OnHammerHit(BasePlayer player, HitInfo info)
{
if (!_destroyableItems.TryGetValue(info.HitEntity.ShortPrefabName, out var destroyableItem))
return null;
if (info.HitEntity.OwnerID != player.userID.Get())
return null;
var entityHash = info.HitEntity.GetHashCode();
if (!_entityHitData.TryGetValue(entityHash, out var data))
_entityHitData.Add(entityHash, data = new EntityHitData
{
LastHitTime = DateTime.Now,
HitCount = 0
});
var timeSinceLastHit = DateTime.Now - data.LastHitTime;
if (timeSinceLastHit >= HitCooldown)
data.HitCount = 0;
data.LastHitTime = DateTime.Now;
data.HitCount++;
var hitsBeforePickup = HitsBeforePickup - data.HitCount;
if (hitsBeforePickup > 0)
{
var timesPlural = hitsBeforePickup > 1 ? "times" : "time";
player.SendConsoleCommand("gametip.showtoast", 1, $"Hit {hitsBeforePickup} more {timesPlural} to pick it up.");
return false;
}
player.SendConsoleCommand("gametip.hidegametip");
_entityHitData.Remove(entityHash);
info.HitEntity.Kill(BaseNetworkable.DestroyMode.Gib);
var waterCatcherItem = ItemManager.CreateByItemID(destroyableItem.ItemId, 1);
player.GiveItem(waterCatcherItem);
CleanupHitData();
return false;
}
private void CleanupHitData()
{
var now = DateTime.Now;
_entityHitData
.Where(kv => now.Subtract(kv.Value.LastHitTime) >= HitCooldown)
.ToList()
.ForEach(kv => _entityHitData.Remove(kv.Key));
}
}
public class EntityHitData
{
public DateTime LastHitTime { get; set; }
public int HitCount { get; set; }
}
public class DestroyableItem
{
public string ShortName { get; set; }
public string ShortPrefabName => ShortName.Replace('.', '_');
public int ItemId { get; set; }
public string DisplayName { get; set; }
}
}