public void Init()
        {
            var files = Directory.GetFiles(".\\Schemas");

            {
                var s = new SchemaNode();

                s.Load("Schemas/rhscope.xml");
            }

            foreach (var file in files)
            {
                var l = file.Substring(file.LastIndexOf("\\") + 1).Replace(".xml", "");


                var s = new SchemaNode();
                if (!SchemaMap.ContainsKey(l))
                {
                    s.Load("Schemas/" + l + ".xml");
                }
            }

            foreach (var schemaMapValue in SchemaMap.Values)
            {
                schemaMapValue.Init();
            }

            LoadBinary();
        }
        private bool HandleUnexpectedChildren(SchemaNode schemaNode, ScriptObject scriptObject, string s, bool rhs,
                                              int index)
        {
            if (schemaNode.TypeList.Contains("value"))
            {
                return(true);
            }

            return(false);
        }
        private void ReadSchemas(BinaryReader reader)
        {
            var num = reader.ReadInt32();

            for (var x = 0; x < num; x++)
            {
                var node = new SchemaNode();

                node.Read(reader);
                SchemaNode.CloneHashMap[node.GetHashCodeL()] = node;
            }
        }
Exemple #4
0
        public ScriptObject(ScriptObject parent, ScriptParsedSegment seg, SchemaNode schema = null)
        {
            if (seg == null)
            {
                return;
            }
            Op      = seg.op;
            IsBlock = seg.isBlock;
            if (parent == null)
            {
                Core.Instance.DeferedPostInitializationListNext.Add(this);
                Core.Instance.DeferedInitializationList.Add(this);
            }

            Name      = seg.name;
            Filename  = seg.filename;
            LineStart = seg.lineNumbers.First();
            LineEnd   = seg.lineNumbers.Last();
            Parent    = parent;
            Library   = Core.Instance.LoadingCK3Library;

            if (LineStart == ScriptObjectBehaviourManager.BreakpointLine &&
                Topmost.Filename.ToRelativeFilename().Contains(ScriptObjectBehaviourManager.BreakpointFile))
            {
            }

            lhsSchema = schema;

            foreach (var scriptParsedSegment in seg.children)
            {
                ScriptObject so = null;
                if (scriptParsedSegment.value.Count > 0)
                {
                    so = ScriptValueParser.Instance.ParseScriptValue(this, scriptParsedSegment);
                }
                else
                {
                    so = ScriptObjectFactory.Instance.CreateScriptObject(Context, scriptParsedSegment, this,
                                                                         Namespace);
                }

                Children.Add(so);

                OnPostInitializeChild(so);
            }
        }
        private SchemaNode FindScriptList(ScriptObject obj, string s, bool allowScriptList, bool rhs, ScopeType scope,
                                          int index, List <SchemaNode> candidates)
        {
            var clone  = new SchemaNode();
            var schema = SchemaManager.Instance.GetSchema("scriptlist");

            var f = schema.FindChild(obj, s, false, rhs, scope, index, candidates);

            if (f == null)
            {
                return(null);
            }

            f.copyTo(clone);
            clone.inherits.UnionWith(inherits);
            clone.inheritsIds.UnionWith(inheritsIds);
            return(clone);
        }
        public void copyTo(SchemaNode dest)
        {
            dest.children    = new HashSet <SchemaNode>(children);
            dest.inheritsIds = new HashSet <string>();
            dest.inheritsIds.UnionWith(inheritsIds);
            dest.inherits = new HashSet <SchemaNode>(inherits);
            dest.scopes   = new List <ScopeType>(scopes);

            dest.namesFrom    = namesFrom;
            dest.name         = name;
            dest.category     = category;
            dest.targetScope  = targetScope;
            dest.doc          = doc;
            dest.function     = function;
            dest.typeList     = typeList;
            dest.requiresData = requiresData;
            dest.globalLink   = globalLink;
            dest.wildcard     = wildcard;
            dest.allowScopes  = allowScopes;
        }
        private void DetermineBehaviourScope(ScriptObject obj, ScriptObjectBehaviourData data)
        {
            if (obj.Parent != null)
            {
                var parentScope = obj.Parent.GetScopeType();

                if (data.lhs != null)
                {
                    int        scopeColorLength = 0;
                    string[]   scopeLine        = data.lhs.Split('.');
                    ScopeType  type             = parentScope;
                    SchemaNode node             = obj.Parent.lhsSchema;
                    if (node != null)
                    {
                        List <SchemaNode> candidates = new List <SchemaNode>();

                        if (obj.Parent.lhsSchema != null && !obj.Parent.lhsSchema.allowScopes)
                        {
                            scopeLine = new[] { data.lhs };
                        }

                        for (int i = 0; i < scopeLine.Length; i++)
                        {
                            string scopeChange = scopeLine[i];

                            node = node.FindChild(obj, scopeChange, scopeLine.Length == 1, false, type, i,
                                                  i == scopeLine.Length - 1 ? candidates : null);

                            if (node != null && (node.function == "event_target" || node.function == "script_list"))
                            {
                                scopeColorLength += scopeChange.Length;
                                if (i < scopeLine.Length - 1)
                                {
                                    scopeColorLength++;
                                }
                            }

                            // failed
                            if (node == null)
                            {
                                break;
                            }

                            type = node.targetScope;
                        }

                        data.candidates = candidates;
                    }



                    // no effect or trigger blocks after '.'s
                    if (node != null &&
                        (node.TypeList.Contains("block") || node.TypeList.Contains("function") ||
                         node.function == "effect") && scopeLine.Length > 1)
                    {
                        node = null;
                    }


                    obj.lhsSchema = node;
                    if (obj.lhsSchema != null)
                    {
                        if (obj.lhsSchema.TypeList.Contains("value"))
                        {
                            obj.lhsSchema.inheritsIds.Add("value");
                            obj.lhsSchema.inherits.Add(SchemaManager.Instance.GetSchema("value"));
                        }

                        data.lhsScopeTextColorLength = scopeColorLength;
                        if (obj.lhsSchema.function == "trigger")
                        {
                            ScopeType scope;
                            bool      foundScope = false;
                            foreach (var s in node.TypeList)
                            {
                                if (Enum.TryParse(s, out scope))
                                {
                                    if (scope != ScopeType.value)
                                    {
                                        obj.SetScopeType(scope);
                                        foundScope = true;
                                    }
                                }
                            }

                            if (!foundScope)
                            {
                                if (obj.lhsSchema.targetScope != ScopeType.any &&
                                    obj.lhsSchema.targetScope != ScopeType.none &&
                                    obj.lhsSchema.targetScope != ScopeType.value)
                                {
                                    obj.SetScopeType(obj.lhsSchema.targetScope);
                                }
                            }
                        }
                        else if (obj.lhsSchema.function == "effect")
                        {
                            ScopeType scope;
                            bool      foundScope = false;
                            foreach (var s in node.TypeList)
                            {
                                if (Enum.TryParse(s, out scope))
                                {
                                    if (scope != ScopeType.value)
                                    {
                                        obj.SetScopeType(scope);
                                        foundScope = true;
                                    }
                                }
                            }

                            if (!foundScope)
                            {
                                if (obj.lhsSchema.targetScope != ScopeType.any &&
                                    obj.lhsSchema.targetScope != ScopeType.none &&
                                    obj.lhsSchema.targetScope != ScopeType.value)
                                {
                                    obj.SetScopeType(obj.lhsSchema.targetScope);
                                }
                            }
                        }
                        else if (obj.lhsSchema.function == "event_target")
                        {
                            if (obj.lhsSchema.targetScope != ScopeType.any &&
                                obj.lhsSchema.targetScope != ScopeType.none &&
                                obj.lhsSchema.targetScope != ScopeType.value)
                            {
                                obj.SetScopeType(obj.lhsSchema.targetScope);
                            }
                        }
                        else if (obj.lhsSchema.function == "script_list")
                        {
                            if (obj.lhsSchema.targetScope != ScopeType.any &&
                                obj.lhsSchema.targetScope != ScopeType.none &&
                                obj.lhsSchema.targetScope != ScopeType.value)
                            {
                                obj.SetScopeType(obj.lhsSchema.targetScope);
                            }
                        }
                    }
                    else
                    {
                        if (data.ParentData.ChildrenAreValueRange)
                        {
                            data.ValueFound = true;
                        }
                        else
                        {
                            data.lhsError = "Unexpected";
                        }
                    }
                }

                if (data.rhs != null && obj.lhsSchema != null)
                {
                    string[]  scopeLine = data.rhs.Split('.');
                    ScopeType type      = parentScope;
                    data.deepestRHSScopeFound = type;
                    SchemaNode node             = obj.Parent.lhsSchema;
                    int        scopeColorLength = 0;
                    data.foundRHSScope = true;
                    for (int i = 0; i < scopeLine.Length; i++)
                    {
                        string scopeChange = scopeLine[i];

                        var prev = node;
                        node = node.FindChild(obj, scopeChange, false, true, type, i, null);

                        if (node != null && (node.function == "event_target" || node.function == "script_list") &&
                            node.name != "yes" && node.name != "no")
                        {
                            scopeColorLength += scopeChange.Length;
                            if (i < scopeLine.Length - 1)
                            {
                                scopeColorLength++;
                            }
                        }


                        // failed
                        if (node == null)
                        {
                            data.foundRHSScope = false;
                            if (prev.targetScope != ScopeType.any && prev.targetScope != ScopeType.none)
                            {
                                data.deepestRHSScopeFound = prev.targetScope;
                            }
                            break;
                        }

                        type = node.targetScope;
                    }

                    obj.rhsSchema = node;
                    if (obj.rhsSchema != null)
                    {
                        data.rhsScopeTextColorLength = scopeColorLength;
                        if (obj.rhsSchema.function == "trigger")
                        {
                            ScopeType scope;
                            bool      foundScope = false;
                            foreach (var s in node.TypeList)
                            {
                                if (Enum.TryParse(s, out scope))
                                {
                                    data.rhsScope = (scope);
                                    foundScope    = true;
                                }
                            }

                            if (!foundScope)
                            {
                                if (obj.rhsSchema.targetScope != ScopeType.any &&
                                    obj.rhsSchema.targetScope != ScopeType.none)
                                {
                                    data.rhsScope = (obj.rhsSchema.targetScope);
                                }
                            }
                        }
                        else if (obj.lhsSchema.function == "effect")
                        {
                            ScopeType scope;
                            bool      foundScope = false;
                            foreach (var s in node.TypeList)
                            {
                                if (Enum.TryParse(s, out scope))
                                {
                                    data.rhsScope = (scope);
                                    foundScope    = true;
                                }
                            }

                            if (!foundScope)
                            {
                                if (obj.rhsSchema.targetScope != ScopeType.any &&
                                    obj.rhsSchema.targetScope != ScopeType.none)
                                {
                                    data.rhsScope = (obj.rhsSchema.targetScope);
                                }
                            }
                        }
                        else if (obj.rhsSchema.function == "event_target")
                        {
                            if (obj.rhsSchema.targetScope != ScopeType.any &&
                                obj.rhsSchema.targetScope != ScopeType.none)
                            {
                                data.rhsScope = (obj.rhsSchema.targetScope);
                            }
                        }
                        else if (obj.rhsSchema.function == "script_list")
                        {
                            if (obj.rhsSchema.targetScope != ScopeType.any &&
                                obj.rhsSchema.targetScope != ScopeType.none)
                            {
                                data.rhsScope = (obj.rhsSchema.targetScope);
                            }
                        }
                        else
                        {
                            if (!ValidateValue(obj, data))
                            {
                                data.rhsError = "Unexpected";
                            }
                        }
                    }
                    else
                    {
                        if (!ValidateValue(obj, data))
                        {
                            data.rhsError = "Unexpected";
                        }
                    }
                }
                else
                {
                    if (data.rhs == null && obj.Children.Count > 0 && obj.lhsSchema != null &&
                        obj.lhsSchema.TypeList.Contains("value"))
                    {
                        // look for alternative value types (scripted values / ranges)
                        if (obj.Children.Count == 2)
                        {
                            string a = obj.Children[0].Name;
                            string b = obj.Children[1].Name;

                            float range = 0;

                            if (Single.TryParse(a, out range) && Single.TryParse(b, out range))
                            {
                                data.ChildrenAreValueRange = true;
                            }
                        }
                    }
                    else if (data.rhs == null && data.lhsNamedFrom != null)
                    {
                        var nameSet =
                            EnumManager.Instance.GetEnums(data.lhsNamedFrom,
                                                          true); //Core.Instance.GetNameSetFromEnumType(type, true);

                        if (nameSet.Contains(data.lhs))
                        {
                            data.ReferencedObject = Core.Instance.Get(data.lhs, data.lhsNamedFrom);
                            data.ReferenceValid   = true;
                            data.NameIsReference  = true;
                        }
                    }
                }
            }
        }
        private ScopeType GetScopeChangeFromData(ScriptObject obj, SchemaNode node, string name, string data,
                                                 bool rhs, ScopeType scope, out bool success)
        {
            success = false;
            if (name == "scope")
            {
                var results = new List <ScriptScope>();
                obj.Topmost.GetValidScriptScopesInit(results, true, ScopeFindType.Any);
                foreach (var objScriptScope in results)
                {
                    if (objScriptScope.Name == data)
                    {
                        success = true;
                        return(objScriptScope.To);
                    }
                }
            }

            if (name == "var")
            {
                if (VariableStore.Instance.unsortedScopedVariables.ContainsKey(data))
                {
                    var results = VariableStore.Instance.unsortedScopedVariables[data]
                                  .Where(a => a.InsideScope == scope);

                    if (results.Any())
                    {
                        success = true;
                        return(results.First().VarType);
                    }
                }
            }

            if (name == "cp")
            {
                if (EnumManager.Instance.GetEnums("council_position", true).Contains(data))
                {
                    success = true;
                    return(ScopeType.character);
                }
            }

            if (name == "culture_group")
            {
                if (EnumManager.Instance.GetEnums("culture_group", true).Contains(data))
                {
                    success = true;
                    return(ScopeType.culture_group);
                }
            }

            if (name == "culture")
            {
                if (EnumManager.Instance.GetEnums("culture", true).Contains(data))
                {
                    success = true;
                    return(ScopeType.culture);
                }
            }

            if (name == "global_var")
            {
                if (VariableStore.Instance.globalVariables.ContainsKey(data))
                {
                    var results = VariableStore.Instance.globalVariables[data];

                    {
                        success = true;
                        return(results.VarType);
                    }
                }
            }

            if (name == "local_var")
            {
                var results = new List <Variable>();
                obj.Topmost.GetValidLocalVariablesInit(results);
                foreach (var objScriptScope in results)
                {
                    if (objScriptScope.Name == data)
                    {
                        success = true;
                        return(objScriptScope.VarType);
                    }
                }
            }

            return(obj.GetScopeType());
        }
        public SchemaNode FindChild(ScriptObject obj, string name, bool allowScriptList, bool rhs, ScopeType scope,
                                    int index, List <SchemaNode> candidates)
        {
            string data = null;

            if (name.Contains(":"))
            {
                data = name.Split(':')[1];
                name = name.Split(':')[0];
            }

            var c = Children;

            if (allowScriptList && !IsNonScriptedListTag(name) &&
                (name.StartsWith("any_") || name.StartsWith("every_") || name.StartsWith("random_") ||
                 name.StartsWith("ordered_")))
            {
                var v = FindScriptList(obj, name, allowScriptList, rhs, scope, index, candidates);

                if (v != null)
                {
                    return(v);
                }
            }

            SchemaNode found = null;

            var list = c.Where(a => a.name == name && (!a.rightHandOnly || rhs)).ToList();

            if (list.Count > 0)
            {
                foreach (var schemaNode in list)
                {
                    var f = schemaNode;

                    if (f.requiresData)
                    {
                        if (data == null)
                        {
                            continue;
                        }

                        bool success;
                        var  scopeType = GetScopeChangeFromData(obj, f, name, data, rhs, scope, out success);
                        if (success)
                        {
                            var clone = new SchemaNode();
                            f.copyTo(clone);

                            if (rhs)
                            {
                                clone.inheritsIds.Add("trigger");
                                clone.inherits.Add(SchemaManager.Instance.GetSchema("trigger"));
                            }
                            else
                            {
                                clone.inherits.UnionWith(inherits);
                                clone.inheritsIds.UnionWith(inheritsIds);
                                if (obj.Parent.lhsSchema != null)
                                {
                                    clone.inherits.UnionWith(obj.Parent.lhsSchema.inherits);
                                    clone.inheritsIds.UnionWith(obj.Parent.lhsSchema.inheritsIds);
                                }
                            }

//                            clone.inherits = clone.inherits.Distinct().ToList();
                            clone.targetScope = scopeType;
                            found             = clone; //return clone;

                            clone.Serialize();

                            if (candidates != null)
                            {
                                candidates.Add(clone);
                            }
                        }

                        continue;
                    }

                    if (f.function == "event_target" && data == null)
                    {
                        var clone = new SchemaNode();
                        f.copyTo(clone);
                        clone.inherits.UnionWith(inherits);
                        //   clone.inherits = clone.inherits.Distinct().ToList();
                        clone.inheritsIds.UnionWith(inheritsIds);
                        if (f.targetScope == ScopeType.none)
                        {
                            clone.targetScope = scope;
                        }

                        if (found == null)
                        {
                            found = clone;
                        }
                        //    if (candidates != null)
                        //        candidates.Add(clone);
                        clone.Serialize();
                    }
                    else if (f.function == "script_list" && data == null)
                    {
                        if (f != null && rhs && f.TypeList.Contains("block"))
                        {
                            continue;
                        }

                        if (found == null)
                        {
                            found = f;
                        }
                        //     if (candidates != null)
                        //       candidates.Add(f);
                    }

                    // don't allow blocks on rhs
                    if (f != null && rhs && f.TypeList.Contains("block"))
                    {
                        continue;
                    }

                    if (obj.Children.Count > 0 && f.Children.Count == 0)
                    {
                        if (!HandleUnexpectedChildren(schemaNode, obj, name, rhs, index))
                        {
                            continue;
                        }
                    }

                    if (!obj.IsBlock && f.Children.Count > 0 && !f.TypeList.Contains("value"))
                    {
                        if (candidates != null)
                        {
                            candidates.Add(f);
                        }
                        continue;
                    }

                    if (found == null)
                    {
                        found = f;
                    }
                    if (candidates != null)
                    {
                        candidates.Add(f);
                    }
                }
            }

            if (found != null)
            {
                return(found);
            }

            if (rhs && obj.lhsSchema != null && obj.lhsSchema.TypeList.Contains("value"))
            {
                var sv = Core.Instance.Get(ScriptContext.ScriptedValues, name);
                if (sv != null)
                {
                    return new SchemaNode
                           {
                               typeList = "value", name = sv.Name, targetScope = ScopeType.value, function = "effect"
                           }
                }
                ;
            }

            /*  if(rhs && !inheritsIds.Contains("trigger") && id!="trigger")
             * {
             *    // we get to try a trigger...
             *    SchemaNode clone = new SchemaNode();
             *    copyTo(clone);
             *    clone.children.Clear();
             *    clone.inheritsIds.Add("trigger");
             *    clone.inherits.Add(SchemaManager.Instance.GetSchema("trigger"));
             *    return clone.FindChild(obj, name, allowScriptList, rhs, scope, index);
             * }*/

            var namesFrom = c.Where(a => a.namesFrom != null).ToList();

            if (namesFrom.Count > 0)
            {
                foreach (var schemaNode in namesFrom)
                {
                    if (schemaNode.namesFrom == "value")
                    {
                        int num;

                        if (int.TryParse(name, out num))
                        {
                            return(schemaNode);
                        }
                    }
                    else
                    {
                        var e = EnumManager.Instance.GetEnums(schemaNode.namesFrom);
                        if (e.Count > 0)
                        {
                            if (e.Contains(name))
                            {
                                obj.BehaviourData.lhsNamedFrom = schemaNode.namesFrom;
                                return(schemaNode);
                            }
                        }
                    }
                }
            }

            return(found);
        }
        public void LoadNode(XmlNode node, SchemaNode parent = null)
        {
            id = loadString(node, "id");

            name      = loadString(node, "name");
            typeList  = loadString(node, "type");
            namesFrom = loadString(node, "namesFrom");
            category  = loadString(node, "category");
            schema    = loadString(node, "schema");

            var scopes   = loadString(node, "scope");
            var inherits = loadString(node, "inherits");

            if (node.Name == "Localized")
            {
                typeList = "localized";
            }
            else if (node.Name == "Effect")
            {
                inherits = "effect";
                typeList = inherits;
            }
            else if (node.Name == "Trigger")
            {
                inherits = "trigger";
                typeList = inherits;
            }
            else if (node.Name == "ModifierStack")
            {
                inherits = "modifierStack";
                typeList = inherits;
            }
            else if (node.Name == "Bool")
            {
                typeList = "bool";
            }
            else if (node.Name == "Value")
            {
                typeList = "value";
            }
            else if (node.Name != "Child")
            {
                typeList = node.Name.ToLower();
            }

            if (name == null)
            {
                if (typeList == "effect_group")
                {
                }

                name = typeList;
            }

            if (typeList == null)
            {
                typeList = "none";
            }

            if (inherits != null)
            {
                var i = inherits.Split(',');

                foreach (var s in i)
                {
                    inheritsIds.Add(s.Trim());
                }
            }

            if (scopes != null)
            {
                var scps = scopes.Split(',');

                foreach (var scp in scps)
                {
                    ScopeType scopeEnum;
                    if (Enum.TryParse(scp, out scopeEnum))
                    {
                        this.scopes.Add(scopeEnum);
                    }
                }
            }
            else
            {
                this.scopes.Add(ScopeType.inheritparent);
            }


            var       targetScope = loadString(node, "targetScope");
            ScopeType tsv;

            Enum.TryParse(targetScope, out tsv);

            this.targetScope = tsv;

            function = loadString(node, "function");

            requiresData  = loadBool(node, "requiresData", false);
            globalLink    = loadBool(node, "globalLink", false);
            wildcard      = loadBool(node, "wildcard", false);
            allowScopes   = loadBool(node, "allowScopes", true);
            rightHandOnly = loadBool(node, "rightHandOnly", false);
            avoidRed      = loadBool(node, "avoidRed", false);

            if (typeList.Contains("value"))
            {
                inheritsIds.Add("value");
            }
            var c = node.FirstChild;

            while (c != null)
            {
                if (c is XmlComment)
                {
                    c = c.NextSibling;
                    continue;
                }

                var cn = new SchemaNode();
                cn.LoadNode(c, this);


                if (cn.function == "script_list")
                {
                    var any = new SchemaNode();
                    cn.copyTo(any);
                    any.name = "any_" + cn.name;
                    children.Add(any);

                    any.inheritsIds.Add("scriptlistTriggerInherits");
                    any.inheritsIds.Add("trigger");

                    var random = new SchemaNode();
                    cn.copyTo(random);
                    random.name = "random_" + cn.name;
                    children.Add(random);

                    random.inheritsIds.Add("scriptlistEffectInherits");
                    random.inheritsIds.Add("effect");

                    var every = new SchemaNode();
                    cn.copyTo(every);
                    every.name = "every_" + cn.name;
                    children.Add(every);

                    every.inheritsIds.Add("scriptlistEffectInherits");
                    every.inheritsIds.Add("effect");

                    var ordered = new SchemaNode();
                    cn.copyTo(ordered);
                    ordered.name = "ordered_" + cn.name;
                    children.Add(ordered);

                    ordered.inheritsIds.Add("scriptlistEffectInherits");
                    ordered.inheritsIds.Add("effect");
                }
                else
                {
                    children.Add(cn);
                }

                c = c.NextSibling;
            }


            if (children.Count > 0 && !children.Any(a => a.name == "scope"))
            {
                var cc = SchemaManager.Instance.GetSchema("rhscope").children;
                children.UnionWith(cc);
            }

            if (id != null)
            {
                SchemaManager.Instance.AddSchema(id, this);
            }

            if (node.Name == "Localized" && parent != null)
            {
                var clone = new SchemaNode();
                copyTo(clone);
                clone.inheritsIds.Add("localized");
                parent.children.Add(clone);
                clone.Serialize();
            }

            Serialize(false);
        }
 public void AddSchema(string id, SchemaNode schemaNode)
 {
     SchemaMap[id] = schemaNode;
 }