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

FREE CustomNpcPlugin : 0.1.0 0.1.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
#define DEBUG
using BaseAIBrain;
using BaseEntity;
using Facepunch;
using JetBrains.Annotations;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Ext.CustomNpc.Gameplay.AI;
using Oxide.Ext.CustomNpc.Gameplay.AI.States;
using Oxide.Ext.CustomNpc.Gameplay.Components;
using Oxide.Ext.CustomNpc.Gameplay.Configurations;
using Oxide.Ext.CustomNpc.Gameplay.Controllers;
using Oxide.Ext.CustomNpc.Gameplay.Controllers.NpcAttire;
using Oxide.Ext.CustomNpc.Gameplay.Data;
using Oxide.Ext.CustomNpc.Gameplay.Entities;
using Oxide.Ext.CustomNpc.Gameplay.Managers;
using Oxide.Ext.CustomNpc.Gameplay.NpcCreator;
using Oxide.Ext.CustomNpc.PluginExntesions;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AI;
//CustomNpcPlugin created with PluginMerge v(1.0.4.0) by MJSU @ https://github.com/dassjosh/Plugin.Merge
namespace Oxide.Plugins {
    [Info("CustomNpcPlugin", "Flutes", "0.1.0")]
    [Description("test")]
    public partial class CustomNpcPlugin : RustPlugin {
#region CustomNpcPlugin.cs
        private void Init() {
            new PluginsExtensionsManager();
            CustomNpc_Manager.Setup();
            Unsubscribe("OnInventoryNetworkUpdate");
        }
        private void Unload() {
            CustomNpc_Manager.DestroyAllNpcs();
        }
        private void SpawnTest(BasePlayer player) {
            CustomNpc_Configuration npcConfig = new CustomNpc_Configuration() {
                DamageScale = 1, DisableRadio = true, AgentTypeID = -1372625422, MemoryDuration = 10.0f, AreaMask = 1, AttackRangeMultiplier = 1.0f, WearItems = new List<CustomNpc_WearItem> {
                    new CustomNpc_WearItem {
                        ShortName = "attire.egg.suit", SkinId = 0
                    }
                }
                , BeltItems = new List<CustomNpc_BeltItem> {
                    new CustomNpc_BeltItem {
                        ShortName = "rifle.lr300", Amount = 1, SkinId = 0, Mods = new List<string> {
                            "weapon.mod.holosight", "weapon.mod.flashlight"
                        }
                    }
                    , new CustomNpc_BeltItem {
                        ShortName = "syringe.medical", Amount = 10, SkinId = 0, Mods = new List<string>()
                    }
                    , new CustomNpc_BeltItem {
                        ShortName = "grenade.f1", Amount = 10, SkinId = 0, Mods = new List<string>()
                    }
                    , new CustomNpc_BeltItem {
                        ShortName = "grenade.smoke", Amount = 10, SkinId = 0, Mods = new List<string>()
                    }
                    , new CustomNpc_BeltItem {
                        ShortName = "explosive.timed", Amount = 10, SkinId = 0, Mods = new List<string>()
                    }
                    , new CustomNpc_BeltItem {
                        ShortName = "rocket.launcher", Amount = 1, SkinId = 0, Mods = new List<string>()
                    }
                }
                , CanTargetOtherNpc = false, ChaseRange = 100.0f, CheckVisionCone = false, ListenRange = 10.0f, MaxHealth = 200.0f, StartHealth = 200.0f, RoamRange = 10f, Name = "Test", SenseRange = 50f, Speed = 7.5f, VisionCone = 15.0f, States = new List<string>() {
                    "DefaultIdleState", "DefaultRoamState", "DefaultChaseState", "DefaultCombatState", "DefaultHealState"
                }
            }
            ;
            NpcInstantiationFactory.InstanceNpcDefault(player.ServerPosition, npcConfig);
        }
#region Oxide Hooks
        private void OnEntityKill(CustomNpc_Component customNpc) {
            CustomNpc_Manager.OnNpcDestroyed(customNpc);
            if (NpcCreator_Manager.IsStarted) {
                NpcCreator_Manager.OnEntityKill(customNpc);
            }
            //NpcCreator_ManagerFactory.OnEntityKill(customNpc);
        }
        object OnInventoryNetworkUpdate(PlayerInventory inventory, ItemContainer container, ProtoBuf.UpdateItemContainer updateItemContainer, PlayerInventory.Type type, bool broadcast) {
            if (inventory.baseEntity == null) return null;
            if (NpcCreator_Manager.Controllers.ContainsKey(inventory.baseEntity.userID) == false) return null;
            var controller = NpcCreator_Manager.Controllers[inventory.baseEntity.userID];
            controller.CopyWearToSelectedNpc();
            return null;
        }
#endregion
        [ChatCommand("customnpc_spawn")]
        private void CustomNpcSpawnChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            SpawnTest(player);
        }
        [ChatCommand("customnpc_creator_start")]
        private void CustomNpcCreatorStartChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (args.Length == 0) return;
            string pluginName = args[0];
            var plugin = Interface.Oxide.RootPluginManager.GetPlugin(pluginName);
            if (plugin == null) {
                player.ChatMessage($"Plugin {pluginName} not found");
                return;
            }
            if (NpcCreator_Manager.IsStarted == false) Subscribe("OnInventoryNetworkUpdate");
            NpcCreator_Manager.StartCreator(player, plugin);
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_stop")]
        private void CustomNpcCreatorStopChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            NpcCreator_Manager.StopCreator(player);
            if (NpcCreator_Manager.IsStarted == false) Unsubscribe("OnInventoryNetworkUpdate");
        }
        [ChatCommand("customnpc_creator_stop_all")]
        private void CustomNpcCreatorStopAllChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            NpcCreator_Manager.Stop();
            Unsubscribe("OnInventoryNetworkUpdate");
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_edit")]
        private void CustomNpcCreatorEditChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (NpcCreator_Manager.Controllers.ContainsKey(player.userID) == false) return;
            var controller = NpcCreator_Manager.Controllers[player.userID];
            controller.InstanceNpcCommand(args);
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_select")]
        private void CustomNpcCreatorSelectChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (NpcCreator_Manager.Controllers.ContainsKey(player.userID) == false) return;
            var controller = NpcCreator_Manager.Controllers[player.userID];
            controller.SelectNpcCommand();
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_unselect")]
        private void CustomNpcCreatorUnselectChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (NpcCreator_Manager.Controllers.ContainsKey(player.userID) == false) return;
            var controller = NpcCreator_Manager.Controllers[player.userID];
            controller.UnselectNpcCommand();
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_save_all")]
        private void CustomNpcCreatorSaveAllChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (NpcCreator_Manager.Controllers.ContainsKey(player.userID) == false) return;
            var controller = NpcCreator_Manager.Controllers[player.userID];
            controller.SaveAllNpcConfig();
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_save_selected")]
        private void CustomNpcCreatorSaveSelectedChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (NpcCreator_Manager.Controllers.ContainsKey(player.userID) == false) return;
            var controller = NpcCreator_Manager.Controllers[player.userID];
            controller.SaveSelectNpcConfig();
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_reload_all")]
        private void CustomNpcCreatoReloadAllChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (NpcCreator_Manager.Controllers.ContainsKey(player.userID) == false) return;
            var controller = NpcCreator_Manager.Controllers[player.userID];
            controller.ReloadAllNpcConfig();
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_reload_selected")]
        private void CustomNpcCreatoReloadSelectedChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (NpcCreator_Manager.Controllers.ContainsKey(player.userID) == false) return;
            var controller = NpcCreator_Manager.Controllers[player.userID];
            controller.ReloadSelectedNpcConfig();
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_test_selected")]
        private void CustomNpcCreatorTestSelectedChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (NpcCreator_Manager.Controllers.ContainsKey(player.userID) == false) return;
            var controller = NpcCreator_Manager.Controllers[player.userID];
            controller.TestSelect();
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_test_all")]
        private void CustomNpcCreatorTestAllChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (NpcCreator_Manager.Controllers.ContainsKey(player.userID) == false) return;
            var controller = NpcCreator_Manager.Controllers[player.userID];
            controller.TestAll();
            player.ChatMessage($"Success");
        }
        [ChatCommand("customnpc_creator_test_stop")]
        private void CustomNpcCreatorTestEndChatCommand(BasePlayer player, string command, string[] args) {
            if (player.IsAdmin == false) return;
            if (NpcCreator_Manager.Controllers.ContainsKey(player.userID) == false) return;
            var controller = NpcCreator_Manager.Controllers[player.userID];
            controller.StopTest();
            player.ChatMessage($"Success");
        }
