using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Oxide.Plugins
{
[Info("NPC Kill Counter", "Kingfoo55", "1.0.0")]
[Description("Counts NPC Kills and adds players to an oxide group once a threshold is reached.")]
public class NPCKillCounter : RustPlugin
{
#region Declaration
static NPCKillCounter ins;
static Dictionary<ulong, PVEStatsData> Cachedplayerstats = new Dictionary<ulong, PVEStatsData>();
public bool UseScientists;
public bool UseHeavy;
public bool UseMurderer;
public bool UseScarecrow;
#endregion
#region Config & Localisation
protected override void LoadDefaultConfig()
{
Config["Count Scientists"] = UseScientists = true;
Config["Count Heavy Scientists"] = UseHeavy = true;
Config["Count Murderers"] = UseMurderer = true;
Config["Count Scarecrow"] = UseScarecrow = true;
Config["first scientist threshhold"] = 50;
Config["first heavy scientist threshhold"] = 50;
Config["first murderer threshhold"] = 50;
Config["first scarecrow threshhold"] = 50;
Config["second scientist threshhold"] = 100;
Config["second heavy scientist threshhold"] = 100;
Config["second murderer threshhold"] = 100;
Config["second scarecrow threshhold"] = 100;
Config["first scientist threshold oxide group"] = "group1scientist";
Config["first heavy scientist threshold oxide group"] = "group1heavy";
Config["first murderer threshold oxide group"] = "group1murderer";
Config["first scarecrow threshold oxide group"] = "group1scarecrow";
Config["second scientist threshold oxide group"] = "group2scientist";
Config["second heavy scientist threshold oxide group"] = "group2heavy";
Config["second murderer threshold oxide group"] = "group2murderer";
Config["second scarecrow threshold oxide group"] = "group2scarecrow";
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["StatsMessage"] = "<color=#55aaff>Your PVE Statistics</color> : <color=#55aaff>{0}</color> Scientist Kills, <color=#55aaff>{1}</color> Heavy Scientist Kills, <color=#55aaff>{2}</color> Murderer Kills, <color=#55aaff>{3}</color> Scarecrow Kills",
["ResetStats"] = "{0} Players PVE Statistics were Reset!",
["ClearStats"] = "{0} PVE Statistics have been cleared",
["NotFound"] = "{0} Not Found!",
}, this);
}
#endregion
#region Hooks
private void OnServerInitialized()
{
ins = this;
foreach (BasePlayer player in BasePlayer.activePlayerList) OnPlayerInit(player);
}
private void OnPlayerInit(BasePlayer player) => PVEStatsData.TryLoad(player.userID);
void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
{
BasePlayer killer = info?.Initiator as BasePlayer;
if (entity == null | info == null) return;
if (killer == null || killer == entity) return;
if (entity.ShortPrefabName == "heavyscientist")
{
if ((bool)Config["Count Heavy Scientists"] == true)
if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].heavyKills++;
}
if (entity.ShortPrefabName == "scientist")
{
if ((bool)Config["Count Scientists"] == true)
if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].scientistkills++;
}
if (entity.ShortPrefabName == "murderer")
{
if((bool)Config["Count Murderers"] == true)
if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].murdererkills++;
}
if (entity.ShortPrefabName == "scarecrow")
{
if((bool)Config["Count Scarecrow"] == true)
if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].scarecrowkills++;
}
foreach (var data in Cachedplayerstats) data.Value.Save(data.Key);
CheckPlayerKills(killer);
return;
}
private void OnServerShutDown() => Unload();
private void Unload()
{
foreach (var data in Cachedplayerstats) data.Value.Save(data.Key);
}
#endregion
#region Commands
[ConsoleCommand("stats.reset")]
private void WipeStatsCmd(ConsoleSystem.Arg arg)
{
if (!arg.IsRcon) return;
GetAllPlayers().ForEach(ID => PVEStatsData.Reset(ID));
PrintWarning(string.Format(msg("ResetStats"), new object[] { GetAllPlayers().Count }));
}
[ConsoleCommand("stats.clear")]
private void ResetStatsCmd(ConsoleSystem.Arg arg)
{
if (!arg.IsRcon) return;
if (!arg.HasArgs()) return;
if (arg.Args.Count() != 1)
{
PrintWarning($"Usage : stats.clear <SteamID64>");
return;
}
string ID = arg.Args[0];
if (!ID.IsSteamId())
{
PrintWarning(string.Format(msg("NotFound"), new object[] { ID }));
return;
}
ulong id = Convert.ToUInt64(ID);
PrintWarning(string.Format(msg("ClearStats"), new object[] { id }));
PVEStatsData.Reset(id);
}
[ChatCommand("pvestats")]
private void cmdShowStatistics(BasePlayer player, string command, string[] args)
{
if (!Cachedplayerstats.ContainsKey(player.userID)) PVEStatsData.TryLoad(player.userID);
PlayerMsg(player, string.Format(msg("StatsMessage", player.userID), new object[] { Cachedplayerstats[player.userID].scientistkills, Cachedplayerstats[player.userID].heavyKills, Cachedplayerstats[player.userID].murdererkills, Cachedplayerstats[player.userID].scarecrowkills }));
}
#endregion
#region Methods
public List<ulong> GetAllPlayers()
{
List<ulong> PlayersID = new List<ulong>();
covalence.Players.All.ToList().ForEach(IPlayer => PlayersID.Add(ulong.Parse(IPlayer.Id)));
return PlayersID;
}
public string GetPlayer(ulong id)
{
IPlayer player = covalence.Players.FindPlayerById(id.ToString());
if (player == null) return string.Empty;
return player.Name;
}
public void PlayerMsg(BasePlayer player, string msg) => SendReply(player, msg);
public void CheckPlayerKills(BasePlayer player)
{
if (Cachedplayerstats.ContainsKey(player.userID)) if (Cachedplayerstats[player.userID].heavyKills == (int)Config["First Heavy Threshold"])
{
PrintToConsole("oxide.usergroup add",player.userID,(string)Config["First Heavy Threshold Oxide Group"]);
}
}
#endregion
#region Data Class
private class PVEStatsData
{
public int heavyKills = 0;
public int scientistkills = 0;
public int murdererkills = 0;
public int scarecrowkills = 0;
internal static void TryLoad(ulong id)
{
if (Cachedplayerstats.ContainsKey(id)) return;
PVEStatsData data = Interface.Oxide.DataFileSystem.ReadObject<PVEStatsData>($"NPCKillCounter/{id}");
if (data == null) data = new PVEStatsData();
Cachedplayerstats.Add(id, data);
}
internal static void Reset(ulong id)
{
PVEStatsData data = Interface.Oxide.DataFileSystem.ReadObject<PVEStatsData>($"NPCKillCounter/{id}");
if (data == null) return;
data = new PVEStatsData();
data.Save(id);
Cachedplayerstats[id].heavyKills = 0;
Cachedplayerstats[id].scarecrowkills = 0;
Cachedplayerstats[id].scientistkills = 0;
Cachedplayerstats[id].murdererkills = 0;
}
internal void Save(ulong id) => Interface.Oxide.DataFileSystem.WriteObject(($"NPCKillCounter/{id}"), this, true);
}
#endregion
#region Localization
public string msg(string key, ulong playerId = 0U) => lang.GetMessage(key, this, playerId != 0U ? playerId.ToString() : null);
#endregion
}
}