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

FREE DogTags : 1.0.0 1.0.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using Oxide.Core;
using Rust;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Database;
using UnityEngine;
using System.Linq;
using Newtonsoft.Json.Linq;
using Oxide.Core.Configuration;
using Steamworks;
using SpawnAddonCallback = System.Func<UnityEngine.Vector3, UnityEngine.Quaternion, Newtonsoft.Json.Linq.JObject, UnityEngine.Component>;
using KillAddonCallback = System.Action<UnityEngine.Component>;
using UpdateAddonCallback = System.Action<UnityEngine.Component, Newtonsoft.Json.Linq.JObject>;
using AddDisplayInfoCallback = System.Action<UnityEngine.Component, Newtonsoft.Json.Linq.JObject, System.Text.StringBuilder>;
using SetAddonDataCallback = System.Action<UnityEngine.Component, object>;
using static BaseEntity.RPC_Server;

namespace Oxide.Plugins
{
    [Info("DogTags", "TTV OdsScott", "1.0.0")]
    [Description("Drops a bounty tag item when a player dies")]
    public class DogTags : RustPlugin
    {
        private const string DogTagPrefab = "assets/prefabs/misc/dogtag_neutral.prefab";
        private List<BaseEntity> SpawnedEntities = new List<BaseEntity>();
        private string[] BountyHunterGuids = {};
        private Dictionary<ulong, int> playerPoints = new Dictionary<ulong, int>();
        private Dictionary<ulong, uint> playerRewards = new Dictionary<ulong, uint>();
        

        Core.SQLite.Libraries.SQLite SQLite = Interface.GetMod().GetLibrary<Core.SQLite.Libraries.SQLite>();
        Connection dbConnection;

        [PluginReference]
        private Plugin Kits = null;

        [PluginReference]
        private Plugin HonorSystem = null;

        [PluginReference]
        private Plugin MonumentAddons = null;

        [PluginReference]
        private Plugin Duelist = null;


        private void Init() { }

        SetAddonDataCallback _setAddonData;

        void OnPluginLoaded(Plugin plugin)
        {
            if (plugin == MonumentAddons)
            {
                RegisterCustomAddon();
            }
        }

        void RegisterCustomAddon()
        {
            var registeredAddon = MonumentAddons.Call(
                "API_RegisterCustomAddon",
                this,
                "bountyhunter",
                new Dictionary<string, object>
                {
                    ["Spawn"] = new SpawnAddonCallback(SpawnCustomAddon),
                    ["Kill"] = new KillAddonCallback(KillCustomAddon)
                }
            ) as Dictionary<string, object>;

            if (registeredAddon == null)
            {
                LogError($"Error registering addon with Monument Addons.");
                return;
            }

            _setAddonData = registeredAddon["SetData"] as SetAddonDataCallback;
            if (_setAddonData == null)
            {
                LogError($"SetData method not present in MonumentAddons return value.");
            }
        }

        private UnityEngine.Component SpawnCustomAddon(Vector3 position, Quaternion rotation, JObject data)
        {
            var entity = GameManager.server.CreateEntity("assets/prefabs/npc/bandit/shopkeepers/missionprovider_test.prefab", position, rotation) as NPCTalking;
            entity.EnableSaving(false);
            entity.Spawn();
            entity._displayName = "Bounty Hunter";
            entity.inventory.Strip();
            entity.inventory.containerWear.AddItem(
                ItemManager.FindItemDefinition("hazmatsuit.nomadsuit"),
                1
            );

            SpawnedEntities.Add(entity);

            return entity;
        }

        private void KillCustomAddon(UnityEngine.Component component)
        {
            var entity = component as BaseEntity;
            if (entity != null && !entity.IsDestroyed)
            {
                entity.Kill();
                SpawnedEntities.Remove(entity);
            }
        }

        bool InDuel(BasePlayer player)
        {
            if (player == null) return false;
            return Duelist?.Call<bool>("inEvent", player) ?? false;
        }

