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

FREE FHorseNpcVendor : 1.0.0 1.0.0

Нет прав для скачивания
C#:
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("FHorseNpcVendor", "fufeldev", "1.0.0")]
    public class FHorseNpcVendor : RustPlugin
    {
        private const string PermAdmin = "fhorsenpcvendor.admin";
        private const string NpcPrefab = "assets/prefabs/npc/bandit/shopkeepers/stables_shopkeeper.prefab";
        private const string MachinePrefab = "assets/prefabs/deployable/vendingmachine/npcvendingmachines/shopkeeper_vm_invis.prefab";
        private const string MachinePrefabAlt = "Assets/Prefabs/Deployable/VendingMachine/NPCVendingMachines/Shopkeeper_VM_Invis.prefab";
        private const int StartingStock = 100;
        private StoredData _data;
        private NPCShopKeeper _npc;
        private InvisibleVendingMachine _machine;

        private class StoredData
        {
            public PositionData Spawn;
        }

        private class PositionData
        {
            public float X;
            public float Y;
            public float Z;
            public float RotY;
        }

        private void Init()
        {
            permission.RegisterPermission(PermAdmin, this);
            LoadData();
        }

        private void OnServerInitialized()
        {
            SpawnNpc();
        }

        private void Unload()
        {
            KillNpc();
        }

        private void OnVendingShopOpen(VendingMachine vending, BasePlayer player)
        {
        }

        private void OnVendingTransaction(VendingMachine vending, BasePlayer buyer, int sellOrderId, int numberOfTransactions, ItemContainer targetContainer)
        {
        }

        private object OnBuyVendingItem(VendingMachine vending, BasePlayer player, int sellOrderId, int numberOfTransactions)
        {
            if (!IsOurMachine(vending) || player == null) return null;
            var realSellOrderId = GetRealSellOrderId(_machine, sellOrderId);
            if (realSellOrderId < 0) return true;
            _machine.DoTransaction(player, realSellOrderId, numberOfTransactions, player.inventory.containerMain);
            Restock(_machine);
            return true;
        }

        private object OnTakeCurrencyItem(VendingMachine vending, Item takenCurrencyItem)
        {
            if (!IsOurMachine(vending) || takenCurrencyItem == null) return null;
            takenCurrencyItem.Remove();
            return true;
        }

        [ChatCommand("horsenpc")]
        private void CmdHorseNpc(BasePlayer player, string command, string[] args)
        {
            if (player == null || !player.IsAdmin && !permission.UserHasPermission(player.UserIDString, PermAdmin)) return;
            if (args.Length == 0)
            {
                SendReply(player, "/horsenpc set - поставить продавца\n/horsenpc remove - удалить продавца\n/horsenpc respawn - переспавнить продавца");
                return;
            }
            if (args[0] == "set")
            {
                _data.Spawn = new PositionData
                {
                    X = player.transform.position.x,
                    Y = player.transform.position.y,
                    Z = player.transform.position.z,
                    RotY = player.eyes.rotation.eulerAngles.y
                };
                SaveData();
                SpawnNpc();
                SendReply(player, "Продавец Ranch поставлен.");
                return;
            }
            if (args[0] == "remove")
            {
                _data.Spawn = null;
                SaveData();
                KillNpc();
                SendReply(player, "Продавец Ranch удалён.");
                return;
            }
            if (args[0] == "respawn")
            {
                SpawnNpc();
                SendReply(player, "Продавец Ranch переспавнен.");
            }
        }

        private void SpawnNpc()
        {
            KillNpc();
            if (_data.Spawn == null) return;
            var position = new Vector3(_data.Spawn.X, _data.Spawn.Y, _data.Spawn.Z);
            var rotation = Quaternion.Euler(0f, _data.Spawn.RotY, 0f);
            _machine = GameManager.server.CreateEntity(MachinePrefab, position, rotation) as InvisibleVendingMachine;
            if (_machine == null) _machine = GameManager.server.CreateEntity(MachinePrefabAlt, position, rotation) as InvisibleVendingMachine;
            if (_machine == null)
            {
                PrintError("Не удалось создать Shopkeeper_VM_Invis.prefab");
                return;
            }
            _machine.enableSaving = false;
            _machine.StartingStock = StartingStock;
            _machine.RefillTime = 1f;
            _machine.BypassDynamicPricing = true;
            _machine.Spawn();
            _npc = GameManager.server.CreateEntity(NpcPrefab, position, rotation) as NPCShopKeeper;
            if (_npc == null)
            {
                PrintError("Не удалось создать stables_shopkeeper.prefab");
                KillNpc();
                return;
            }
            _npc.enableSaving = false;
            _npc.Spawn();
            _npc.transform.rotation = rotation;
            _npc.EndSleeping();
            _npc.SetAimDirection(rotation * Vector3.forward);
            _npc.SendNetworkUpdateImmediate();
            _npc.machine = _machine;
            _npc.invisibleVendingMachineRef.Set(_machine);
            _machine.SetAttachedNPC(_npc);
            timer.Once(1.2f, () => InstallRanchShop(_machine));
        }

        private void InstallRanchShop(InvisibleVendingMachine machine)
        {
            if (machine == null || machine.IsDestroyed) return;
            machine.StartingStock = StartingStock;
            machine.RefillTime = 1f;
            machine.BypassDynamicPricing = true;
            if (machine.sellOrders == null || machine.sellOrders.sellOrders == null) machine.InstallDefaultSellOrders();
            machine.CancelInvoke(machine.InstallFromVendingOrders);
            machine.CancelInvoke(machine.Refill);
            machine.ClearSellOrders();
            machine.inventory.Clear();
            machine.inventory.capacity = 300;
            ItemManager.DoRemoves();
            AddOrder(machine, "horse.saddle.single", 1, 150);
            AddOrder(machine, "horse.shoes.basic", 1, 100);
            AddOrder(machine, "horse.shoes.advanced", 1, 250);
            machine.RefreshSellOrderStockLevel();
            machine.SendSellOrders();
            machine.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
        }

        private void Restock(InvisibleVendingMachine machine)
        {
            if (machine == null || machine.IsDestroyed) return;
            machine.transactionActive = true;
            EnsureItem(machine, "horse.saddle.single", StartingStock);
            EnsureItem(machine, "horse.shoes.basic", StartingStock);
            EnsureItem(machine, "horse.shoes.advanced", StartingStock);
            machine.transactionActive = false;
            machine.RefreshSellOrderStockLevel();
            machine.SendSellOrders();
            machine.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
        }

        private void EnsureItem(InvisibleVendingMachine machine, string shortName, int stockMultiplier)
        {
            var def = ItemManager.FindItemDefinition(shortName);
            if (def == null) return;
            int target = stockMultiplier;
            int current = 0;
            if (machine.inventory != null)
            {
                for (int i = 0; i < machine.inventory.itemList.Count; i++)
                {
                    var item = machine.inventory.itemList[i];
                    if (item != null && item.info == def) current += item.amount;
                }
            }
            if (current >= target) return;
            int toAdd = target - current;
            machine.inventory.AddItem(def, toAdd, 0UL, ItemContainer.LimitStack.All);
        }

        private void AddOrder(InvisibleVendingMachine machine, string shortName, int amount, int price)
        {
            var sellDefinition = ItemManager.FindItemDefinition(shortName);
            var scrapDefinition = ItemManager.FindItemDefinition("scrap");
            if (sellDefinition == null || scrapDefinition == null)
            {
                PrintWarning($"Не найден предмет для продажи: {shortName}");
                return;
            }
            var order = new ProtoBuf.VendingMachine.SellOrder();
            order.ShouldPool = false;
            order.itemToSellID = sellDefinition.itemid;
            order.itemToSellAmount = amount;
            order.currencyID = scrapDefinition.itemid;
            order.currencyAmountPerItem = price;
            order.currencyIsBP = false;
            order.itemToSellIsBP = false;
            order.priceMultiplier = 1f;
            order.receivedQuantityMultiplier = 1f;
            machine.sellOrders.sellOrders.Add(order);
            machine.transactionActive = true;
            machine.inventory.AddItem(sellDefinition, amount * StartingStock, 0UL, ItemContainer.LimitStack.All);
            machine.transactionActive = false;
        }

        private bool IsOurMachine(VendingMachine vending)
        {
            return _machine != null && vending != null && vending.EqualNetID(_machine);
        }

        private int GetRealSellOrderId(VendingMachine vending, int visibleSellOrderId)
        {
            if (vending == null || vending.sellOrders == null || vending.sellOrders.sellOrders == null) return -1;
            var visibleIndex = 0;
            for (int i = 0; i < vending.sellOrders.sellOrders.Count; i++)
            {
                var sellOrder = vending.sellOrders.sellOrders[i];
                var itemDefinition = ItemManager.FindItemDefinition(sellOrder.itemToSellID);
                var currencyDefinition = ItemManager.FindItemDefinition(sellOrder.currencyID);
                if (itemDefinition == null || currencyDefinition == null) continue;
                if (!itemDefinition.IsAllowed(vending.CurrentEraRestriction) || !currencyDefinition.IsAllowed(vending.CurrentEraRestriction)) continue;
                if (visibleIndex == visibleSellOrderId) return i;
                visibleIndex++;
            }
            return -1;
        }

        private void KillNpc()
        {
            if (_npc != null && !_npc.IsDestroyed) _npc.Kill();
            if (_machine != null && !_machine.IsDestroyed) _machine.Kill();
            _npc = null;
            _machine = null;
        }

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

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

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