#endregion
#region Configuration.cs
        public class Configuration {
            private static Configuration m_current;
            public static Configuration Current => m_current != null ? m_current : Load();
            public static Configuration Load() {
                if (ConfigurationFileExist() == false) {
                    return Create();
                }
                // else Load
                return null;
            }
            private static bool ConfigurationFileExist() {
                return false;
            }
            private static Configuration Create() {
                return null;
            }
        }
#endregion
#region PluginExntesions\PluginsExtensionsManager.cs
        public class PluginsExtensionsManager : IDisposable {
            public static PluginsExtensionsManager Instance {
                get;
                private set;
            }
            public IReadOnlyDictionary<string, Plugin> LoadedPlugins => m_loadedPlugins;
            private Dictionary<string, Plugin> m_loadedPlugins = new Dictionary<string, Plugin>();
            private readonly List<string> m_neededPlugins = new List<string>() {
                "Kits"
            }
            ;
            public PluginsExtensionsManager() {
                if (Instance != null) return;
                Instance = this;
                RegisterPlugins();
                RegisterEvents();
            }
            private void RegisterEvents() {
                Interface.Oxide.RootPluginManager.OnPluginAdded += OnPluginAdded;
                Interface.Oxide.RootPluginManager.OnPluginAdded -= OnPluginRemoved;
            }
            private void UnregisterEvents() {
                Interface.Oxide.RootPluginManager.OnPluginAdded -= OnPluginAdded;
                Interface.Oxide.RootPluginManager.OnPluginAdded -= OnPluginRemoved;
            }
            private void RegisterPlugins() {
                foreach (var pluginName in m_neededPlugins) {
                    var plugin = Interface.Oxide.RootPluginManager.GetPlugin(pluginName);
                    if (plugin == null) continue;
                    m_loadedPlugins.Add(pluginName, plugin);
                }
            }
            private void OnPluginAdded(Plugin plugin) {
                if (m_neededPlugins.Contains(plugin.Name) == false) return;
                if (m_loadedPlugins.ContainsKey(plugin.Name)) return;
                m_loadedPlugins.Add(plugin.Name, plugin);
            }
            private void OnPluginRemoved(Plugin plugin) {
                if (m_neededPlugins.Contains(plugin.Name) == false) return;
                if (m_loadedPlugins.ContainsKey(plugin.Name) == false) return;
                m_loadedPlugins.Remove(plugin.Name);
            }
            private bool m_isDisposed;
            public void Dispose() {
                if (m_isDisposed) {
                    Interface.Oxide.LogWarning($"attempt to dispose already disposed {nameof(PluginsExtensionsManager)} ");
                    return;
                }
                UnregisterEvents();
                m_isDisposed = true;
            }
        }