        private void OnServerInitialized()
        {
            // LoadBountyHunters();
            LoadData();
            var playersCount = BasePlayer.activePlayerList.Count;
            for (var i = 0; i < playersCount; i++)
            {
                OnPlayerInit(BasePlayer.activePlayerList[i]);
            }
            if(MonumentAddons) {
                RegisterCustomAddon();
            }
        }

        private void OnServerSave()
        {
            SaveData();
        }

        private void Unload()
        {
            SaveData();
            // DestroySpawnedEntities();
            // SQLite.CloseDb(dbConnection);
        }

        private void OnServerShutdown()
        {
            SaveData();
            // DestroySpawnedEntities();
            // SQLite.CloseDb(dbConnection);
        }

        // private void LoadBountyHunters() {
        //     BountyHunterGuids = Interface.Oxide.DataFileSystem.ReadObject<string[]>("DogTags");
        // }

        private void LoadData()
        {
            dbConnection = SQLite.OpenDb("PlayerPoints.db", this);
            SQLite.Insert(
                Core.Database.Sql.Builder.Append(
                    "CREATE TABLE IF NOT EXISTS PlayerPoints (userId TEXT PRIMARY KEY, points INTEGER)"
                ),
                dbConnection
            );

            SQLite.Query(
                Core.Database.Sql.Builder.Append("SELECT * FROM PlayerPoints"),
                dbConnection,
                query =>
                {
                    foreach (var data in query)
                    {
                        // Puts(data["userId"].ToString());
                        // Puts(data["points"].ToString());
                        var userId = ulong.Parse(data["userId"].ToString());
                        var points = int.Parse(data["points"].ToString());
                        playerPoints[userId] = points;
                    }
                }
            );
        }

        private void SaveData()
        {
            foreach (var entry in playerPoints)
            {
                var userId = entry.Key.ToString();
                var points = entry.Value.ToString();
                SQLite.Insert(
                    Core.Database.Sql.Builder.Append(
                        "UPDATE PlayerPoints SET points = @1 WHERE userId = @0",
                        userId,
                        points
                    ),
                    dbConnection,
                    rowsAffected =>
                    {
                        if (rowsAffected > 0)
                        {
                            // Puts("New record inserted with ID: {0}", dbConnection.LastInsertRowId);
                        }
                        else
                        {
                            SQLite.Insert(
                                Core.Database.Sql.Builder.Append(
                                    "INSERT OR REPLACE INTO PlayerPoints (userId, points) VALUES (@0, @1)",
                                    userId,
                                    points
                                ),
                                dbConnection
                            );
                        }
                    }
                );
            }
        }

        private void AddPoints(ulong playerId, int points, string type)
        {
            if (playerPoints.ContainsKey(playerId))
            {
                playerPoints[playerId] += points;
            }
            else
            {
                playerPoints[playerId] = points;
            }

            Puts(type);

            Interface.CallHook("OnAddBountyPoints", playerId, points, type);
        }

        private void OnPlayerInit(BasePlayer player)
        {
            AddPoints(player.userID, 0, "init");
        }

        private int GetPoints(ulong playerId) {
            if (!playerPoints.ContainsKey(playerId)) {
                return 0;
            }

            if (!playerPoints.TryGetValue(playerId, out int points)) {
                return 0;
            }

            return points;
        }

        [ChatCommand("bounty")]
        private void PointsCommand(BasePlayer player, string command, string[] args)
        {
            if (args.Length < 1)
            {
                SendReply(
                    player,
                    $"<color=#c45508>[RustWipeDay]</color>: You are currently at {GetPoints(player.userID)} bounty points."
                );
                return;
            }

            if (!player.IsAdmin)
            {
                SendReply(player, "<color=#c45508>[RustWipeDay]</color>: You don't have permission to use this command.");
                return;
            }

            if (args[0].ToLower() == "add" && args.Length == 3)
            {
                if (
                    ulong.TryParse(args[1], out ulong targetUserId)
                    && int.TryParse(args[2], out int points)
                )
                {
                    AddPoints(targetUserId, points, "admin");
                    SendReply(player, $"<color=#c45508>[RustWipeDay]</color>: Added {points} bounty points to user {targetUserId}.");
                }
                else
                {
                    SendReply(player, "<color=#c45508>[RustWipeDay]</color>: Invalid arguments.Usage: bounty add <userId> <points>");
                }
            }
            else
            {
                SendReply(player, "<color=#c45508>[RustWipeDay]</color>: Invalid command.Usage: bounty [add <userId> <points>]");
            }
        }

