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

FREE NPCRoam : 0.0.1 0.0.1

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6

// Requires: Cordyceps
using Convert = System.Convert;
using Network;
using Oxide.Core.Plugins;
using Oxide.Core;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using Rust.Ai;
using System;
using System.IO;
using UnityEngine; 
using Newtonsoft.Json;
using Oxide.Core.Libraries.Covalence;
using Oxide.Plugins;
using Oxide.Core.Plugins;
using Oxide.Core;

namespace Oxide.Plugins
{
	[Info("NPCRoam", "obsol", "0.0.1")]
	[Description("A baseline for swapping out custom AI state handlers without lobotomies.")]
	public class NPCRoam : CovalencePlugin
	{
		private Game.Rust.Libraries.Player _rustPlayer = Interface.Oxide.GetLibrary<Game.Rust.Libraries.Player>("Player");
		private void SendChatMsg(BasePlayer pl, string msg) => _rustPlayer.Message(pl, msg,  "<color=#00ff00>[NPCRoam]</color>", 0, Array.Empty<object>());			
		public Configuration config;
		//public LayerMask NPCLayers = 0; //Debug.Log(LayerMask.LayerToName(1));
		
		Cordyceps cordy;
		
		private void Loaded()
		{
			cordy = (Cordyceps)Manager.GetPlugin("Cordyceps");
			string[] targets = new string[]{"assets/rust.ai/agents/npcplayer/humannpc/banditguard/npc_bandit_guard.prefab", 
			"assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_any.prefab", 
			"assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_lr300.prefab", 
			"assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_mp5.prefab", 
			"assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_pistol.prefab", 
			"assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_shotgun.prefab", 
			"assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_heavy.prefab", 
			"assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_junkpile_pistol.prefab", 
			"assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_peacekeeper.prefab", 
			"assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_roam.prefab"};
			foreach(string s in targets){
				CustomChaseState ccs= new CustomChaseState();
				CustomRoam cr = new CustomRoam();
				CustomTryCover ctc= new CustomTryCover();
				cordy.AssignHumanState(s, ccs.StateType, ccs);
				cordy.AssignHumanState(s, cr.StateType, cr);
				cordy.AssignHumanState(s, ctc.StateType, ctc);
			}
		}
		
		public class Configuration
		{
			[JsonProperty("Name", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public string name = "";
			public string ToJson() => JsonConvert.SerializeObject(this);				
			public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
			
		}
		
		protected override void LoadDefaultConfig() => config = new Configuration();//
		protected override void LoadConfig(){
			base.LoadConfig();
			try{
				config = Config.ReadObject<Configuration>();
				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 e){LogWarning($"Configuration file {Name}.json is invalid; using defaults");LogWarning(e.ToString());LoadDefaultConfig();}
		}
		
		protected override void SaveConfig(){
			LogWarning($"Configuration changes saved to {Name}.json");
			Config.WriteObject(config, true);
		}	
		
		private void OnServerInitialized()
        {
			LoadConfig();
		}
		
		class CustomRoam : global::BaseAIBrain<HumanNPC>.BaseRoamState
		{
			private global::StateStatus status = global::StateStatus.Error;
			Vector3 LastVector = new Vector3(0,-501,0);
			float LastWet = 0f;
			Vector3 Target = new Vector3(0,0,0);
			Vector3 Root = new Vector3(0,0,0);
			Vector3 Direction = new Vector3(0,0,0);
			Vector3 currentPosition = new Vector3(0,0,0);
			float startTime = 0;
			bool TurnDirection = false;
			float nextThinkTime = 0f;
			BaseNavigator.NavigationSpeed Speed = BaseNavigator.NavigationSpeed.Normal;
			bool hasWarped = false;
			bool stuck = false;
			public CustomRoam() : base(){
				TurnDirection = (Oxide.Core.Random.Range(0, 2) == 1);
				startTime = Time.realtimeSinceStartup;
				nextThinkTime=startTime+1;
			}
			public override void StateEnter(){
				base.StateEnter();
				Root = this.brain.transform.position;
				currentPosition = Root;
				Speed = BaseNavigator.NavigationSpeed.Normal;
				float currentWet = WaterLevel.GetOverallWaterDepth(this.brain.transform.position, true, null, false);
				Direction =  (stuck?(-1*this.brain.transform.forward):this.brain.transform.forward);
				stuck=false;
				
				if(this.brain.GroupLeader!=null){
					Root=(this.brain.Events.Memory.Entity.Get(6)).transform.position;
					Target = this.brain.PathFinder.GetRandomPositionAround(Root+Direction,3f, 5f);
				}
				if(this.brain.OwningPlayer!=null){
					Root=(this.brain.OwningPlayer).transform.position;
					Target = this.brain.PathFinder.GetRandomPositionAround(Root+Direction,3f, 5f);
				}
				else {
					if(currentWet > 0f)	{
						Root = LastVector;
						Direction = (TurnDirection?this.brain.transform.right:(-1*this.brain.transform.right));
						Target = this.brain.PathFinder.GetRandomPositionAround(Root-(this.brain.transform.forward*5)+(Direction*5),4f, 5f);
						
						if (currentWet > 80f)
						{
								(this.brain.GetEntity() as BasePlayer)?.Hurt(10f);
								
						}
						
					}else{
						LastWet=currentWet;
						LastVector=this.brain.transform.position;
						Target = this.brain.PathFinder.GetRandomPositionAround(Root+(Direction*10),2f, 5f);						
					}
				}
				if(Vector3.Distance(Target,this.brain.transform.position)<5)
					Speed = BaseNavigator.NavigationSpeed.Slow;
				if(Vector3.Distance(Target,this.brain.transform.position)>15)
					Speed = BaseNavigator.NavigationSpeed.Fast;
				
				if (this.brain.Navigator.SetDestination(Target, Speed, 0f, 0f))
				{
					this.status = global::StateStatus.Running;
				}
				else{
					status = global::StateStatus.Error;					
					if(!hasWarped){
						this.brain.Navigator.Warp(this.brain.transform.position);
						hasWarped=true;
					}
				}
			}
			public override global::StateStatus StateThink(float delta)
			{
				if (this.status == global::StateStatus.Error)
					return this.status;
				if (this.brain.Navigator.Moving && Time.realtimeSinceStartup <(startTime+10))
					return global::StateStatus.Running;
				return global::StateStatus.Finished;
			}
			public override void StateLeave()
			{
				if(Vector3.Distance(currentPosition,this.brain.transform.position)<0.1f)stuck=true;
				base.StateLeave();
				
			}
		}
		
		class CustomTryCover : global::BaseAIBrain<HumanNPC>.BasicAIState
		{
			private global::StateStatus status = global::StateStatus.Error;
			
			public CustomTryCover():base(AIState.TakeCover){}
			
			public override void StateEnter(){
				base.StateEnter();
				if (this.brain.Navigator.SetDestination(this.brain.PathFinder.GetRandomPositionAround(this.brain.transform.position+(
					((-this.brain.Events.Memory.Entity.Get(this.brain.Events.CurrentInputMemorySlot).transform.right)*7)+
					(this.brain.Events.Memory.Entity.Get(this.brain.Events.CurrentInputMemorySlot).transform.forward*5)
					),3f, 7f), global::BaseNavigator.NavigationSpeed.Fast, 0f, 0f))
				{
					this.status = global::StateStatus.Running;
					return;
				}
			}
			public override global::StateStatus StateThink(float delta)
			{
				if (this.status == global::StateStatus.Error)
					return this.status;
				if (this.brain.Navigator.Moving)
					return global::StateStatus.Running;
				return global::StateStatus.Finished;
			}
			
		}
		
		class CustomChaseState : global::BaseAIBrain<global::HumanNPC>.BaseChaseState
		{
			Vector3 LastVector = new Vector3(0,-501,0);
			Vector3 Target = new Vector3(0,0,0);
			Vector3 Root = new Vector3(0,0,0);
			Vector3 Direction = new Vector3(0,0,0);
			float LastWet = 0f;
			float startTime = 0;
			bool TurnDirection = false;
			bool hasWarped = false;
			BaseNavigator.NavigationSpeed Speed = BaseNavigator.NavigationSpeed.Normal;
			public CustomChaseState() : base()
			{
				base.AgrresiveState = true;
				TurnDirection = (Oxide.Core.Random.Range(0, 2) == 1);
				startTime = Time.realtimeSinceStartup;
			}

			public override void StateLeave()
			{
				base.StateLeave();
						
				this.Stop();
			}

			public override void StateEnter()
			{
				base.StateEnter();
				this.status = global::StateStatus.Error;
				if (this.brain.PathFinder == null)
				{
					return;
				}
						
				if (WaterLevel.GetOverallWaterDepth(this.brain.transform.position, true, null, false) > 0.8f)
				{
					(this.brain.GetEntity() as BasePlayer).Hurt(10f);
				}
				this.status = global::StateStatus.Running;
				this.nextPositionUpdateTime = 0f;
				global::BaseEntity baseEntity = this.brain.Events.Memory.Entity.Get(this.brain.Events.CurrentInputMemorySlot);
				if (baseEntity != null)
				{
					this.brain.Navigator.SetDestination(this.brain.PathFinder.GetRandomPositionAround(baseEntity.transform.position,5f, 10f), global::BaseNavigator.NavigationSpeed.Fast, 0.25f, 0f);
				}
			}

			private void Stop()
			{
				this.brain.Navigator.Stop();
				this.brain.Navigator.ClearFacingDirectionOverride();
			}

			public override global::StateStatus StateThink(float delta)
			{
				global::BaseEntity baseEntity = this.brain.Events.Memory.Entity.Get(this.brain.Events.CurrentInputMemorySlot);
				if (baseEntity == null)
				{
					return global::StateStatus.Error;
				}
				global::HumanNPC entity = base.GetEntity();
				float num = Vector3.Distance(baseEntity.transform.position, entity.transform.position);
				if (this.brain.Senses.Memory.IsLOS(baseEntity) || num <= 10f || base.TimeInState <= 5f)
				{
					this.brain.Navigator.SetFacingDirectionEntity(baseEntity);
				}
				else
				{
					this.brain.Navigator.ClearFacingDirectionOverride();
				}
				if (num <= 10f)
				{
					this.brain.Navigator.SetCurrentSpeed(global::BaseNavigator.NavigationSpeed.Normal);
				}
				else
				{
					this.brain.Navigator.SetCurrentSpeed(global::BaseNavigator.NavigationSpeed.Fast);
				}
				if (Time.time > this.nextPositionUpdateTime)
				{
					this.nextPositionUpdateTime = Time.time + UnityEngine.Random.Range(0.5f, 1f);			
					
					this.status = global::StateStatus.Running;
					float currentWet = WaterLevel.GetOverallWaterDepth(this.brain.transform.position, true, null, false);
					if(currentWet > 0f)	{
						if (currentWet > 0.8f){
								(this.brain.GetEntity() as BasePlayer).Hurt(10f);
						}
						Root = LastVector;
						Direction = (TurnDirection?this.brain.transform.right:(-1*this.brain.transform.right));
						Target = this.brain.PathFinder.GetRandomPositionAround(Root-(this.brain.transform.forward*3)+(Direction*3),7f, 10f);
						if(Vector3.Distance(Target,this.brain.transform.position)<5)
							Speed = BaseNavigator.NavigationSpeed.Slow;
						if(Vector3.Distance(Target,this.brain.transform.position)>15)
							Speed = BaseNavigator.NavigationSpeed.Fast;
						
						if (this.brain.Navigator.SetDestination(Target, Speed, 0f, 0f))
						{
							this.status = global::StateStatus.Running;
							return this.status;
						}
						else{
							status = global::StateStatus.Error;
							if(!hasWarped){
								this.brain.Navigator.Warp(this.brain.transform.position);
								hasWarped=true;
							}
						}
					
					}else{
						LastWet=currentWet;
						LastVector=this.brain.transform.position;				
					}
				}
				if (this.brain.Navigator.Moving)
				{
					return global::StateStatus.Running;
				}
				return global::StateStatus.Finished;
				
				
			}

			private global::StateStatus status = global::StateStatus.Error;

			private float nextPositionUpdateTime;
		}


	}
}

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