#endregion
#region Gameplay\AI\CustomNpc_Pathfinding.cs
        public class CustomNpc_Pathfinding {
            private CustomNpc_Controller m_controller;
            private CustomNpc_Component m_component => m_controller.Component;
            public CustomNpc_Pathfinding(CustomNpc_Controller controller) {
                m_controller = controller;
            }
            public bool IsEqualsVector3(Vector3 a, Vector3 b) => Vector3.Distance(a, b) < 0.1f;
            public void SetDestination(Vector3 pos, float radius, BaseNavigator.NavigationSpeed speed) {
                Vector3 sample = GetSamplePosition(pos, radius);
                sample.y += 2f;
                if (!IsEqualsVector3(sample, m_controller.Brain.Component.Navigator.Destination)) m_controller.Brain.Component.Navigator.SetDestination(sample, speed);
            }
            public Vector3 GetSamplePosition(Vector3 source, float radius) {
                NavMeshHit navMeshHit;
                if (NavMesh.SamplePosition(source, out navMeshHit, radius, m_component.NavAgent.areaMask)) {
                    NavMeshPath path = new NavMeshPath();
                    if (NavMesh.CalculatePath(m_controller.GameObject.transform.position, navMeshHit.position, m_component.NavAgent.areaMask, path)) {
                        if (path.status == NavMeshPathStatus.PathComplete) return navMeshHit.position;
                        else return path.corners.Last();
                    }
                }
                return source;
            }
            public Vector3 GetRandomPositionAround(Vector3 source, float radius) {
                Vector2 vector2 = UnityEngine.Random.insideUnitCircle * radius;
                return source + new Vector3(vector2.x, 0f, vector2.y);
            }
        }
#endregion
#region Gameplay\Components\CustomNpcBrain_Component.cs
        public class CustomNpcBrain_Component : ScientistBrain {
            public Action onAddStates;
            public Action onInitializeAI;
            public Action<float> onThink;
            protected CustomNpcBrain_Controller m_controller;
            public virtual void Setup(CustomNpcBrain_Controller controller) {
                m_controller = controller;
            }
            public override void AddStates() {
                onAddStates?.Invoke();
            }
            public override void InitializeAI() {
                onInitializeAI?.Invoke();
            }
            public override void Think(float delta) {
                onThink?.Invoke(delta);
            }
            public void SetThinkRate(float rate) {
                thinkRate = rate;
            }
            public void SetLastThinkTime(float time) {
                lastThinkTime = time;
            }
        }
#endregion
#region Gameplay\Components\CustomNpc_Component.cs
        public class CustomNpc_Component : ScientistNPC {
            public Action onServerInstantiated;
            public Action onDestroy;
            public bool IsEquipingWeapon {
                get;
                private set;
            }
            public bool IsReloadGrenadeLauncher {
                get;
                private set;
            }
            public bool IsReloadFlameThrower {
                get;
                private set;
            }
            public bool IsHealing {
                get;
                private set;
            }
            public BaseEntity CurrentTarget {
                get;
                private set;
            }
            public AttackEntity CurrentWeapon {
                get;
                private set;
            }
            public Vector3 HomePosition {
                get;
                private set;
            }
            public void Setup(CustomNpcBrain_Component brainComponent, Vector3 homePosition) {
                HomePosition = homePosition;
                skinID = 11185464824609;
                Brain = brainComponent;
                enableSaving = false;
                gameObject.AwakeFromInstantiate();
            }
            private void OnDestroy() {
                CancelInvoke();
                onDestroy?.Invoke();
            }
            protected override string OverrideCorpseName() => displayName;
            public override void ServerInit() {
                base.ServerInit();
                onServerInstantiated?.Invoke();
            }
            public void OnEquipingWeapon(AttackEntity weapon) {
                CurrentWeapon = weapon;
                IsEquipingWeapon = true;
            }
            public void OnDesequipingWeapon() {
                CurrentWeapon = null;
            }
            public void OnFinishEquipingWeapon() {
                IsEquipingWeapon = false;
            }
            public void SetTarget(BaseEntity target) {
                CurrentTarget = target;
            }
            public void OnHeal() {
                IsHealing = true;
            }
            public void OnFinishHeal() {
                IsHealing = false;
            }
        }
