//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 static void Register(AITarget cond) { registry.Add(cond.Name, cond); Log.Debug($"Registered AITarget token: {cond.Name}", Plugin.Instance.Config.VerboseOutput); }