        private void OnPlayerDeath(BasePlayer player, HitInfo hitInfo)
        {
            var npcDropChance = NpcDropsTagChance(player);
            if (npcDropChance > 0)
            {
                int maxChanceValue = 10; // This value is used to cap the npcDropChance at 100%
                float actualChance = Mathf.Min(npcDropChance * 10, 100) / 100.0f; // Convert to decimal for percentage (e.g., 2 becomes 0.2 for 20%)
                Puts(actualChance);

                float randomValue = UnityEngine.Random.Range(0f, 1f); // Generate a random number between 0 and 1 for percentage comparison
                Puts(randomValue);
                if (randomValue <= actualChance)
                {
                    DropDogTags(player, 1, "dogtagneutral");
                }
                return;
            }

            if (hitInfo == null)
            {
                return;
            }

            var attacker = hitInfo.InitiatorPlayer;

            if (InDuel(attacker) || InDuel(player))
            {
                return;
            }

            if (player == null || 
                attacker == null ||
                (player != null && player.secondsSleeping >= 300) ||
                attacker == player ||
                (attacker != null && attacker.IsNpc) || 
                hitInfo.damageTypes.GetMajorityDamageType() == DamageType.Suicide
            )
            {
                return;
            }

            if (!playerPoints.ContainsKey(player.userID))
            {
                playerPoints[player.userID] = 0;
            }

            HandlePlayerPointsOnDeath(attacker, player);
        }

        void HandlePlayerPointsOnDeath(BasePlayer attacker, BasePlayer victim) {
            var currentPoints = playerPoints[victim.userID];

            var pointsToLose = CalculatePointsToLose(currentPoints);
    
            if (pointsToLose < 0)
            {
                return;
            }

            AddPoints(victim.userID, -1 * (int)pointsToLose, "death");
            SendReply(victim, $"<color=#c45508>[RustWipeDay]</color>: You have died and lost {pointsToLose} bounty points.");

            if ((attacker == null || attacker.IsNpc) || attacker == victim)
            {
                DropDogTags(victim, (int)pointsToLose);
                return;
            }

            double tagsToDrop = pointsToLose / 2;
            var pointsToEarn = Math.Floor(tagsToDrop);
            if (tagsToDrop < 1) {
                tagsToDrop = 1;
            }

            if (pointsToEarn > 0) {
                AddPoints(attacker.userID, (int)pointsToEarn, "kill");
                SendReply(attacker, $"<color=#c45508>[RustWipeDay]</color>: You have killed a player and gained {pointsToEarn} bounty points.");
            }
        
            DropDogTags(victim, (int)tagsToDrop);
            return;  
        }

        int NpcDropsTagChance(BasePlayer entity) {
            var isPlayer = entity is BasePlayer && !entity.IsNpc;
            
            if (isPlayer) {
                return 0;
            }

            return GetEntityHonorRank(entity) * 3;
        }
        
        int GetEntityHonorRank(BaseCombatEntity entity)
        {
            return HonorSystem.Call<int>("GetEntityHonorRank", entity);
        }

        string GetDisplayName(BaseCombatEntity entity)
        {
            return HonorSystem.Call<string>("GetDisplayName", entity);
        }