#endregion
#region Gameplay\Configurations\CustomNpc_BeltItem.cs
        public class CustomNpc_BeltItem {
            public string ShortName;
            public ulong SkinId;
            public int Amount;
            public List<string> Mods = new List<string>();
            public string Ammo;
        }
#endregion
#region Gameplay\Configurations\CustomNpc_Configuration.cs
        public class CustomNpc_Configuration {
            public string Name;
            public int AreaMask;
            public int AgentTypeID;
            public float StartHealth;
            public float MaxHealth;
            public float DamageScale;
            public float AttackRangeMultiplier;
            public float Speed;
            public float MemoryDuration;
            public float SenseRange;
            public bool CheckVisionCone;
            public float ListenRange;
            public float VisionCone;
            public bool CanRunAwayWater;
            public float ChaseRange;
            public float RoamRange;
            public List<string> States = new List<string>();
            public bool DisableRadio;
            public string Kit;
            public List<CustomNpc_BeltItem> BeltItems = new List<CustomNpc_BeltItem>();
            public List<CustomNpc_WearItem> WearItems = new List<CustomNpc_WearItem>();
            public bool CanTargetOtherNpc;
            public static CustomNpc_Configuration Default() {
                CustomNpc_Configuration npcConfig = new CustomNpc_Configuration() {
                    DamageScale = 1, DisableRadio = true, AgentTypeID = -1372625422, MemoryDuration = 10.0f, AreaMask = 1, AttackRangeMultiplier = 1.0f, WearItems = new List<CustomNpc_WearItem> {
                        new CustomNpc_WearItem {
                            ShortName = "attire.egg.suit", SkinId = 0
                        }
                    }
                    , BeltItems = new List<CustomNpc_BeltItem> {
                        new CustomNpc_BeltItem {
                            ShortName = "rifle.lr300", Amount = 1, SkinId = 0, Mods = new List<string> {
                                "weapon.mod.holosight", "weapon.mod.flashlight"
                            }
                        }
                        , new CustomNpc_BeltItem {
                            ShortName = "syringe.medical", Amount = 10, SkinId = 0, Mods = new List<string>()
                        }
                        , new CustomNpc_BeltItem {
                            ShortName = "grenade.f1", Amount = 10, SkinId = 0, Mods = new List<string>()
                        }
                        , new CustomNpc_BeltItem {
                            ShortName = "grenade.smoke", Amount = 10, SkinId = 0, Mods = new List<string>()
                        }
                        , new CustomNpc_BeltItem {
                            ShortName = "explosive.timed", Amount = 10, SkinId = 0, Mods = new List<string>()
                        }
                        , new CustomNpc_BeltItem {
                            ShortName = "rocket.launcher", Amount = 1, SkinId = 0, Mods = new List<string>()
                        }
                    }
                    , CanTargetOtherNpc = false, ChaseRange = 100.0f, CheckVisionCone = false, ListenRange = 10.0f, MaxHealth = 200.0f, StartHealth = 200.0f, RoamRange = 10f, Name = "Test", SenseRange = 50f, Speed = 7.5f, VisionCone = 15.0f, States = new List<string>() {
                        "DefaultIdleState", "DefaultRoamState", "DefaultChaseState", "DefaultCombatState", "ChangeWeaponState"
                    }
                }
                ;
                return npcConfig;
            }
        }
#endregion
#region Gameplay\Configurations\CustomNpc_WearItem.cs
        public class CustomNpc_WearItem {
            public string ShortName;
            public ulong SkinId;
        }
