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

FREE SpawnVehicles : 2.0.0 2.0.0

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("SpawnVehicles", "spunK", "2.0.0")]
    [Description("Allow players to spawn vehicles via chat commands with payment system integration.")]
    public class SpawnVehicles : CovalencePlugin
    {
        #region Fields

        [PluginReference]
        private Plugin Economics, ServerRewards;

        private ConfigData _config;
        private Dictionary<ulong, Dictionary<string, DateTime>> _cooldowns = new Dictionary<ulong, Dictionary<string, DateTime>>();

        #endregion

        #region Configuration

        private class ConfigData
        {
            [JsonProperty("Require Building Privilege")]
            public bool RequireBuildingPrivilege { get; set; } = true;

            [JsonProperty("Check for Building Blocked")]
            public bool CheckBuildingBlocked { get; set; } = true;

            [JsonProperty("Default Payment Type (none, scrap, economics, serverrewards)")]
            public string DefaultPaymentType { get; set; } = "scrap";

            [JsonProperty("Spawn Distance From Player")]
            public float SpawnDistance { get; set; } = 3f;

            [JsonProperty("Spawn Height Offset")]
            public float SpawnHeightOffset { get; set; } = 0.5f;

            [JsonProperty("Vehicles")]
            public Dictionary<string, VehicleConfig> Vehicles { get; set; } = new Dictionary<string, VehicleConfig>
            {
                ["bike"] = new VehicleConfig
                {
                    DisplayName = "Motorbike",
                    EntityPrefab = "assets/content/vehicles/bikes/motorbike.prefab",
                    SpawnWithFuel = false,
                    FuelAmount = 0,
                    Cooldown = 120f,
                    Costs = new Dictionary<string, int>
                    {
                        ["scrap"] = 50,
                        ["economics"] = 250,
                        ["serverrewards"] = 125
                    }
                },
                ["mini"] = new VehicleConfig
                {
                    DisplayName = "Minicopter",
                    EntityPrefab = "assets/content/vehicles/minicopter/minicopter.entity.prefab",
                    SpawnWithFuel = true,
                    FuelAmount = 100,
                    Cooldown = 600f,
                    Costs = new Dictionary<string, int>
                    {
                        ["scrap"] = 500,
                        ["economics"] = 2500,
                        ["serverrewards"] = 1250
                    }
                },
                ["scrappy"] = new VehicleConfig
                {
                    DisplayName = "Scrap Transport Helicopter",
                    EntityPrefab = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab",
                    SpawnWithFuel = true,
                    FuelAmount = 100,
                    Cooldown = 600f,
                    Costs = new Dictionary<string, int>
                    {
                        ["scrap"] = 750,
                        ["economics"] = 3750,
                        ["serverrewards"] = 1875
                    }
                },
                ["attackheli"] = new VehicleConfig 
                {
                    DisplayName = "Attack Helicopter",
                    EntityPrefab = "assets/content/vehicles/attackhelicopter/attackhelicopter.entity.prefab",
                    SpawnWithFuel = true,
                    FuelAmount = 100,
                    Cooldown = 900f,
                    Costs = new Dictionary<string, int>
                    {
                        ["scrap"] = 2250,
                        ["economics"] = 5000,
                        ["serverrewards"] = 2500
                    }
                },
                ["rhib"] = new VehicleConfig
                {
                    DisplayName = "RHIB",
                    EntityPrefab = "assets/content/vehicles/boats/rhib/rhib.prefab",
                    SpawnWithFuel = true,
                    FuelAmount = 50,
                    Cooldown = 300f,
                    Costs = new Dictionary<string, int>
                    {
                        ["scrap"] = 300,
                        ["economics"] = 1000,
                        ["serverrewards"] = 500
                    }
                },
                ["boat"] = new VehicleConfig
                {
                    DisplayName = "Rowboat",
                    EntityPrefab = "assets/content/vehicles/boats/rowboat/rowboat.prefab",
                    SpawnWithFuel = true,
                    FuelAmount = 50,
                    Cooldown = 180f,
                    Costs = new Dictionary<string, int>
                    {
                        ["scrap"] = 125,
                        ["economics"] = 500,
                        ["serverrewards"] = 250
                    }
                },
                ["snowmobile"] = new VehicleConfig
                {
                    DisplayName = "Snowmobile",
                    EntityPrefab = "assets/content/vehicles/snowmobiles/snowmobile.prefab",
                    SpawnWithFuel = true,
                    FuelAmount = 50,
                    Cooldown = 240f,
                    Costs = new Dictionary<string, int>
                    {
                        ["scrap"] = 150,
                        ["economics"] = 750,
                        ["serverrewards"] = 375
                    }
                },
                ["horse"] = new VehicleConfig
                {
                    DisplayName = "Horse",
                    EntityPrefab = "assets/content/vehicles/horse/ridablehorse.prefab",
                    Cooldown = 180f,
                    Costs = new Dictionary<string, int>
                    {
                        ["scrap"] = 75,
                        ["economics"] = 375,
                        ["serverrewards"] = 188
                    }
                }
            };

            public string ToJson() => JsonConvert.SerializeObject(this);
            public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
        }

        private class VehicleConfig
        {
            [JsonProperty("Display Name")]
            public string DisplayName { get; set; }

            [JsonProperty("Entity Prefab")]
            public string EntityPrefab { get; set; }

            [JsonProperty("Spawn With Fuel")]
            public bool SpawnWithFuel { get; set; } = true;

            [JsonProperty("Fuel Amount")]
            public int FuelAmount { get; set; } = 100;

            [JsonProperty("Cooldown (seconds)")]
            public float Cooldown { get; set; } = 300f;

            [JsonProperty("Costs (payment type:  amount)")]
            public Dictionary<string, int> Costs { get; set; } = new Dictionary<string, int>();
        }

        protected override void LoadDefaultConfig() => _config = new ConfigData();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<ConfigData>();
                if (_config == null)
                {
                    throw new JsonException();
                }

                if (!_config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys))
                {
                    LogWarning("Configuration appears to be outdated; updating and saving");
                    SaveConfig();
                }
            }
            catch (Exception ex)
            {
                LogWarning($"Configuration file {Name}.json is invalid; using defaults. Error: {ex.Message}");
                LoadDefaultConfig();
            }
        }

        protected override void SaveConfig()
        {
            Log($"Configuration changes saved to {Name}.json");
            Config.WriteObject(_config, true);
        }

        #endregion

        #region Localization

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["NoPermission"] = "You do not have permission to use this command.",
                ["NoPermissionVehicle"] = "You do not have permission to spawn a {0}.",
                ["SpawnedVehicle"] = "You have spawned a {0}.",
                ["NeedBuildingPrivilege"] = "You need building privilege to spawn vehicles here.",
                ["BuildingBlocked"] = "You cannot spawn vehicles in a building blocked area.",
                ["VehicleNotFound"] = "Vehicle '{0}' not found in configuration.",
                ["FailedToSpawn"] = "Failed to spawn {0}.  Please try again.",
                ["OnCooldown"] = "You must wait <color=yellow>{0}</color> seconds before spawning another {1}.",
                ["InsufficientFunds"] = "You need <color=yellow>{0}</color> {1} to spawn a {2}.",
                ["PaymentDeducted"] = "You paid {0} {1} to spawn a {2}.",
                ["InvalidPaymentType"] = "Invalid payment type '{0}'. Valid types:  none, scrap, economics, serverrewards",
                ["PluginNotLoaded"] = "The {0} plugin is not loaded. Payment type has been set to 'none'.",
                ["VehicleList"] = "Available vehicles:\n{0}",
                ["VehicleListItem"] = "- /{0} - {1} ({2})",
                ["Free"] = "Free"
            }, this);
        }

        private string Lang(string key, string id = null, params object[] args)
        {
            return string.Format(lang.GetMessage(key, this, id), args);
        }

        #endregion

        #region Hooks

        private void Init()
        {
            permission.RegisterPermission("spawnvehicles.free", this);
            permission.RegisterPermission("spawnvehicles.nocooldown", this);

            foreach (var vehicleKey in _config.Vehicles.Keys)
            {
                permission.RegisterPermission($"spawnvehicles.{vehicleKey}", this);
            }

            AddCovalenceCommand("vehicles", nameof(CmdVehicleList));
            
            foreach (var vehicleKey in _config.Vehicles.Keys)
            {
                AddCovalenceCommand(vehicleKey, nameof(CmdSpawnVehicle));
            }
        }

        private void Unload()
        {
            _cooldowns.Clear();
        }

        #endregion

        #region Commands

        private void CmdVehicleList(IPlayer player, string command, string[] args)
        {
            var vehicleList = _config.Vehicles
                .Select(v =>
                {
                    var cost = GetCostString(v.Value, player.Id);
                    return Lang("VehicleListItem", player.Id, v.Key, v.Value.DisplayName, cost);
                });

            player.Reply(Lang("VehicleList", player.Id, string.Join("\n", vehicleList)));
        }

        private void CmdSpawnVehicle(IPlayer player, string command, string[] args)
        {
            var vehicleKey = command.TrimStart('/');

            if (!_config.Vehicles.TryGetValue(vehicleKey, out var vehicleConfig))
            {
                ShowNotify(player, Lang("VehicleNotFound", player.Id, vehicleKey));
                return;
            }

            if (!HasPermission(player, $"spawnvehicles.{vehicleKey}"))
            {
                ShowNotify(player, Lang("NoPermissionVehicle", player.Id, vehicleConfig.DisplayName));
                return;
            }

            var basePlayer = player.Object as BasePlayer;
            if (basePlayer == null)
            {
                return;
            }

            // Check building privilege
            if (_config.RequireBuildingPrivilege && !basePlayer.IsBuildingAuthed() && !basePlayer.HasPrivilegeFromOther())
            {
                ShowNotify(player, Lang("NeedBuildingPrivilege", player.Id));
                return;
            }

            // Check building blocked
            if (_config.CheckBuildingBlocked && !basePlayer.CanBuild())
            {
                ShowNotify(player, Lang("BuildingBlocked", player.Id));
                return;
            }

            // Check cooldown
            if (!HasPermission(player, "spawnvehicles.nocooldown"))
            {
                if (IsOnCooldown(basePlayer.userID, vehicleKey, out var remainingTime))
                {
                    ShowNotify(player, Lang("OnCooldown", player.Id, Math.Ceiling(remainingTime), vehicleConfig.DisplayName));
                    return;
                }
            }

            // Handle payment
            if (!HasPermission(player, "spawnvehicles.free"))
            {
                if (!TryTakePayment(basePlayer, vehicleConfig, out var paymentMessage))
                {
                    ShowNotify(player, paymentMessage);
                    return;
                }
            }

            // Spawn vehicle
            if (!SpawnVehicle(basePlayer, vehicleKey, vehicleConfig))
            {
                ShowNotify(player, Lang("FailedToSpawn", player.Id, vehicleConfig.DisplayName));
                return;
            }

            // Set cooldown
            if (!HasPermission(player, "spawnvehicles.nocooldown"))
            {
                SetCooldown(basePlayer.userID, vehicleKey, vehicleConfig.Cooldown);
            }

            ShowNotify(player, Lang("SpawnedVehicle", player.Id, vehicleConfig.DisplayName));
        }

        #endregion

        #region Core Methods

        private bool SpawnVehicle(BasePlayer player, string vehicleKey, VehicleConfig vehicleConfig)
        {
            var spawnPosition = player.transform.position + player.transform.forward * _config.SpawnDistance;
            spawnPosition.y += _config.SpawnHeightOffset;

            var rotation = Quaternion.Euler(0, player.transform.rotation.eulerAngles.y, 0);
            var entity = GameManager.server.CreateEntity(vehicleConfig.EntityPrefab, spawnPosition, rotation);

            if (entity == null)
            {
                return false;
            }

            entity.OwnerID = player.userID;
            entity.Spawn();

            if (vehicleConfig.SpawnWithFuel && vehicleConfig.FuelAmount > 0)
            {
                var vehicle = entity as BaseVehicle;
                if (vehicle != null)
                {
                    IFuelSystem fuelSystem = vehicle.GetFuelSystem();
                    if (fuelSystem != null) fuelSystem.AddFuel(vehicleConfig.FuelAmount);
                }
            }

            return true;
        }

        private bool TryTakePayment(BasePlayer player, VehicleConfig vehicleConfig, out string message)
        {
            message = string.Empty;
            var paymentType = _config.DefaultPaymentType.ToLower();

            if (!vehicleConfig.Costs.TryGetValue(paymentType, out var cost))
            {
                return true;
            }

            if (cost <= 0)
            {
                return true;
            }

            switch (paymentType)
            {
                case "none":
                    return true;

                case "scrap":
                    var scrapAmount = player.inventory.GetAmount(-932201673);
                    if (scrapAmount < cost)
                    {
                        message = Lang("InsufficientFunds", player.UserIDString, cost, "scrap", vehicleConfig.DisplayName);
                        return false;
                    }
                    player.inventory.Take(null, -932201673, cost);
                    return true;

                case "economics": 
                    if (Economics == null)
                    {
                        message = Lang("PluginNotLoaded", player.UserIDString, "Economics");
                        return true;
                    }
                    var balance = Economics.Call<double>("Balance", player.userID);
                    if (balance < cost)
                    {
                        message = Lang("InsufficientFunds", player.UserIDString, cost, "coins", vehicleConfig.DisplayName);
                        return false;
                    }
                    Economics.Call("Withdraw", player.userID, (double)cost);
                    return true;

                case "serverrewards":
                    if (ServerRewards == null)
                    {
                        message = Lang("PluginNotLoaded", player.UserIDString, "ServerRewards");
                        return true;
                    }
                    var points = ServerRewards.Call<int>("CheckPoints", player.userID);
                    if (points < cost)
                    {
                        message = Lang("InsufficientFunds", player.UserIDString, cost, "RP", vehicleConfig.DisplayName);
                        return false;
                    }
                    ServerRewards.Call("TakePoints", player.userID, cost);
                    return true;

                default:
                    message = Lang("InvalidPaymentType", player.UserIDString, paymentType);
                    return false;
            }
        }

        private string GetCostString(VehicleConfig vehicleConfig, string playerId)
        {
            var paymentType = _config.DefaultPaymentType.ToLower();

            if (!vehicleConfig.Costs.TryGetValue(paymentType, out var cost) || cost <= 0 || paymentType == "none")
            {
                return Lang("Free", playerId);
            }

            var currencyName = paymentType switch
            {
                "scrap" => "scrap",
                "economics" => "coins",
                "serverrewards" => "RP",
                _ => paymentType
            };

            return $"{cost} {currencyName}";
        }

        private void ShowNotify(IPlayer player, string message)
        {
            var basePlayer = player.Object as BasePlayer;
            if (basePlayer == null)
            {
                return;
            }

            basePlayer.ShowToast(GameTip.Styles.Server_Event, message);
        }

        #endregion

        #region Cooldown Management

        private bool IsOnCooldown(ulong userId, string vehicleKey, out double remainingTime)
        {
            remainingTime = 0;

            if (!_cooldowns.ContainsKey(userId))
            {
                return false;
            }

            if (!_cooldowns[userId].ContainsKey(vehicleKey))
            {
                return false;
            }

            var cooldownEnd = _cooldowns[userId][vehicleKey];
            if (DateTime.UtcNow >= cooldownEnd)
            {
                _cooldowns[userId].Remove(vehicleKey);
                return false;
            }

            remainingTime = (cooldownEnd - DateTime.UtcNow).TotalSeconds;
            return true;
        }

        private void SetCooldown(ulong userId, string vehicleKey, float cooldownSeconds)
        {
            if (!_cooldowns.ContainsKey(userId))
            {
                _cooldowns[userId] = new Dictionary<string, DateTime>();
            }

            _cooldowns[userId][vehicleKey] = DateTime.UtcNow.AddSeconds(cooldownSeconds);
        }

        #endregion

        #region Helpers

        private bool HasPermission(IPlayer player, string perm)
        {
            return permission.UserHasPermission(player.Id, perm);
        }

        #endregion
    }
}

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