        private void DropDogTags(BasePlayer player, int amount, string type="bluedogtags") {
            var dropPosition = player.GetDropPosition();
            var dogTagItem = ItemManager.CreateByItemID(
                ItemManager.FindItemDefinition(type).itemid,
                amount
            );

            if (dogTagItem != null)
            {
                var vector3 = new Vector3(
                    UnityEngine.Random.Range(-2f, 2f),
                    0.2f,
                    UnityEngine.Random.Range(-2f, 2f)
                );
                dogTagItem.Drop(
                    dropPosition,
                    player.GetInheritedDropVelocity() + vector3.normalized * 3f
                );
            }
        }

        object OnNpcConversationStart(
            NPCTalking npcTalking,
            BasePlayer player,
            ConversationData conversationData
        )
        {
            if (!SpawnedEntities.Contains(npcTalking)) {
                return null;
            }
            ClaimDogTags(player);
            Kits.Call("OpenKitGrid", player, 0, 0, true);
            //OpenGui(player);
            return true;
        }

        [ConsoleCommand("bountyhunter.close")]
        private void BountyHunterCloseConsoleCommand(ConsoleSystem.Arg arg)
        {
            if (arg.Player() == null)
                return;

            BasePlayer player = arg.Player();
            CloseBountyHunter(player);
        }

        [ConsoleCommand("bountyhunter.reward")]
        private void ClaimReward(ConsoleSystem.Arg arg)
        {
            BasePlayer player = arg.Player();
            if (player == null || !IsPlayerInRangeOfEntities(player, SpawnedEntities, 5))
                return;

            CloseBountyHunter(player);

            ulong playerId = player.userID;

            Kits.Call("OpenKitGrid", player, 0, 0, true);
        }

        [ConsoleCommand("bountyhunter.claim")]
        private void BountyHunterClaimConsoleCommand(ConsoleSystem.Arg arg)
        {
            BasePlayer player = arg.Player();
            if (player == null || !IsPlayerInRangeOfEntities(player, SpawnedEntities, 5))
                return;

            ClaimDogTags(player);

            CloseBountyHunter(player);
        }

        private void ClaimDogTags(BasePlayer player)
        {
            var points = CountAndRemoveItemFromPlayer(player, "dogtagneutral");
            var points2 = CountAndRemoveItemFromPlayer(player, "bluedogtags");

            if (points > 0)
            {
                AddPoints(player.userID, points, "dogtagneutral");

            }


            if (points2 > 0)
            {
                AddPoints(player.userID, points2, "bluedogtags");
            }
        }

        [HookMethod("TakePoints")]
        public bool TakePoints(ulong playerId, int amount) {
            var rangeCheck = false;
            var player = BasePlayer.FindByID(playerId);
            if (player == null || (rangeCheck && !IsPlayerInRangeOfEntities(player, SpawnedEntities, 5)))
                return false;
            
            if (playerPoints.ContainsKey(playerId) && playerPoints[playerId] >= amount)
            {
                playerPoints[playerId] -= amount;
                Interface.CallHook("OnTakeBountyPoints", playerId, amount);
                return true;
            }           
            return false;
        }

        private bool IsPlayerInRangeOfEntities(
            BasePlayer player,
            List<BaseEntity> entities,
            float range
        )
        {
            if (player == null || entities == null || entities.Count == 0)
                return false;

            foreach (var entity in entities)
            {
                if (entity == null)
                    continue;

                float distance = Vector3.Distance(
                    player.transform.position,
                    entity.transform.position
                );
                if (distance <= range)
                    return true;
            }

            return false;
        }

        private bool IsPlayerInRange(BasePlayer player, BasePlayer targetPlayer, float range)
        {
            if (player == null || targetPlayer == null)
                return false;

            float distance = Vector3.Distance(
                player.transform.position,
                targetPlayer.transform.position
            );
            return distance <= range;
        }

        private int CountAndRemoveItemFromPlayer(BasePlayer player, string shortname)
        {
            int totalCount = 0;

            ItemContainer beltContainer = player.inventory.containerBelt;
            ItemContainer mainContainer = player.inventory.containerMain;

            totalCount += CountAndRemoveItemInContainer(beltContainer, shortname);
            totalCount += CountAndRemoveItemInContainer(mainContainer, shortname);

            return totalCount;
        }