#endregion
#region Gameplay\Controllers\CustomNpcBrain_Controller.cs
        public class CustomNpcBrain_Controller {
            public CustomNpcBrain_Component Component {
                get;
                private set;
            }
            private CustomNpc_Controller m_npc;
            public CustomNpc_Controller Npc => m_npc;
            private bool m_isInit;
            public virtual void Initialize(CustomNpc_Controller npc, CustomNpcBrain_Component component) {
                Component = component;
                m_npc = npc;
                component.Setup(this);
                Component.onAddStates += AddStates;
                Component.onInitializeAI += InitializeAI;
                Component.onThink += Think;
                m_isInit = true;
            }
            protected virtual void AddStates() {
                if (m_isInit == false) return;
                Component.states = new Dictionary<AIState, BasicAIState>();
                foreach (var stateName in m_npc.Configuration.States) {
                    CustomNpc_Manager.IStatesFactory states = null;
                    if (CustomNpc_Manager.States.TryGetValue(stateName, out states) == false) continue;
                    var state = states.Get();
                    state.Setup(m_npc);
                    Component.AddState(state);
                }
                if (Component.states.Count == 0) {
                    Interface.Oxide.LogWarning("Not state added for this npc");
                }
            }
            protected virtual void InitializeAI() {
                if (m_isInit == false) {
                    Interface.Oxide.LogError("[CustomNpc] InitializeAI brain without initialization !!");
                    return;
                }
                m_npc.Component.HasBrain = true;
                Component.Navigator = m_npc.GameObject.GetComponent<BaseNavigator>();
                Component.Navigator.Speed = m_npc.Configuration.Speed;
                Component.InvokeRandomized(Component.DoMovementTick, 1f, 0.1f, 0.01f);
                Component.AttackRangeMultiplier = m_npc.Configuration.AttackRangeMultiplier;
                Component.MemoryDuration = m_npc.Configuration.MemoryDuration;
                Component.SenseRange = Math.Abs(m_npc.Configuration.SenseRange);
                Component.TargetLostRange = Component.SenseRange * 2f;
                Component.VisionCone = Vector3.Dot(Vector3.forward, Quaternion.Euler(0f, m_npc.Configuration.VisionCone, 0f) * Vector3.forward);
                Component.CheckVisionCone = m_npc.Configuration.CheckVisionCone;
                Component.CheckLOS = true;
                Component.IgnoreNonVisionSneakers = true;
                Component.MaxGroupSize = 0;
                Component.ListenRange = m_npc.Configuration.ListenRange;
                Component.HostileTargetsOnly = m_npc.Configuration.SenseRange < 0f;
                Component.IgnoreSafeZonePlayers = !Component.HostileTargetsOnly;
                Component.SenseTypes = EntityType.Player;
                Component.RefreshKnownLOS = false;
                Component.IgnoreNonVisionMaxDistance = Component.ListenRange / 3f;
                Component.IgnoreSneakersMaxDistance = Component.IgnoreNonVisionMaxDistance / 3f;
                Component.Senses.Init(m_npc.Component, Component, Component.MemoryDuration, Component.SenseRange, Component.TargetLostRange, Component.VisionCone, Component.CheckVisionCone, Component.CheckLOS, Component.IgnoreNonVisionSneakers, Component.ListenRange, Component.HostileTargetsOnly, false, Component.IgnoreSafeZonePlayers, Component.SenseTypes, Component.RefreshKnownLOS);
                Component.ThinkMode = AIThinkMode.Interval;
                Component.SetThinkRate(0.5f);
                Component.PathFinder = new HumanPathFinder();
                ((HumanPathFinder)Component.PathFinder).Init(m_npc.Component);
            }
            protected virtual void Think(float delta) {
                if (m_isInit == false) return;
                if (m_npc == null) return;
                if (Component == null) return;
                if (Component.Senses == null) return;
                if (Component.states == null) return;
                Component.SetLastThinkTime(Time.time);
                if (Component.sleeping) return;
                Component.Senses.Update();
                m_npc.SetBestTarget();
                if (Component.CurrentState != null) {
                    var thinkResult = Component.CurrentState.StateThink(delta, Component, m_npc.Component);
                    switch (thinkResult) {
                        case StateStatus.Finished : case StateStatus.Error : Component.CurrentState.StateLeave(Component, m_npc.Component);
                        Component.CurrentState = null;
                        break;
                        case StateStatus.Running : if (Component.CurrentState.CanLeave() == false) {
                            return;
                        }
                        break;
                    }
                }
                float num = 0f;
                BasicAIState newState = null;
                foreach (BasicAIState value in Component.states.Values) {
                    if (value == null || value.CanEnter() == false) continue;
                    float weight = value.GetWeight();
                    if (weight < num) continue;
                    num = weight;
                    newState = value;
                }
                if (newState != Component.CurrentState) {
                    Component.CurrentState?.StateLeave(Component, m_npc.Component);
                    Component.CurrentState = newState;
                    Component.CurrentState?.StateEnter(Component, m_npc.Component);
                }
            }
        }
#endregion
#region Gameplay\Controllers\CustomNpc_Controller.cs
        public class CustomNpc_Controller {
            public GameObject GameObject => Component.gameObject;
            public CustomNpc_Component Component {
                get;
                private set;
            }
            public CustomNpcBrain_Controller Brain {
                get;
                private set;
            }
            public CustomNpc_Pathfinding Pathfinding {
                get;
                private set;
            }
            public CustomNpc_Configuration Configuration {
                get;
                private set;
            }
            public float DistanceToTarget => Vector3.Distance(GameObject.transform.position, Component.CurrentTarget.transform.position);
            public float DistanceFromHome => Vector3.Distance(GameObject.transform.position, Component.HomePosition);
            public bool IsBehindBarricade() => Component.CanSeeTarget(Component.CurrentTarget) && HasNearbyBarricade();
            private Coroutine m_healCoroutine;
            private bool m_isInit;
#region Setup
            public virtual void Initialize(CustomNpc_Component component, CustomNpc_Configuration configuration) {
                Component = component;
                Configuration = configuration;
                Pathfinding = new CustomNpc_Pathfinding(this);
                m_isInit = true;
            }
            public virtual void Start(CustomNpcBrain_Controller brain) {
                if (m_isInit == false) {
                    Interface.Oxide.LogError("[CustomNpc] Start npc without initialization !!");
                    return;
                }
                Brain = brain;
                Component.Setup(brain.Component, GameObject.transform.position);
                RegisterEvents();
                Component.Spawn();
            }
            private void RegisterEvents() {
                Component.onServerInstantiated += OnSpawn;
                Component.onDestroy += OnDestroy;
            }
            protected virtual void OnSpawn() {
                if (m_isInit == false) return;
                Setup();
            }
            protected virtual void OnDestroy() {
                if (m_isInit == false) return;
                if (m_healCoroutine != null) ServerMgr.Instance.StopCoroutine(m_healCoroutine);
                if (Brain.Component.CurrentState != null) {
                    Brain.Component.CurrentState.StateLeave(Brain.Component, Component);
                }
                Component.onServerInstantiated -= OnSpawn;
                Component.onDestroy -= OnDestroy;
            }
            protected virtual void Setup() {
                if (m_isInit == false) return;
                Component.displayName = Configuration.Name;
                SetupNavAgent();
                SetupHealth();
                SetupDamages();
                SetupSound();
                SetupInventory();
                Component.InvokeRepeating(Component.LightCheck, 1f, 30f);
                // Todo : Config
                Component.InvokeRepeating(Update, 1f, 2f);
                // Todo : Config
            }
            protected virtual void SetupNavAgent() {
                if (Component.NavAgent == null) Component.NavAgent = GameObject.GetComponent<NavMeshAgent>();
                if (Component.NavAgent != null) {
                    Component.NavAgent.areaMask = Configuration.AreaMask;
                    Component.NavAgent.agentTypeID = Configuration.AgentTypeID;
                }
            }
            protected virtual void SetupHealth() {
                Component.startHealth = Configuration.StartHealth;
                Component._maxHealth = Configuration.MaxHealth;
                Component._health = Configuration.StartHealth;
            }
            protected virtual void SetupDamages() {
                Component.damageScale = Configuration.DamageScale;
            }
            protected virtual void SetupSound() {
                if (Configuration.DisableRadio) {
                    Component.CancelInvoke(Component.PlayRadioChatter);
                    Component.RadioChatterEffects = Array.Empty<GameObjectRef>();
                    Component.DeathEffects = Array.Empty<GameObjectRef>();
                }
            }
            protected virtual void SetupInventory() {
                ClearItems(Component.inventory.containerWear);
                ClearItems(Component.inventory.containerBelt);
                NpcAttire_Controller_Base attire = null;
                if (string.IsNullOrEmpty(Configuration.Kit) == false && PluginsExtensionsManager.Instance.LoadedPlugins.ContainsKey(NpcAttire_Kits_Controller.PLUGIN_NAME)) {
                    attire = new NpcAttire_Kits_Controller(this, Configuration.Kit);
                }
                else {
                    attire = new NpcAttire_Default_Controller(Component.inventory, Configuration.BeltItems, Configuration.WearItems);
                }
                attire.Equip();
            }
#endregion
            private void ClearItems(ItemContainer container) {
                for (int i = container.itemList.Count - 1; i >= 0; i--) {
                    Item item = container.itemList[i];
                    item.RemoveFromContainer();
                    item.Remove();
                }
            }
            protected virtual void Update() {
                if (m_isInit == false) return;
            }
            protected virtual void SetAimTowardsTarget() {
                Vector3 aimDirection = (Component.CurrentTarget.transform.position - GameObject.transform.position).normalized;
                Component.SetAimDirection(aimDirection);
            }
            private IEnumerable<Barricade> GetBarricadeHits(RaycastHit[] hits) {
                foreach (var hit in hits) {
                    var barricade = hit.GetEntity() as Barricade;
                    if (barricade != null && CoversData.Barricades.Contains(barricade.ShortPrefabName)) {
                        yield return barricade;
                    }
                }
            }
            private bool HasNearbyBarricade() {
                SetAimTowardsTarget();
                RaycastHit[] hits = UnityEngine.Physics.RaycastAll(Component.eyes.HeadRay());
                GamePhysics.Sort(hits);
                return GetBarricadeHits(hits).Any(barricade => Vector3.Distance(GameObject.transform.position, barricade.transform.position) < DistanceToTarget);
            }
#region Weapons
#region Grenade Launcher
            public bool IsReloadGrenadeLauncher {
                get;
                private set;
            }
            = false;
            protected int m_availableAmmoInGrenadeLauncher = 6;
            public virtual void FireGrenadeLauncher() {
                RaycastHit raycastHit;
                Component.SignalBroadcast(Signal.Attack, string.Empty);
                Vector3 vector3 = Component.IsMounted() ? Component.eyes.position + new Vector3(0f, 0.5f, 0f) : Component.eyes.position;
                Vector3 modifiedAimConeDirection = AimConeUtil.GetModifiedAimConeDirection(0.675f, Component.eyes.BodyForward());
                float distance = 1f;
                if (UnityEngine.Physics.Raycast(vector3, modifiedAimConeDirection, out raycastHit, distance, 1236478737)) distance = raycastHit.distance - 0.1f;
                TimedExplosive grenade = GameManager.server.CreateEntity("assets/prefabs/ammo/40mmgrenade/40mm_grenade_he.prefab", vector3 + modifiedAimConeDirection * distance) as TimedExplosive;
                grenade.creatorEntity = Component;
                ServerProjectile serverProjectile = grenade.GetComponent<ServerProjectile>();
                serverProjectile.InitializeVelocity(Component.GetInheritedProjectileVelocity(modifiedAimConeDirection) + modifiedAimConeDirection * serverProjectile.speed * 2f);
                grenade.Spawn();
                m_availableAmmoInGrenadeLauncher--;
                if (m_availableAmmoInGrenadeLauncher == 0) {
                    IsReloadGrenadeLauncher = true;
                    Component.Invoke(FinishReloadGrenadeLauncher, 8f);
                }
            }
            protected void FinishReloadGrenadeLauncher() {
                m_availableAmmoInGrenadeLauncher = 6;
                IsReloadGrenadeLauncher = false;
            }
#endregion Multiple Grenade Launcher
#region Flame Thrower
            public bool IsReloadFlameThrower {
                get;
                private set;
            }
            public virtual void FireFlameThrower() {
                FlameThrower flameThrower = Component.CurrentWeapon as FlameThrower;
                if (flameThrower == null || flameThrower.IsFlameOn()) return;
                if (flameThrower.ammo <= 0) {
                    IsReloadFlameThrower = true;
                    Component.Invoke(FinishReloadFlameThrower, 4f);
                    return;
                }
                flameThrower.SetFlameState(true);
                Component.Invoke(flameThrower.StopFlameState, 0.25f);
            }
            protected void FinishReloadFlameThrower() {
                FlameThrower flameThrower = Component.CurrentWeapon as FlameThrower;
                if (flameThrower == null) return;
                flameThrower.TopUpAmmo();
                IsReloadFlameThrower = false;
            }
#endregion Flame Thrower
#region Melee Weapon
            public void UseMeleeWeapon() {
                BaseMelee weapon = Component.CurrentWeapon as BaseMelee;
                if (weapon.HasAttackCooldown()) return;
                weapon.StartAttackCooldown(weapon.repeatDelay * 2f);
                Component.SignalBroadcast(Signal.Attack, string.Empty, null);
                if (weapon.swingEffect.isValid) Effect.server.Run(weapon.swingEffect.resourcePath, weapon.transform.position, Vector3.forward, Component.net.connection, false);
                Vector3 vector31 = Component.eyes.BodyForward();
                for (int i = 0; i < 2; i++) {
                    List<RaycastHit> list = Pool.GetList<RaycastHit>();
                    GamePhysics.TraceAll(new Ray(Component.eyes.position - (vector31 * (i == 0 ? 0f : 0.2f)), vector31), (i == 0 ? 0f : weapon.attackRadius), list, weapon.effectiveRange + 0.2f, 1219701521, QueryTriggerInteraction.UseGlobal, null);
                    bool flag = false;
                    for (int j = 0; j < list.Count; j++) {
                        RaycastHit item = list[j];
                        BaseEntity entity = item.GetEntity();
                        if (entity != null && (entity == null || entity != Component && !entity.EqualNetID(Component)) && (entity == null || !entity.isClient)) {
                            float single = weapon.damageTypes.Sum(x => x.amount);
                            entity.OnAttacked(new HitInfo(Component, entity, DamageType.Slash, single * weapon.npcDamageScale * Configuration.DamageScale));
                            HitInfo hitInfo = Pool.Get<HitInfo>();
                            hitInfo.HitEntity = entity;
                            hitInfo.HitPositionWorld = item.point;
                            hitInfo.HitNormalWorld = -vector31;
                            if (entity is BaseNpc || entity is BasePlayer) hitInfo.HitMaterial = StringPool.Get("Flesh");
                            else hitInfo.HitMaterial = StringPool.Get(item.GetCollider().sharedMaterial != null ? item.GetCollider().sharedMaterial.GetName() : "generic");
                            weapon.ServerUse_OnHit(hitInfo);
                            Effect.server.ImpactEffect(hitInfo);
                            Pool.Free(ref hitInfo);
                            flag = true;
                            if (entity == null || entity.ShouldBlockProjectiles()) break;
                        }
                    }
                    Pool.FreeList(ref list);
                    if (flag) break;
                }
            }
#endregion Melee Weapon
#endregion
#region Targeting
            public virtual void SetBestTarget() {
                BaseEntity bestTarget = null;
                float highestScore = -1f;
                foreach (BaseEntity potentialTarget in Brain.Component.Senses.Players) {
                    if (!CanTargetEntity(potentialTarget)) continue;
                    float targetScore = CalculateTargetScore(potentialTarget);
                    if (targetScore > highestScore) {
                        bestTarget = potentialTarget;
                        highestScore = targetScore;
                    }
                }
                Component.SetTarget(bestTarget);
            }
            protected virtual float CalculateTargetScore(BaseEntity entity) {
                float distanceScore = 1f - Mathf.InverseLerp(1f, Brain.Component.SenseRange, Vector3.Distance(entity.transform.position, GameObject.transform.position));
                float visionScore = Mathf.InverseLerp(Brain.Component.VisionCone, 1f, Vector3.Dot((entity.transform.position - Component.eyes.position).normalized, Component.eyes.BodyForward())) / 2f;
                float losBonus = Brain.Component.Senses.Memory.IsLOS(entity) ? 2f : 0f;
                return distanceScore + visionScore + losBonus;
            }
            protected virtual bool CanTargetEntity(BaseEntity target) {
                if (target == null || target.IsDestroyed || target.Health() <= 0f) return false;
                BasePlayer player = target as BasePlayer;
                if (player != null) {
                    return CanTargetPlayer(player);
                }
                else {
                    Drone drone = target as Drone;
                    if (drone != null) {
                        return CanTargetDrone(drone);
                    }
                }
                return false;
            }
            private bool CanTargetPlayer(BasePlayer player) {
                if (player.IsDead()) return false;
                if (player.skinID != 0 && NpcSkinsData.PlayerSkinIDs.Contains(player.skinID)) return true;
                if (player.userID.IsSteamId()) return !player.IsSleeping() && !player.IsWounded() && !player._limitedNetworking;
                NPCPlayer npcPlayer = player as NPCPlayer;
                if (npcPlayer != null) return CanTargetNpcPlayer(npcPlayer);
                return false;
            }
            protected virtual bool CanTargetNpcPlayer(NPCPlayer npcPlayer) {
                return npcPlayer is FrankensteinPet || Configuration.CanTargetOtherNpc;
            }
            protected virtual bool CanTargetDrone(Drone drone) {
                return !(Component.CurrentWeapon is BaseMelee);
            }
#endregion
            public void Heal() {
                m_healCoroutine = ServerMgr.Instance.StartCoroutine(HealCoroutine());
            }
            private IEnumerator HealCoroutine() {
                Component.OnHeal();
                Item syringe = Component.inventory.containerBelt.itemList.FirstOrDefault(x => x.info.shortname == "syringe.medical");
                Component.OnDesequipingWeapon();
                Component.UpdateActiveItem(syringe.uid);
                MedicalTool medicalTool = syringe.GetHeldEntity() as MedicalTool;
                yield return CoroutineEx.waitForSeconds(1.5f);
                if (medicalTool != null) medicalTool.ServerUse();
                Component.InitializeHealth(Component.health + 15f > Configuration.MaxHealth ? Configuration.MaxHealth : Component.health + 15f, Configuration.MaxHealth);
                yield return CoroutineEx.waitForSeconds(3f);
                Component.OnFinishHeal();
            }
        }
