private IEnumerator MarkRoutine() { AITarget target = GetComponent <AITarget>(); if (target == null) { yield break; } target.alignment = Alignment.Wildcard; // TODO - Flashing particle effect while (duration > 0) { duration -= Time.deltaTime; Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, radius); for (int i = 0; i < colliders.Length; ++i) { AIController controller = colliders[i].GetComponent <AIController>(); if (controller != null && controller.gameObject != gameObject) { controller.SetTarget(target); } } yield return(null); } if (target.attackingEnemies.Count == 0) { target.ResetAlignmentFrom(Alignment.Wildcard); } // TODO - Destroy flashing effect Destroy(this); }
// Update is called once per frame void Update() { if (!character.dead) { if (target != null && target.targetObject != null) { CheckSight(target); float targetDistance = Vector2.Distance(this.transform.position, target.targetObject.transform.position); target.distance = targetDistance; inputMove = Vector2.zero; if (AIState != AIStates.Melee && AIState != AIStates.Shooting && AIState != AIStates.Wait) { HandleMove(targetDistance, target); } if (AIState == AIStates.Melee) { HandleMelee(); } if (AIState == AIStates.Shooting) { HandleShooting(); } if (currentTimeBetweenAttacks <= 0) { if (target.lineOfSight) { if (canMelee && (targetDistance <= meleeRange)) { if (AIState != AIStates.Melee) { currentAttackLoadTime = attackLoadTime; targetPosition = target.targetObject.transform.position; movementController.lastInputMove = (targetPosition - this.transform.position).normalized; movementController.PlayAnimation( SNMovementController.AnimationsStates.Prepare, true); character.immune = true; AIState = AIStates.Melee; } } else if (canShoot && (targetDistance <= shotRange)) { if (AIState != AIStates.Melee) { currentAttackLoadTime = attackLoadTime; targetPosition = target.targetObject.transform.position; movementController.PlayAnimation( SNMovementController.AnimationsStates.Prepare, true); AIState = AIStates.Shooting; } } } } else { currentTimeBetweenAttacks -= Time.deltaTime; } if (target.targetCharacter.dead) { AITargets.Remove(target); target = null; } } else { FindTargets(); } movementController.MoveUpdate(inputMove); target = ChooseTarget(AggroBase); } }
private AITarget ChooseTarget(AIAggroBases aggroBase) { AITarget rv = null; for (int i = 0; i < AITargets.Count; i++) { if (AITargets [i].targetCharacter.dead) { Debug.Log("remove target"); AITargets.Remove(AITargets [i]); } } for (int i = 0; i < AITargets.Count; i++) { if (AITargets [i].targetObject == null) { Debug.Log("remove target"); AITargets.Remove(AITargets [i]); } } for (int i = 0; i < AITargets.Count; i++) { if (Vector3.Distance(this.transform.position, AITargets [i].targetObject.transform.position) <= chaseRange) { AITargets [i].spotted = true; } } if (AITargets.Count == 1) { if (AITargets [0].spotted) { return(AITargets [0]); } else { return(null); } } else if (AITargets.Count == 0) { return(null); } int last = 0; bool found = false; if (AITargets [last].targetObject != null) { float lastDist = -1f; for (int i = 0; i < AITargets.Count; i++) { if (AITargets [i].spotted) { found = true; if (aggroBase == AIAggroBases.Closest) { float dist = Vector3.Distance(this.transform.position, AITargets [i].targetObject.transform.position); if ((lastDist > dist) || (lastDist == -1f)) { lastDist = dist; last = i; } } else if (aggroBase == AIAggroBases.AllDamage) { if ((AITargets [last].dealedDamageToMe + AITargets [last].dealedDamageByMe) < (AITargets [i].dealedDamageToMe + AITargets [i].dealedDamageToMe)) { last = i; } } else if (aggroBase == AIAggroBases.ReceivedDamage) { if (AITargets [last].dealedDamageByMe < AITargets [i].dealedDamageByMe) { last = i; } } else if (aggroBase == AIAggroBases.DealedDamage) { if (AITargets [last].dealedDamageToMe < AITargets [i].dealedDamageToMe) { last = i; } } } } } if (found) { Debug.LogWarning("best target not found, search for closest"); rv = AITargets [last]; if (aggroBase == AIAggroBases.AllDamage) { if (AITargets [last].dealedDamageToMe + AITargets [last].dealedDamageByMe == 0) { rv = ChooseTarget(AIAggroBases.Closest); } } else if (aggroBase == AIAggroBases.ReceivedDamage) { if (AITargets [last].dealedDamageByMe == 0) { rv = ChooseTarget(AIAggroBases.Closest); } } else if (aggroBase == AIAggroBases.DealedDamage) { if (AITargets [last].dealedDamageToMe == 0) { rv = ChooseTarget(AIAggroBases.Closest); } } } return(rv); }
public override void OnEnabled() { try { Log.Info("Started plugin initialization..."); Instance = this; Random = new Random(); foreach (MethodBase bas in Evs.Events.Instance.Harmony.GetPatchedMethods()) { if (bas.Name.Equals("TransmitData")) { Exiled.Events.Events.DisabledPatchesHashSet.Add(bas); } else if (bas.DeclaringType.Name.Equals("RoundSummary") && bas.Name.Equals("Start")) { Exiled.Events.Events.DisabledPatchesHashSet.Add(bas); } else if (bas.Name.Equals("BanUser")) { Exiled.Events.Events.DisabledPatchesHashSet.Add(bas); } else if (bas.Name.Equals("CallCmdShoot")) { Exiled.Events.Events.DisabledPatchesHashSet.Add(bas); } } Evs.Events.Instance.ReloadDisabledPatches(); Harmony = new HarmonyLib.Harmony($"gamehunt.cnpcs.{reloads}"); reloads++; Harmony.PatchAll(); EventHandlers = new EventHandlers(); Handlers.Server.RoundStarted += EventHandlers.OnRoundStart; Handlers.Server.RoundEnded += EventHandlers.OnRoundEnd; Handlers.Server.WaitingForPlayers += EventHandlers.OnWaitingForPlayers; Handlers.Server.RespawningTeam += EventHandlers.OnTeamRespawning; Handlers.Player.Dying += EventHandlers.OnDying; Handlers.Player.EnteringPocketDimension += EventHandlers.OnEnteringPocketDim; Handlers.Player.Hurting += EventHandlers.OnHurt; Handlers.Map.ExplodingGrenade += EventHandlers.OnGrenadeExplosion; Handlers.Map.Decontaminating += EventHandlers.OnDecontamination; Handlers.Warhead.Starting += EventHandlers.OnWarheadStart; if (!Directory.Exists(Config.NPCs_root_path)) { Directory.CreateDirectory(Config.NPCs_root_path); } if (!Directory.Exists(Config.NPCs_nodes_path)) { Directory.CreateDirectory(Config.NPCs_nodes_path); } if (!Directory.Exists(Config.NPCs_mappings_path)) { Directory.CreateDirectory(Config.NPCs_mappings_path); } if (!File.Exists(Config.NPCs_nav_mappings_path)) { StreamWriter sw = File.CreateText(Config.NPCs_nav_mappings_path); sw.Write(Config.DefaultNavMappings); sw.Close(); } if (!File.Exists(Path.Combine(Config.NPCs_nodes_path, "default_node.yml"))) { StreamWriter sw = File.CreateText(Path.Combine(Config.NPCs_nodes_path, "default_node.yml")); sw.Write(Config.DefaultNodeContents); sw.Close(); } if (!File.Exists(Path.Combine(Config.NPCs_root_path, "default_npc.yml"))) { StreamWriter sw = File.CreateText(Path.Combine(Config.NPCs_root_path, "default_npc.yml")); sw.Write(Config.DefaultNPCContents); sw.Close(); } Log.Info("Registering conditions..."); NodeCondition.Register(new RoleCondition()); NodeCondition.Register(new HasItemCondition()); NodeCondition.Register(new HasntItemCondition()); NodeCondition.Register(new HealthCondition()); NodeCondition.Register(new ArtificalHealthCondition()); NodeCondition.Register(new HasEffectCondition()); NodeCondition.Register(new HasntEffectCondition()); NodeCondition.Register(new PermissionCondition()); NodeCondition.Register(new RoundTimeCondition()); NodeCondition.Register(new NukeStateCondition()); NodeCondition.Register(new HeldItemCondition()); NodeCondition.Register(new RoleExistsCondition()); NodeCondition.Register(new RoleNotExistsCondition()); NodeCondition.Register(new RandomCondition()); Log.Info("Registering actions..."); NodeAction.Register(new Actions.DieAction()); NodeAction.Register(new Actions.GiveItemAction()); NodeAction.Register(new Actions.RetrieveItemAction()); NodeAction.Register(new Actions.GiveHealthAction()); NodeAction.Register(new Actions.ConsumeHealthAction()); NodeAction.Register(new Actions.EnableEffectAction()); NodeAction.Register(new Actions.DisableEffectAction()); NodeAction.Register(new Actions.BroadcastAction()); NodeAction.Register(new Actions.HeldItemAction()); NodeAction.Register(new Actions.BlackoutAction()); NodeAction.Register(new Actions.ChangeRoleAction()); NodeAction.Register(new Actions.ChangeSelfRoleAction()); NodeAction.Register(new Actions.NukeStartAction()); NodeAction.Register(new Actions.NukeStopAction()); NodeAction.Register(new Actions.StartDecontaminationAction()); NodeAction.Register(new Actions.SwitchGodAction()); NodeAction.Register(new Actions.MoveAction()); NodeAction.Register(new Actions.RotationAction()); NodeAction.Register(new Actions.RoundEndAction()); NodeAction.Register(new Actions.CassieAction()); NodeAction.Register(new Actions.RoomTeleportAction()); NodeAction.Register(new Actions.RoomSelfTeleportAction()); NodeAction.Register(new Actions.DropItemAction()); NodeAction.Register(new Actions.NavEnqueueAction()); NodeAction.Register(new Actions.NavClearAction()); NodeAction.Register(new Actions.FollowAction()); NodeAction.Register(new Actions.StopFollowAction()); NodeAction.Register(new Actions.FireEventAction()); NodeAction.Register(new Actions.ShootAction()); NodeAction.Register(new Actions.GoToRoomAction()); NodeAction.Register(new Actions.ControlDoorAction()); NodeAction.Register(new Actions.ToggleAIAction()); Log.Info("Registering AI targets..."); AITarget.Register(new AITestTarget()); AITarget.Register(new AIFindPlayerTarget()); AITarget.Register(new AIAttackTarget()); AITarget.Register(new AINavigateToRoom()); AITarget.Register(new AIFollowTarget()); AITarget.Register(new AIFindItemTarget()); AITarget.Register(new AIConditionalJump()); //AITarget.Register(new AIRunAwayTarget()); //AITarget.Register(new AIFindAmmoTarget()); AITarget.Register(new AIStop()); Log.Info("Registering targets filters..."); TargetFilter.Register(new CommonTargetFilter()); TargetFilter.Register(new Scp939TargetFilter()); TargetFilter.Register(new Scp096TargetFilter()); Log.Info($"CustomNPCs plugin loaded. @gamehunt"); } catch (Exception e) { Log.Error($"There was an error loading the plugin: {e}"); } }
/// <summary> /// Locate the specified AI target /// </summary> /// <param name="_target">Target to locate</param> public virtual void LocateTarget(AITarget _target) { mTarget = _target; }
public virtual void SetTarget(AITarget targ) { target = targ; }
public static void UnregisterTarget(AITarget target) { targets.Remove(target); }
public ItemComponent(Item item, XElement element) { this.item = item; originalElement = element; name = element.Name.ToString(); SerializableProperties = SerializableProperty.GetProperties(this); requiredItems = new Dictionary <RelatedItem.RelationType, List <RelatedItem> >(); requiredSkills = new List <Skill>(); #if CLIENT sounds = new Dictionary <ActionType, List <ItemSound> >(); #endif SelectKey = InputType.Select; try { string selectKeyStr = element.GetAttributeString("selectkey", "Select"); selectKeyStr = ToolBox.ConvertInputType(selectKeyStr); SelectKey = (InputType)Enum.Parse(typeof(InputType), selectKeyStr, true); } catch (Exception e) { DebugConsole.ThrowError("Invalid select key in " + element + "!", e); } PickKey = InputType.Select; try { string pickKeyStr = element.GetAttributeString("pickkey", "Select"); pickKeyStr = ToolBox.ConvertInputType(pickKeyStr); PickKey = (InputType)Enum.Parse(typeof(InputType), pickKeyStr, true); } catch (Exception e) { DebugConsole.ThrowError("Invalid pick key in " + element + "!", e); } SerializableProperties = SerializableProperty.DeserializeProperties(this, element); ParseMsg(); foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "requireditem": case "requireditems": RelatedItem ri = RelatedItem.Load(subElement, item.Name); if (ri != null) { if (!requiredItems.ContainsKey(ri.Type)) { requiredItems.Add(ri.Type, new List <RelatedItem>()); } requiredItems[ri.Type].Add(ri); } else { DebugConsole.ThrowError("Error in item config \"" + item.ConfigFile + "\" - component " + GetType().ToString() + " requires an item with no identifiers."); } break; case "requiredskill": case "requiredskills": if (subElement.Attribute("name") != null) { DebugConsole.ThrowError("Error in item config \"" + item.ConfigFile + "\" - skill requirement in component " + GetType().ToString() + " should use a skill identifier instead of the name of the skill."); continue; } string skillIdentifier = subElement.GetAttributeString("identifier", ""); requiredSkills.Add(new Skill(skillIdentifier, subElement.GetAttributeInt("level", 0))); break; case "statuseffect": var statusEffect = StatusEffect.Load(subElement, item.Name); if (statusEffectLists == null) { statusEffectLists = new Dictionary <ActionType, List <StatusEffect> >(); } List <StatusEffect> effectList; if (!statusEffectLists.TryGetValue(statusEffect.type, out effectList)) { effectList = new List <StatusEffect>(); statusEffectLists.Add(statusEffect.type, effectList); } effectList.Add(statusEffect); break; case "aitarget": AITarget = new AITarget(item, subElement) { Enabled = isActive }; break; default: if (LoadElemProjSpecific(subElement)) { break; } ItemComponent ic = Load(subElement, item, item.ConfigFile, false); if (ic == null) { break; } ic.Parent = this; item.AddComponent(ic); break; } } }
public override void OnTriggerEvent(AITriggerEventType eventType, Collider other) { if (_zombieStateMachine == null) { return; } if (eventType != AITriggerEventType.Exit) { AITarget curType = _zombieStateMachine.VisualThreat; if (other.CompareTag("Player")) { float distance = Vector3.Distance(_zombieStateMachine.sensorPosition, other.transform.position); if (curType.type != AITargetType.Visual_Player || (curType.type != AITargetType.Visual_Player && distance < _stateMachine.VisualThreat.distance)) { RaycastHit hitInfo; if (ColliderIsVisible(other, out hitInfo, _playerLayerMask)) { _zombieStateMachine.VisualThreat.Set(AITargetType.Visual_Player, other, other.transform.position, distance); } } } else if (other.CompareTag("Flash Light") && curType.type != AITargetType.Visual_Player) { BoxCollider flashLightTrigger = (BoxCollider)other; float distanceToThreat = Vector3.Distance(_zombieStateMachine.sensorPosition, flashLightTrigger.transform.position); float zSize = flashLightTrigger.size.z * flashLightTrigger.transform.lossyScale.z; float aggrFactor = distanceToThreat / zSize; if (aggrFactor < _zombieStateMachine.sight && aggrFactor <= _zombieStateMachine.intelligence) { _zombieStateMachine.VisualThreat.Set(AITargetType.Visual_Light, other, other.transform.position, distanceToThreat); } } else if (other.CompareTag("AI Sound Emitter")) { SphereCollider soundTrigger = (SphereCollider)other; if (soundTrigger == null) { return; } Vector3 agentSensorePosition = _zombieStateMachine.sensorPosition; Vector3 soundPos; float soundRadius; AIState.ConvertSphereColliderToWorldSpace(soundTrigger, out soundPos, out soundRadius); float distanceToThreat = (soundPos - agentSensorePosition).magnitude; float distanceFactor = (distanceToThreat / soundRadius); distanceFactor += distanceFactor * (1.0f - _zombieStateMachine.hearing); if (distanceFactor > 1.0f) { return; } if (distanceToThreat < _zombieStateMachine.AudioThreat.distance) { _zombieStateMachine.AudioThreat.Set(AITargetType.Audio, other, soundPos, distanceToThreat); } } else if (other.CompareTag("AI Food") && curType.type != AITargetType.Visual_Player && curType.type != AITargetType.Visual_Light && _zombieStateMachine.satisfaction <= 0.9f && _zombieStateMachine.AudioThreat.type == AITargetType.None) { float distanceToThreat = (other.transform.position - _zombieStateMachine.sensorPosition).magnitude; if (distanceToThreat < _zombieStateMachine.VisualThreat.distance) { RaycastHit hitInfo; if (ColliderIsVisible(other, out hitInfo, _visualLayerMask)) { _zombieStateMachine.VisualThreat.Set(AITargetType.Visual_Food, other, other.transform.position, distanceToThreat); } } } } }
public void RpcInit(BallType type, ControlType ctrlType, int characterId, string nickname) { this.type = type; this.ctrlType = ctrlType; this.characterId = characterId; this.nickname = nickname; Debug.Log("We re running RPCInit character is _ " + this.characterId); Up = Vector3.up; //Set up drifty smoke smoke = Instantiate(prefabs.Smoke); smoke.target = this; smoke.DriftAudio = sounds.Brake; //Grab reference to Rigidbody rb = GetComponent <Rigidbody>(); //Set angular velocity (This is necessary for fast) rb.maxAngularVelocity = 1000f; //Set object name gameObject.name = nickname; //Set character if (CharacterId >= 0 && CharacterId < Data.ActiveData.Characters.Length) { SetCharacter(Data.ActiveData.Characters[CharacterId]); } //Create objects and components based on ball type if (type == BallType.Player && cameraBall == null && isLocalPlayer) { OmniCamera newCam = Instantiate(prefabs.Camera); newCam.Target = rb; newCam.CtrlType = ctrlType; PivotCamera oldCam = Instantiate(prefabs.OldCamera); oldCam.Target = rb; oldCam.CtrlType = ctrlType; //Create camera if (Data.ActiveData.GameSettings.useOldControls) { cameraBall = oldCam; newCam.gameObject.SetActive(false); ((PivotCamera)cameraBall).UseMouse = ctrlType == ControlType.Keyboard; } else { cameraBall = newCam; oldCam.gameObject.SetActive(false); } cameraBall.Target = rb; cameraBall.CtrlType = ctrlType; if (CameraCreatedEvent != null) { CameraCreatedEvent(this, new CameraCreationArgs(cameraBall, oldCam.gameObject, newCam.gameObject)); } } if (type == BallType.LobbyPlayer) { //Make the lobby camera follow this ball var cam = FindObjectOfType <LobbyCamera>(); if (cam) { cam.AddBall(this); } } if ((type == BallType.Player || type == BallType.LobbyPlayer && isLocalPlayer) && input == null) { //Create input component input = gameObject.AddComponent <BallControlInput>(); } if (type == BallType.AI) { //Create AI component var ai = gameObject.AddComponent <BallControlAI>(); ai.pathToFollow = FindObjectOfType <Path>(); //Create target for the AI AITarget pFollower = Instantiate(prefabs.AiTarget); pFollower.GetComponent <PathFollower>().path = ai.pathToFollow; pFollower.stupidness = ai.stupidness; pFollower.GetComponent <Patroller>().target = gameObject; ai.target = pFollower; } if (!isServer) { } }
//------------------------------------------ #endregion Properties #region Coroutines private IEnumerator <float> AICoroutine() { for (; ;) { if (AIEnabled) { if (CurrentAITarget != null) { bool res = false; try { res = CurrentAITarget.Check(this); } catch (Exception e) { Log.Warn($"AI Target check failure: {e}"); } if (res) { float delay = 0f; bool failure = false; try { delay = CurrentAITarget.Process(this); for (; SkippedTargets > 0; SkippedTargets--) { AITarget target = AIQueue.First.Value; AIQueue.RemoveFirst(); AIQueue.AddLast(target); } } catch (Exception e) { failure = true; Log.Warn($"Target processing failure: {e}"); } yield return(Timing.WaitForSeconds(delay)); if (CurrentAITarget.IsFinished || failure) { CurrentAITarget.IsFinished = false; CurrentAITarget = null; } } else { CurrentAITarget.IsFinished = false; CurrentAITarget = null; yield return(Timing.WaitForSeconds(Plugin.Instance.Config.AIIdleUpdateFrequency)); } } else { try { if (!AIQueue.IsEmpty()) { CurrentAITarget = AIQueue.First.Value; AIQueue.RemoveFirst(); AIQueue.AddLast(CurrentAITarget); } } catch (Exception e) { Log.Debug($"Error while scheduling AI target: {e}", Plugin.Instance.Config.VerboseOutput); } yield return(Timing.WaitForSeconds(Plugin.Instance.Config.AIIdleUpdateFrequency)); } } else { yield return(Timing.WaitForSeconds(Plugin.Instance.Config.AIIdleUpdateFrequency)); } } }
public BaseAIObservation(AITarget aiTarget) { //SetObjName("BaseAIObservation"); this.attributeLock = new object(); this.aiTarget = aiTarget; }
protected virtual void UpdateBasedOnTarget(AITarget closestTarget) { }
private void Awake() { selfTarget = GetComponent <AITarget>(); }
/// <summary> /// Main Update Loop /// </summary> /// <param name="_gameTime">Reference to current GameTime</param> public override void Update(GameTime _gameTime) { mMind.Update(_gameTime); base.Update(_gameTime); mTarget = null; }
public void SetAITarget(AITarget aiTarget) { this.aiTarget = aiTarget; }
public GoToAIAction(AITarget aiTarget) : base(aiTarget) { actionType = Enumeration.AiActionType.GoToAIAction; }
private void Start() { Up = Vector3.up; //Set up drifty smoke // smoke = Instantiate(prefabs.Smoke); // smoke.target = this; // smoke.DriftAudio = sounds.Brake; //Grab reference to Rigidbody rb = GetComponent <Rigidbody>(); //Set angular velocity (This is necessary for fast) rb.maxAngularVelocity = 1000f; //Set object name gameObject.name = nickname; //Set character if (CharacterId >= 0 && CharacterId < Data.ActiveData.Characters.Length) { SetCharacter(Data.ActiveData.Characters[CharacterId]); } //Create objects and components based on ball type if (type == BallType.Player) { IBallCamera camera; OmniCamera newCam = Instantiate(prefabs.Camera); newCam.Target = rb; newCam.CtrlType = ctrlType; PivotCamera oldCam = Instantiate(prefabs.OldCamera); oldCam.Target = rb; oldCam.CtrlType = ctrlType; //Create camera if (Data.ActiveData.GameSettings.useOldControls)//camara vieja { camera = oldCam; newCam.gameObject.SetActive(false); ((PivotCamera)camera).UseMouse = (ctrlType == ControlType.Keyboard); } else { camera = newCam; oldCam.gameObject.SetActive(false); } camera.Target = rb; camera.CtrlType = ctrlType; if (CameraCreated != null) { CameraCreated(this, new CameraCreationArgs(camera, oldCam.gameObject, newCam.gameObject)); } } if (type == BallType.LobbyPlayer) { //Make the lobby camera follow this ball var cam = FindObjectOfType <LobbyCameraLocal>(); if (cam) { cam.AddBall(this); } } if ((type == BallType.Player || type == BallType.LobbyPlayer)) { //Create input component input = gameObject.AddComponent <BallControlInputLocal>(); } if (type == BallType.AI) { //Create AI component var ai = gameObject.AddComponent <BallControlAILocal>(); ai.pathToFollow = FindObjectOfType <Path>(); //Create target for the AI AITarget pFollower = Instantiate(prefabs.AiTarget); pFollower.GetComponent <PathFollower>().path = ai.pathToFollow; pFollower.stupidness = ai.stupidness; pFollower.GetComponent <Patroller>().target = gameObject; ai.target = pFollower; } }
public static void RegisterTarget(AITarget target) { targets.Add(target); }
public void ResetTarget() { _currentTarget = null; }
//NPC format //name: SomeName //health: -1 //role: Scientist //scale: [1, 1, 1] //inventory: [KeycardO5, GunLogicer] //item_held: GunLogicer //root_node: default_node.yml //god_mode: false //is_exclusive: true //process_scp_logic: false //affect_summary: false //events: [] //ai_enabled: false //ai: [] public static Npc CreateNPC(Vector3 pos, Vector2 rot, string path) { try { var input = new StringReader(File.ReadAllText(Path.Combine(Config.NPCs_root_path, path))); var deserializer = new DeserializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) // Workaround to remove YamlAttributesTypeInspector .WithTypeInspector(inner => inner, s => s.InsteadOf <YamlAttributesTypeInspector>()) .WithTypeInspector( inner => new YamlAttributesTypeInspector(inner), s => s.Before <NamingConventionTypeInspector>() ) .Build(); NpcSerializationInfo raw_npc = deserializer.Deserialize <NpcSerializationInfo>(input); Npc n = CreateNPC(pos, rot, new Vector3(raw_npc.Scale[0], raw_npc.Scale[1], raw_npc.Scale[2]), raw_npc.Role, ItemType.None, raw_npc.Name, raw_npc.RootNode); foreach (ItemType type in raw_npc.Inventory) { Log.Debug($"Added item: {type:g}"); n.TakeItem(type); } n.ItemHeld = raw_npc.ItemHeld; n.NPCPlayer.IsGodModeEnabled = raw_npc.GodMode; n.IsExclusive = raw_npc.IsExclusive; n.SaveFile = path; n.AffectRoundSummary = raw_npc.AffectSummary; n.ProcessSCPLogic = raw_npc.ProcessScpLogic; int health = raw_npc.Health; if (health > 0) { n.NPCPlayer.MaxHealth = health; n.NPCPlayer.Health = health; } Log.Info("Parsing events..."); foreach (NpcEventSerializationInfo info in raw_npc.Events) { Dictionary <NodeAction, Dictionary <string, string> > actions_mapping = new Dictionary <NodeAction, Dictionary <string, string> >(); foreach (NpcNodeWithArgsSerializationInfo action in info.Actions) { NodeAction act = NodeAction.GetFromToken(action.Token); if (act != null) { actions_mapping.Add(act, action.Args); } else { Log.Error($"Failed to event action: {info.Token} (invalid token)"); } } n.Events.Add(info.Token, actions_mapping); } n.AIEnabled = raw_npc.AiEnabled; foreach (NpcNodeWithArgsSerializationInfo info in raw_npc.Ai) { AI.AITarget act = AITarget.GetFromToken(info.Token); if (act != null) { Log.Debug($"Recognized ai target: {act.Name}", Plugin.Instance.Config.VerboseOutput); act.Arguments = info.Args; if (act.Verified) { n.AIQueue.AddLast(act); } else { Log.Warn($"Failed to verify config or construct {act.Name}, it will be skipped!"); } } else { Log.Error($"Failed to parse ai node: {info.Token} (invalid token)"); } } return(n); } catch (Exception e) { Log.Error($"Failed to load NPC from {path}: {e}"); return(null); } }
public EnemyAIObservation(AITarget aiTarget) : base(aiTarget) { }
protected virtual bool ShouldAttack(AITarget other) { return(AITarget.FactionsHostile(selfTarget.alignment, other.alignment) && (selfTarget.alignment != Alignment.Wildcard || selfTarget.attackingEnemies.Contains(other.gameObject))); }
public AttackAIAction(AITarget aiTarget) : base(aiTarget) { actionType = Enumeration.AiActionType.AttackAIAction; }