        private int CountAndRemoveItemInContainer(ItemContainer container, string shortname)
        {
            int count = 0;

            foreach (Item item in container.itemList)
            {
                if (item.info.shortname == shortname)
                {
                    count += item.amount;
                    item.Remove();
                }
            }

            return count;
        }

        private int CalculatePointsToLose(int currentPoints)
        {
            if (currentPoints <= -6)
            {
                return 0;
            }
            if (currentPoints <= 0)
            {
                // If points are already 0 or below, set the minimum to -3
                return 1;
            }
            else
            {
                // Calculate points to lose based on logarithmic scale
                // Adjust the base and multiplier values as needed
                float baseValue = 2f; // Base value for the logarithm

                float logValue = Mathf.Log(currentPoints, baseValue); // Calculate the logarithm
                int pointsToLose = Mathf.RoundToInt(logValue); // Apply the multiplier and round to nearest integer
                if (pointsToLose <= 0)
                {
                    pointsToLose = 1;
                }
                return pointsToLose;
            }
        }

        private void CloseBountyHunter(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "BountyHunterOverlay");
        }

        private void OpenGui(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "BountyHunterOverlay");
            var container = new CuiElementContainer();

            // Black bar on top
            container.Add(
                new CuiPanel
                {
                    Image = { Color = "0 0 0 0" },
                    RectTransform =
                    {
                        AnchorMin = "0 0",
                        AnchorMax = "1 1",
                        OffsetMax = "0 0"
                    },
                    CursorEnabled = true
                },
                "Overlay",
                "BountyHunterOverlay"
            );

            // Black bar on top
            container.Add(
                new CuiPanel
                {
                    Image = { Color = "0 0 0 1" },
                    RectTransform =
                    {
                        AnchorMin = "0 0",
                        AnchorMax = "1 0.125",
                        OffsetMax = "0 0"
                    }
                },
                "BountyHunterOverlay",
                "TopBar"
            );

            // Black bar on bottom
            container.Add(
                new CuiPanel
                {
                    Image = { Color = "0 0 0 1" },
                    RectTransform =
                    {
                        AnchorMin = "0 0.875",
                        AnchorMax = "1 1",
                        OffsetMax = "0 0"
                    }
                },
                "BountyHunterOverlay",
                "BottomBar"
            );

            // Dialog window
            container.Add(
                new CuiPanel
                {
                    Image = { Color = "0.2 0.2 0.2 0.9" },
                    RectTransform = { AnchorMin = "0.60 0.375", AnchorMax = "0.85 0.675" }
                },
                "BountyHunterOverlay",
                "DialogWindow"
            );

            // Dialog window
            container.Add(
                new CuiPanel
                {
                    Image = { Color = "0.2 0.2 0.2 1" },
                    RectTransform = { AnchorMin = "0.05 0.85", AnchorMax = "0.4 0.95" }
                },
                "DialogWindow",
                "NameOverlay"
            );

            // Name Text
            container.Add(
                new CuiLabel
                {
                    RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                    Text =
                    {
                        Color = "0.72 0.72 0.72 1",
                        FontSize = 16,
                        Text = "Bounty Hunter",
                        Align = TextAnchor.MiddleCenter
                    }
                },
                "NameOverlay",
                "BountyHunterNpcName"
            );

            // Close button
            container.Add(
                new CuiButton
                {
                    Button =
                    {
                        Command = "bountyhunter.close",
                        Color = "0.8 0.1 0.1 1",
                        FadeIn = 0.5f
                    },
                    RectTransform = { AnchorMin = "0.90 0.90", AnchorMax = "1 1" },
                    Text = { Text = "X", Align = TextAnchor.MiddleCenter }
                },
                "DialogWindow",
                "CloseButton"
            );

