Иконка ресурса

FREE KillAwards : 1.4.0 1.4.0

Нет прав для скачивания
C#:
/*
 * Copyright (C) 2024 Game4Freak.io
 * This mod is provided under the Game4Freak EULA.
 * Full legal terms can be found at https://game4freak.io/eula/
 */

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Plugins;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Kill Awards", "VisEntities", "1.4.0")]
    [Description("Reward players with items, kits, XP, and more for reaching kill milestones.")]
    public class KillAwards : RustPlugin
    {
        #region 3rd Party Dependencies

        [PluginReference]
        private readonly Plugin Kits, Economics, ServerRewards, XPerience, SkillTree;

        #endregion 3rd Party Dependencies

        #region Fields

        private static KillAwards _plugin;
        private static Configuration _config;
        private StoredData _storedData;

        #endregion Fields

        #region Configuration

        private class Configuration
        {
            [JsonProperty("Version")]
            public string Version { get; set; }

            [JsonProperty("Count NPC Kills Towards Milestones")]
            public bool CountNpcKills { get; set; }

            [JsonProperty("Count Animal Kills Towards Milestones")]
            public bool CountAnimalKills { get; set; }

            [JsonProperty("Exclude Teammate Kills From Count")]
            public bool ExcludeTeammateKills { get; set; }

            [JsonProperty("Reset Kill Count On Player Death")]
            public bool ResetKillCountOnDeath { get; set; }

            [JsonProperty("Kill Milestones")]
            public Dictionary<int, MilestoneRewardConfig> Milestones { get; set; } = new Dictionary<int, MilestoneRewardConfig>();
        }

        private class MilestoneRewardConfig
        {
            [JsonProperty("Health To Restore (0 to disable)")]
            public float HealthToRestore { get; set; }

            [JsonProperty("Refill Held Weapon Ammo")]
            public bool RefillWeaponAmmo { get; set; }

            [JsonProperty("Kit Name (requires Kits plugin, empty to disable)")]
            public string KitName { get; set; }

            [JsonProperty("Server Rewards Points (requires Server Rewards plugin, 0 to disable)")]
            public int ServerRewardsPoints { get; set; }

            [JsonProperty("Economics Money (requires Economics plugin, 0 to disable)")]
            public int EconomicsMoney { get; set; }

            [JsonProperty("XPerience XP (requires XPerience plugin, 0 to disable)")]
            public double XPerienceXp { get; set; }

            [JsonProperty("Skill Tree XP (requires Skill Tree plugin, 0 to disable)")]
            public double SkillTreeXp { get; set; }

            [JsonProperty("Personal Message (shown only to player, supports {playerName} and {killCount})")]
            public string PersonalMessage { get; set; }

            [JsonProperty("Broadcast Message (shown to all players, supports {playerName} and {killCount})")]
            public string BroadcastMessage { get; set; }

            [JsonProperty("Commands To Execute")]
            public List<CommandEntry> Commands { get; set; }
        }

        private class CommandEntry
        {
            [JsonProperty("Command Type (Chat, Server, or Client)")]
            [JsonConverter(typeof(StringEnumConverter))]
            public CommandType Type { get; set; }

            [JsonProperty("Command (supports {playerId}, {playerName}, {positionX}, {positionY}, {positionZ}, {grid})")]
            public string Command { get; set; }
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            _config = Config.ReadObject<Configuration>();

            if (string.Compare(_config.Version, Version.ToString()) < 0)
                UpdateConfig();

            SaveConfig();
        }

        protected override void LoadDefaultConfig()
        {
            _config = GetDefaultConfig();
        }

        protected override void SaveConfig()
        {
            Config.WriteObject(_config, true);
        }

        private void UpdateConfig()
        {
            PrintWarning("Config changes detected! Updating...");

            Configuration defaultConfig = GetDefaultConfig();

            if (string.Compare(_config.Version, "1.0.0") < 0)
                _config = defaultConfig;

            if (string.Compare(_config.Version, "1.1.0") < 0)
            {
                foreach (var milestone in _config.Milestones)
                {
                    milestone.Value.EconomicsMoney = 0;
                    milestone.Value.ServerRewardsPoints = 0;
                }
            }

            PrintWarning("Config update complete! Updated from version " + _config.Version + " to " + Version.ToString());
            _config.Version = Version.ToString();
        }

        private Configuration GetDefaultConfig()
        {
            return new Configuration
            {
                Version = Version.ToString(),
                CountNpcKills = false,
                CountAnimalKills = false,
                ExcludeTeammateKills = true,
                ResetKillCountOnDeath = true,
                Milestones = new Dictionary<int, MilestoneRewardConfig>
                {
                    {
                        1, new MilestoneRewardConfig
                        {
                            HealthToRestore = 10.0f,
                            RefillWeaponAmmo = false,
                            KitName = "",
                            ServerRewardsPoints = 0,
                            EconomicsMoney = 0,
                            XPerienceXp = 0,
                            SkillTreeXp = 0,
                            PersonalMessage = "You reached {killCount} kills, nice start!",
                            BroadcastMessage = "{playerName} just hit 1 kill milestone!",
                            Commands = new List<CommandEntry>()
                        }
                    },
                    {
                        2, new MilestoneRewardConfig
                        {
                            HealthToRestore = 15.0f,
                            RefillWeaponAmmo = true,
                            KitName = "",
                            ServerRewardsPoints = 0,
                            EconomicsMoney = 0,
                            XPerienceXp = 0,
                            SkillTreeXp = 0,
                            PersonalMessage = "You reached {killCount} kills! Keep it going!",
                            BroadcastMessage = "{playerName} is on a roll with {killCount} kills!",
                            Commands = new List<CommandEntry>()
                        }
                    },
                    {
                        3, new MilestoneRewardConfig
                        {
                            HealthToRestore = 20.0f,
                            RefillWeaponAmmo = true,
                            KitName = "",
                            ServerRewardsPoints = 0,
                            EconomicsMoney = 0,
                            XPerienceXp = 0,
                            SkillTreeXp = 0,
                            PersonalMessage = "You reached {killCount} kills and earned 50 scrap!",
                            BroadcastMessage = "Watch out! {playerName} just reached {killCount} kills!",
                            Commands = new List<CommandEntry>
                            {
                               new CommandEntry
                                {
                                    Type = CommandType.Server,
                                    Command = "inventory.giveto {playerId} scrap 50"
                                }
                            }
                        }
                    }
                }
            };
        }

        #endregion Configuration

        #region Stored Data

        private class StoredData
        {
            [JsonProperty("Players")]
            public Dictionary<ulong, PlayerData> Players { get; set; } = new Dictionary<ulong, PlayerData>();
        }

        private class PlayerData
        {
            [JsonProperty("Kills")]
            public int Kills { get; set; }
        }

        private void LoadData()
        {
            _storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
            if (_storedData == null)
            {
                _storedData = new StoredData();
            }
        }

        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject(Name, _storedData);
        }

        private void ClearData()
        {
            Interface.Oxide.DataFileSystem.DeleteDataFile(Name);
        }

        #endregion Stored Data

        #region Oxide Hooks

        private void Init()
        {
            _plugin = this;
            LoadData();
        }

        private void Unload()
        {
            _config = null;
            _plugin = null;
        }

        private void OnNewSave()
        {
            ClearData();
        }

        private void OnEntityDeath(BaseEntity victim, HitInfo deathInfo)
        {
            if (victim == null || deathInfo == null)
                return;

            if (victim is BasePlayer victimPlayer && _config.ResetKillCountOnDeath)
            {
                if (_storedData.Players.TryGetValue(victimPlayer.userID, out PlayerData victimData))
                {
                    victimData.Kills = 0;
                    SaveData();
                }
            }

            BasePlayer killer = deathInfo.InitiatorPlayer;
            if (killer == null || killer == victim || !killer.userID.IsSteamId())
                return;

            if (victim is BasePlayer victimBasePlayer)
            {
                if (_config.ExcludeTeammateKills && AreTeammates(killer.userID, victimBasePlayer.userID))
                    return;

                if (victimBasePlayer.IsNpc && !_config.CountNpcKills)
                    return;
            }
            else if (victim is BaseAnimalNPC)
            {
                if (!_config.CountAnimalKills)
                    return;
            }
            else
            {
                return;
            }

            ProcessKillReward(killer);
        }

        #endregion Oxide Hooks

        #region Reward Processing

        private void ProcessKillReward(BasePlayer player)
        {
            if (!_storedData.Players.TryGetValue(player.userID, out PlayerData playerData))
            {
                playerData = new PlayerData();
                _storedData.Players[player.userID] = playerData;
            }

            playerData.Kills++;

            int maxMilestone = _config.Milestones.Keys.Max();
            if (playerData.Kills > maxMilestone)
                playerData.Kills = 0;

            if (_config.Milestones.TryGetValue(playerData.Kills, out MilestoneRewardConfig reward))
            {
                GrantHealthReward(player, reward);
                GrantAmmoRefill(player, reward);
                GrantKit(player, reward);
                GrantServerRewardsPoints(player, reward);
                GrantEconomicsMoney(player, reward);
                GrantXPerienceXp(player, reward);
                GrantSkillTreeXp(player, reward);
                ExecuteCommands(player, reward);
                SendPersonalMessage(player, reward, playerData.Kills);
                SendBroadcastMessage(player, reward, playerData.Kills);
            }

            SaveData();
        }

        private void GrantHealthReward(BasePlayer player, MilestoneRewardConfig reward)
        {
            if (reward.HealthToRestore <= 0)
                return;

            player.Heal(reward.HealthToRestore);
            SendReplyLocalized(player, Lang.Reward_HealthRestored, reward.HealthToRestore);
        }

        private void GrantAmmoRefill(BasePlayer player, MilestoneRewardConfig reward)
        {
            if (!reward.RefillWeaponAmmo)
                return;

            RefillActiveWeaponAmmo(player);
            SendReplyLocalized(player, Lang.Reward_AmmoRefilled);
        }

        private void GrantKit(BasePlayer player, MilestoneRewardConfig reward)
        {
            if (string.IsNullOrEmpty(reward.KitName))
                return;

            if (KitsUtil.GiveKit(player, reward.KitName))
            {
                SendReplyLocalized(player, Lang.Reward_KitGiven, reward.KitName);
            }
        }

        private void GrantServerRewardsPoints(BasePlayer player, MilestoneRewardConfig reward)
        {
            if (reward.ServerRewardsPoints <= 0 || !IsPluginLoaded(ServerRewards))
                return;

            ServerRewards.Call("AddPoints", player.userID, reward.ServerRewardsPoints);
            SendReplyLocalized(player, Lang.Reward_PointsAwarded, reward.ServerRewardsPoints);
        }

        private void GrantEconomicsMoney(BasePlayer player, MilestoneRewardConfig reward)
        {
            if (reward.EconomicsMoney <= 0 || !IsPluginLoaded(Economics))
                return;

            Economics.Call("Deposit", player.userID, (double)reward.EconomicsMoney);
            SendReplyLocalized(player, Lang.Reward_MoneyAwarded, reward.EconomicsMoney);
        }

        private void GrantXPerienceXp(BasePlayer player, MilestoneRewardConfig reward)
        {
            if (reward.XPerienceXp <= 0 || !IsPluginLoaded(XPerience))
                return;

            XPerienceUtil.GiveXp(player, reward.XPerienceXp);
            SendReplyLocalized(player, Lang.Reward_XPerienceXpAwarded, reward.XPerienceXp);
        }

        private void GrantSkillTreeXp(BasePlayer player, MilestoneRewardConfig reward)
        {
            if (reward.SkillTreeXp <= 0 || !IsPluginLoaded(SkillTree))
                return;

            SkillTreeUtil.AwardXp(player, reward.SkillTreeXp);
            SendReplyLocalized(player, Lang.Reward_SkillTreeXpAwarded, reward.SkillTreeXp);
        }

        private void ExecuteCommands(BasePlayer player, MilestoneRewardConfig reward)
        {
            if (reward.Commands == null)
                return;

            foreach (CommandEntry commandEntry in reward.Commands)
            {
                ExecuteCommand(player, commandEntry.Type, commandEntry.Command);
            }
        }

        private void SendPersonalMessage(BasePlayer player, MilestoneRewardConfig reward, int killCount)
        {
            if (string.IsNullOrEmpty(reward.PersonalMessage))
                return;

            string message = FormatMessage(reward.PersonalMessage, player, killCount);
            SendReplyLocalized(player, message);
        }

        private void SendBroadcastMessage(BasePlayer player, MilestoneRewardConfig reward, int killCount)
        {
            if (string.IsNullOrEmpty(reward.BroadcastMessage))
                return;

            string message = FormatMessage(reward.BroadcastMessage, player, killCount);

            foreach (BasePlayer activePlayer in BasePlayer.activePlayerList)
            {
                if (activePlayer != null)
                    SendReplyLocalized(activePlayer, message);
            }
        }

        #endregion Reward Processing

        #region Helper Functions

        private bool AreTeammates(ulong firstPlayerId, ulong secondPlayerId)
        {
            RelationshipManager.PlayerTeam team = RelationshipManager.ServerInstance.FindPlayersTeam(firstPlayerId);
            if (team != null && team.members.Contains(secondPlayerId))
            {
                return true;
            }
            return false;
        }

        private void RefillActiveWeaponAmmo(BasePlayer player)
        {
            var activeItem = player.GetActiveItem();
            if (activeItem == null)
                return;

            BaseProjectile weapon = activeItem.GetHeldEntity() as BaseProjectile;
            if (weapon == null || weapon.primaryMagazine == null)
                return;

            weapon.SetAmmoCount(weapon.primaryMagazine.capacity);
            weapon.SendNetworkUpdateImmediate();
        }

        private string FormatMessage(string text, BasePlayer player, int killCount)
        {
            return text
                .Replace("{playerName}", player.displayName)
                .Replace("{killCount}", killCount.ToString());
        }

        public static bool IsPluginLoaded(Plugin plugin)
        {
            if (plugin != null && plugin.IsLoaded)
            {
                return true;
            }
            return false;
        }

        #endregion Helper Functions

        #region 3rd Party Integration

        public static class KitsUtil
        {
            public static bool GiveKit(BasePlayer player, string kitName)
            {
                if (!IsPluginLoaded(_plugin.Kits))
                    return false;

                if (player == null || string.IsNullOrEmpty(kitName))
                    return false;

                object result = _plugin.Kits.Call("GiveKit", player, kitName);
                if (result is bool)
                {
                    return (bool)result;
                }
                return false;
            }
        }

        public static class XPerienceUtil
        {
            public static void GiveXp(BasePlayer player, double amount)
            {
                if (!IsPluginLoaded(_plugin.XPerience))
                    return;

                if (player == null || amount <= 0)
                    return;

                _plugin.XPerience.Call("GiveXP", player, amount);
            }
        }

        public static class SkillTreeUtil
        {
            public static void AwardXp(BasePlayer player, double xpAmount)
            {
                if (!IsPluginLoaded(_plugin.SkillTree))
                    return;

                if (player == null || xpAmount <= 0)
                    return;

                _plugin.SkillTree.Call("AwardXP", player.userID.Get(), xpAmount, "KillAwards", false);
            }
        }

        #endregion 3rd Party Integration

        #region Command Execution

        private enum CommandType
        {
            Chat,
            Server,
            Client
        }

        private void ExecuteCommand(BasePlayer player, CommandType type, string command)
        {
            string formattedCommand = command
                .Replace("{playerId}", player.UserIDString)
                .Replace("{playerName}", player.displayName)
                .Replace("{positionX}", player.transform.position.x.ToString())
                .Replace("{positionY}", player.transform.position.y.ToString())
                .Replace("{positionZ}", player.transform.position.z.ToString())
                .Replace("{grid}", MapHelper.PositionToString(player.transform.position));

            switch (type)
            {
                case CommandType.Chat:
                    player.Command(string.Format("chat.say \"{0}\"", formattedCommand));
                    break;
                case CommandType.Client:
                    player.Command(formattedCommand);
                    break;
                case CommandType.Server:
                    Server.Command(formattedCommand);
                    break;
            }
        }

        #endregion Command Execution

        #region Localization

        private static class Lang
        {
            public const string Reward_HealthRestored = "Reward.HealthRestored";
            public const string Reward_AmmoRefilled = "Reward.AmmoRefilled";
            public const string Reward_KitGiven = "Reward.KitGiven";
            public const string Reward_PointsAwarded = "Reward.PointsAwarded";
            public const string Reward_MoneyAwarded = "Reward.MoneyAwarded";
            public const string Reward_XPerienceXpAwarded = "Reward.XPerienceXpAwarded";
            public const string Reward_SkillTreeXpAwarded = "Reward.SkillTreeXpAwarded";
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                [Lang.Reward_HealthRestored] = "You have been healed for <color=#90EE90>{0}</color> health!",
                [Lang.Reward_AmmoRefilled] = "Your weapon ammo has been fully refilled!",
                [Lang.Reward_KitGiven] = "You have received the <color=#87CEEB>{0}</color> kit!",
                [Lang.Reward_PointsAwarded] = "You have been awarded <color=#FFD700>{0}</color> Server Rewards points!",
                [Lang.Reward_MoneyAwarded] = "You have been awarded <color=#FFD700>{0}</color> money!",
                [Lang.Reward_XPerienceXpAwarded] = "You have been awarded <color=#DDA0DD>{0}</color> XPerience XP!",
                [Lang.Reward_SkillTreeXpAwarded] = "You have been awarded <color=#DDA0DD>{0}</color> SkillTree XP!",
            }, this, "en");
        }

        private static string GetMessage(BasePlayer player, string messageKey, params object[] args)
        {
            string userId;
            if (player != null)
                userId = player.UserIDString;
            else
                userId = null;

            string message = _plugin.lang.GetMessage(messageKey, _plugin, userId);

            if (args.Length > 0)
                message = string.Format(message, args);

            return message;
        }

        public static void SendReplyLocalized(BasePlayer player, string messageKey, params object[] args)
        {
            string message = GetMessage(player, messageKey, args);

            if (!string.IsNullOrWhiteSpace(message))
                _plugin.SendReply(player, message);
        }

        #endregion Localization
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху