private bool CheckCompatibilityOfSides(ScriptObject obj, ScriptObjectBehaviourData data)
        {
            bool foundTypeMatch = false;

            if (obj.rhsSchema != null)
            {
                foreach (var s in obj.lhsSchema.TypeList)
                {
                    if (obj.rhsSchema.TypeList.Contains(s))
                    {
                        foundTypeMatch = true;
                    }
                }
            }

            if (obj.rhsSchema != null && foundTypeMatch)
            {
                return(true);
            }

            if (obj.lhsSchema.TypeList.Contains("any"))
            {
                return(true);
            }

            // can't determine type of rhs, so figure that out in validate value
            if (obj.rhsSchema == null)
            {
                return(true);
            }

            return(false);
        }
        private string InferTypeFromRHS(ScriptObject scriptObject, ScriptObjectBehaviourData data, string type)
        {
            string expected = type;

            if (expected == null)
            {
                expected = scriptObject.lhsSchema.targetScope.ToString();
            }

            if (expected == "value")
            {
                float val;
                if (Single.TryParse(data.rhs, out val))
                {
                    return(expected);
                }
            }

            if (data.rhs == "yes" || data.rhs == "no")
            {
                return("bool");
            }

            return(expected);
        }
Пример #3
0
        public void CompleteScopedVar(ScriptObject scriptObject, ScriptObjectBehaviourData data, ScopeType scopeType)
        {
            var name = scriptObject.GetChildStringValue("name");

            if (!unsortedScopedVariables.ContainsKey(name))
            {
                return;
            }

            foreach (var variable in unsortedScopedVariables[name])
            {
                if (variable.Declared == scriptObject)
                {
                    variable.InsideScope = scopeType;
                }
            }
        }
        private bool ValidateValue(ScriptObject scriptObject, ScriptObjectBehaviourData data)
        {
            if (!CheckCompatibilityOfSides(scriptObject, data))
            {
                return(false);
            }

            foreach (var s in scriptObject.lhsSchema.TypeList)
            {
                string type = scriptObject.rhsSchema == null?InferTypeFromRHS(scriptObject, data, s) : s;

                string ltype = s;
                if (ltype == null)
                {
                    ltype = scriptObject.lhsSchema.targetScope.ToString();
                }
                if (type != ltype)
                {
                    continue;
                }

                // primitive or scope
                if (type == "value")
                {
                    float val;
                    if (Single.TryParse(data.rhs, out val))
                    {
                        return(true);
                    }

                    var nameSet =
                        EnumManager.Instance.GetEnums("value",
                                                      true); //Core.Instance.GetNameSetFromEnumType(type, true);

                    var v = data.rhs;

                    if (v != null && v.Contains("."))
                    {
                        v = v.Substring(v.LastIndexOf(".") + 1);
                    }

                    if (nameSet.Contains(v))
                    {
                        data.ReferencedObject = Core.Instance.Get(v, type);
                        data.ReferenceValid   = true;
                        return(true);
                    }

                    var triggerSchema = SchemaManager.Instance.GetSchema("trigger");

                    var results = triggerSchema.Children.Where(a =>
                                                               a.name == v && (a.scopes.Contains(data.deepestRHSScopeFound) ||
                                                                               a.scopes.Contains(ScopeType.none)));

                    if (results.Count() > 0)
                    {
                        data.ReferenceValid = true;
                        return(true);
                    }
                }

                if (type == "any" || type == "string")
                {
                    data.ReferenceValid = true;
                    return(true);
                }

                if (type == "flag")
                {
                    if (data.rhs.StartsWith("flag:"))
                    {
                        data.ReferenceValid = true;
                        return(true);
                    }
                }

                else if (type == "scope")
                {
                    List <ScriptScope> results = new List <ScriptScope>();
                    scriptObject.Topmost.GetValidScriptScopesInit(results, true, ScopeFindType.Any);
                    foreach (var topmostScriptScope in results)
                    {
                        // its a scope!
                        if (topmostScriptScope.Name == data.rhs)
                        {
                            data.ReferenceValid = true;
                            return(true);
                        }
                    }
                }
                else if (type == "var")
                {
                    data.ReferenceValid = true;
                    return(true);
                }
                else if (type == "global_var")
                {
                    data.ReferenceValid = true;
                    return(true);
                }
                else if (type == "local_var")
                {
                    data.ReferenceValid = true;
                    return(true);
                }
                else if (type == "bool")
                {
                    if (data.rhs == "yes" || data.rhs == "no")
                    {
                        data.ReferenceValid = true;
                        return(true);
                    }
                }
                else if (type == "localized")
                {
                    if (Core.Instance.HasLocalizedText(data.rhs.Replace("\"", "")))
                    {
                        data.ReferenceValid = true;
                        return(true);
                    }
                }
                else if (type == "trigger_localization")
                {
                    if (Core.Instance.GetNameSet("trigger_localization", false).Contains(data.rhs.Replace("\"", "")))
                    {
                        data.ReferenceValid = true;
                        return(true);
                    }
                }
                else if (type == scriptObject.GetScopeType().ToString())
                {
                    if (!data.foundRHSScope)
                    {
                        continue;
                    }

                    data.ReferenceValid = true;
                    return(true);
                }

                {
                    var nameSet =
                        EnumManager.Instance.GetEnums(type, true); //Core.Instance.GetNameSetFromEnumType(type, true);

                    if (nameSet.Contains(data.rhs))
                    {
                        data.ReferencedObject = Core.Instance.Get(data.rhs, type);
                        data.ReferenceValid   = true;
                        return(true);
                    }
                }
            }

            return(false);
        }
        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;
                        }
                    }
                }
            }
        }
        public void ProcessObject(BinaryWriter writer, BinaryReader reader, ScriptObject obj)
        {
            if (obj.Name == "root")
            {
                obj.SetScopeType(obj.Topmost.GetScopeType());
            }



            BreakpointLine = 30;

            BreakpointFile = "events/kill_them_all_events/kill_them_all_events.txt";


            if (obj.Filename.ToRelativeFilename().Contains(BreakpointFile))
            {
            }

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

            var data = new ScriptObjectBehaviourData();

            data.ScriptObject = obj;
            data.ScopeType    = obj.GetScopeType();

            if (obj.Parent != null)
            {
                data.ParentData = obj.Parent.BehaviourData;
            }

            obj.BehaviourData = data;

            data.lhs = obj.Name;
            if (obj.Parent != null)
            {
                data.ParentData = obj.Parent.BehaviourData;
            }

            if (data.lhs == "set_variable")
            {
                VariableStore.Instance.CompleteScopedVar(obj, data, obj.Parent.GetScopeType());
            }

            data.rhs     = obj.GetStringValue();
            data.IsBlock = obj.IsBlock;

            if (reader == null)
            {
                DetermineBehaviourScope(obj, data);
            }
            else
            {
                ReadBehaviour(reader, obj);
            }

            if (data.lhs.Contains("var:"))
            {
                if (!VariableStore.Instance.HasScopedVariableComplete(data.lhs, obj.GetScopeType()) && obj.DeferedCount < 1)
                {
                    obj.DeferedCount++;
                    Core.Instance.BehaviourRecalculateList.Add(obj);
                }
            }

            if (data.rhs != null && data.rhs.Contains("var:"))
            {
                if (!VariableStore.Instance.HasScopedVariableComplete(data.rhs.Substring(data.rhs.IndexOf("var:")),
                                                                      data.deepestRHSScopeFound) && obj.DeferedCount < 1)
                {
                    obj.DeferedCount++;
                    Core.Instance.BehaviourRecalculateList.Add(obj);
                }
            }


            if (writer != null)
            {
                WriteBehaviour(writer, obj);
            }

            foreach (var scriptObject in obj.Children)
            {
                scriptObject.PostInitialize(writer, reader);
            }
        }