            // Text overlay
            container.Add(
                new CuiPanel
                {
                    Image = { Color = "0.2 0.2 0.2 1" },
                    RectTransform = { AnchorMin = "0.05 0.40", AnchorMax = "0.95 0.80" }
                },
                "DialogWindow",
                "TextOverlay"
            );

            // Name Text
            container.Add(
                new CuiLabel
                {
                    RectTransform = { AnchorMin = "0.01 0.01", AnchorMax = "0.99 0.99" },
                    Text =
                    {
                        Color = "0.53 0.51 0.49 1",
                        FontSize = 10,
                        Text =
                            "Hey there! I am looking for Bounty Tags, do you have any? If you give me some, I will reward you with some loot.I heard you can find them near dead bodies.",
                        Align = TextAnchor.UpperLeft,
                        Font = "robotocondensed-regular.ttf"
                    }
                },
                "TextOverlay",
                "TextConversation"
            );

            // Close button
            container.Add(
                new CuiButton
                {
                    Button = { Command = "bountyhunter.close", Color = "0.8 0.1 0.1 1", },
                    RectTransform = { AnchorMin = "0.90 0.90", AnchorMax = "1 1" },
                    Text = { Text = "X", Align = TextAnchor.MiddleCenter }
                },
                "DialogWindow",
                "CloseButton"
            );

            // Claim Button
            container.Add(
                new CuiButton
                {
                    Button = { Command = "bountyhunter.claim", Color = "0.16 0.16 0.13 1", },
                    RectTransform = { AnchorMin = "0.05 0.30", AnchorMax = "0.95 0.35" },
                    Text =
                    {
                        FontSize = 10,
                        Font = "robotocondensed-regular.ttf",
                        Text = "1.Hand over the bounty tags.",
                        Align = TextAnchor.MiddleLeft
                    }
                },
                "DialogWindow",
                "ClaimButton"
            );

            // Claim Button
            container.Add(
                new CuiButton
                {
                    Button = { Command = "bountyhunter.reward", Color = "0.16 0.16 0.13 1", },
                    RectTransform = { AnchorMin = "0.05 0.20", AnchorMax = "0.95 0.25" },
                    Text =
                    {
                        FontSize = 10,
                        Font = "robotocondensed-regular.ttf",
                        Text = "2.Ask about the loot.",
                        Align = TextAnchor.MiddleLeft
                    }
                },
                "DialogWindow",
                "ClaimButton"
            );

            // Create the GUI
            CuiHelper.AddUi(player, container);
        }

        [ChatCommand("spawnbountyhunter")]
        private void SpawnNpcWithCuiCommand(BasePlayer player, string command, string[] args)
        {
            if (!player.IsAdmin)
            {
                SendReply(player, "<color=#c45508>[RustWipeDay]</color>: You must be an admin to use this command.");
                return;
            }

            SpawnNpcWithCui(player);
        }

        private void SpawnNpcWithCui(BasePlayer player)
        {
            try
            {
                var npc = GameManager.server.CreateEntity(
                        "assets/prefabs/npc/bandit/shopkeepers/missionprovider_test.prefab",
                        player.transform.position + new Vector3(3f, 0f, 0f),
                        Quaternion.identity
                    ).ToPlayer();

                if (npc != null)
                {
                    npc.Spawn();
                    npc._displayName = "Bounty Hunter";
                    npc.inventory.Strip();
                    npc.inventory.containerWear.AddItem(
                        ItemManager.FindItemDefinition("hazmatsuit.nomadsuit"),
                        1
                    );
                    npc.SendNetworkUpdateImmediate();
                    SpawnedEntities.Add(npc);
                }
            }
            catch (Exception e)
            {
                Puts(e.Message);
            }
        }

        private void DestroySpawnedEntities()
        {
            foreach (var entity in SpawnedEntities)
            {
                if (entity != null && !entity.IsDestroyed)
                    entity.Kill();
            }

            SpawnedEntities.Clear();
        }
    }
}

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