#endregion
#region Gameplay\Data\CoversData.cs
        public static class CoversData {
            public static readonly HashSet<string> Barricades = new HashSet<string> {
                "barricade.cover.wood", "barricade.sandbags", "barricade.concrete", "barricade.stone"
            }
            ;
        }
#endregion
#region Gameplay\Data\NpcSkinsData.cs
        public static class NpcSkinsData {
            public static HashSet<ulong> PlayerSkinIDs = new HashSet<ulong> {
                14922524, 19395142091920
            }
            ;
        }
#endregion
#region Gameplay\Data\WeaponsData.cs
        public static class WeaponsData {
            public class Range {
                public float EffectiveRange;
                public float AttackLengthMin;
                public float AttackLengthMax;
            }
            public static readonly Dictionary<string, Range> WeaponsRange = new Dictionary<string, Range> {
                ["snowballgun"]
                = new Range {
                    EffectiveRange = 5f, AttackLengthMin = 2f, AttackLengthMax = 2f
                }
                , ["shotgun.double"] = new Range {
                    EffectiveRange = 10f, AttackLengthMin = 0.3f, AttackLengthMax = 1f
                }
                , ["pistol.eoka"] = new Range {
                    EffectiveRange = 10f, AttackLengthMin = -1f, AttackLengthMax = -1f
                }
                , ["shotgun.waterpipe"] = new Range {
                    EffectiveRange = 10f, AttackLengthMin = -1f, AttackLengthMax = -1f
                }
                , ["speargun"] = new Range {
                    EffectiveRange = 15f, AttackLengthMin = -1f, AttackLengthMax = -1f
                }
                , ["bow.compound"] = new Range {
                    EffectiveRange = 15f, AttackLengthMin = -1f, AttackLengthMax = -1f
                }
                , ["crossbow"] = new Range {
                    EffectiveRange = 15f, AttackLengthMin = -1f, AttackLengthMax = -1f
                }
                , ["bow.hunting"] = new Range {
                    EffectiveRange = 15f, AttackLengthMin = -1f, AttackLengthMax = -1f
                }
                , 
// ... [Code preview truncated due to length. Full source in attached file] ...

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