예제 #1
0
 public override bool OnMoveOver(Mobile m)
 {
     if (XmlScript.HasTrigger(this, TriggerName.onMoveOver) && UberScriptTriggers.Trigger(this, m, TriggerName.onMoveOver))
     {
         return(false);
     }
     return(true);
 }
예제 #2
0
 public override void OnDelete()
 {
     if (XmlScript.HasTrigger(this, TriggerName.onDelete))
     {
         UberScriptTriggers.Trigger(this, this.RootParentEntity as Mobile, TriggerName.onDelete);
     }
     base.OnDelete();
 }
예제 #3
0
 public override void OnMovement(Mobile m, Point3D oldLocation)
 {
     base.OnMovement(m, oldLocation);
     if (XmlScript.HasTrigger(this, TriggerName.onNearbyMove))
     {
         UberScriptTriggers.Trigger(this, m, TriggerName.onNearbyMove);
     }
 }
예제 #4
0
 public override void OnSpeech(SpeechEventArgs e)
 {
     if (UberScriptTriggers.Trigger(this, e.Mobile, TriggerName.onSpeech, null, e.Speech))
     {
         e.Handled = true;
         return;
     }
 }
예제 #5
0
        public override void OnRemoved(object parent)
        {
            if (parent is Mobile)
            {
                UberScriptTriggers.Trigger(this, (Mobile)parent, TriggerName.onUnequip);
            }
            else if (parent is Item)
            {
                Item parentItem = (Item)parent;
                UberScriptTriggers.Trigger(this, parentItem.RootParentEntity as Mobile, TriggerName.onRemove, parentItem);
            }

            Server.Engines.XmlSpawner2.XmlAttach.CheckOnRemoved(this, parent);
            base.OnRemoved(parent);
        }
예제 #6
0
        public void OnExpiration()
        {
            if (XmlScript.HasTrigger(AttachedTo, TriggerName.onExpire))
            {
                UberScriptTriggers.Trigger(AttachedTo, AttachedTo as Mobile, TriggerName.onExpire, AttachedTo as Item);
            }

            // with uberscript, I don't really see the need for this anymore

            /*
             * // now check for any conditions as well
             * // check for any condition that must be met for this entry to be processed
             * if (!BaseXmlSpawner.CheckCondition(ExpireActCondition, null, m_OwnedBy as Mobile))
             * return;
             *
             * BaseXmlSpawner.ExecuteActions(m_OwnedBy as Mobile, null, ExpireAction);
             */
        }
예제 #7
0
        public override void OnAttach()
        {
            base.OnAttach();
            AllScripts.Add(this, true);

            /*
             * List<string> timerTriggers = ParsedScripts.GetTimerTriggers(ScriptFile, RootNodeIndeces);
             * if (timerTriggers != null)
             * {
             *  // subscribe to timers
             *  UberScriptTimedScripts.SubscribeScript(this, timerTriggers);
             * }
             * */

            UpdateScriptTriggerLookup();

            if (XmlScript.HasTrigger(AttachedTo, TriggerName.onCreate))
            {
                TriggerObject trigObject = new TriggerObject();
                trigObject.TrigName = TriggerName.onCreate;
                trigObject.This     = AttachedTo;
                this.Execute(trigObject, true);
            }

            if (AttachedTo is BaseCreature)
            {
                if (XmlScript.HasTrigger(AttachedTo, TriggerName.onActivate))
                {
                    BaseCreature bc = (BaseCreature)AttachedTo;
                    if (bc.AIObject.m_Timer != null && bc.AIObject.m_Timer.Running)
                    {
                        UberScriptTriggers.Trigger(bc, bc, TriggerName.onActivate);
                    }
                }
            }
        }
예제 #8
0
        public static RootNode ParseFileContents(string[] lines, string fileName)
        {
            CurrentFileBeingParsed = fileName;

            // ERROR HANDLING OUTSIDE OF THIS FUNCTION
            var      balanceStack      = new Stack <UberNode>();
            RootNode root              = new RootNode(null, null);
            RootNode currentRoot       = root;       // spawn nodes are root nodes
            UberNode current           = root;
            UberNode prev              = null;
            int      currentLineNumber = 0;
            int      openCurlyBraces   = 0;

            var cleanedStrings = new List <CleanLine>();

            foreach (string line in lines)
            {
                //Console.WriteLine(line);
                currentLineNumber++;

                StringBuilder sb          = new StringBuilder();
                string        cleanedLine = line.Trim();

                if (cleanedLine.StartsWith("//"))
                {
                    continue;
                }

                bool insideQuotation            = false;
                bool justEscapedBackslash       = false;
                bool possibleComment            = false;
                int  forLoopRemainingSemiColons = 0;

                for (int i = 0; i < cleanedLine.Length; i++)
                {
                    if (cleanedLine[i] == '\t')
                    {
                        continue;                         // always remove tabs... not allowed even in strings..
                    }

                    if (cleanedLine[i] == '\\')
                    {
                        if (!insideQuotation)
                        {
                            throw new UberScriptException(
                                      String.Format(
                                          "Parse: unexpected escape token '\\' in '{0}' at line {1}:\n{2}", fileName, currentLineNumber, cleanedLine));
                        }

                        if (!justEscapedBackslash)
                        {
                            if (i > 0 && cleanedLine[i - 1] == '\\')
                            {
                                justEscapedBackslash = true;
                            }
                        }
                        else
                        {
                            justEscapedBackslash = false;
                        }

                        sb.Append('\\');                         // keep the double backslash in there regardless (it is handled in MathTree.ParseOperand)
                        continue;
                    }

                    if (cleanedLine[i] == '"')
                    {
                        if (!(i > 0 && cleanedLine[i - 1] == '\\' && !justEscapedBackslash))
                        {
                            insideQuotation = !insideQuotation;
                        }

                        sb.Append("\"");                         // add \" to the string
                        continue;
                    }

                    justEscapedBackslash = false;                     // make sure to reset this if you have gotten to this point

                    if (insideQuotation)
                    {
                        sb.Append(cleanedLine[i]);
                        continue;
                    }

                    if (cleanedLine[i] == '/')
                    {
                        if (possibleComment)
                        {
                            sb.Remove(sb.Length - 1, 1);                             // remove the previously added / character
                            break;
                        }

                        possibleComment = true;
                        sb.Append('/');
                        continue;
                    }

                    possibleComment = false;

                    if (cleanedLine[i] == ' ' || cleanedLine[i] == '\t')
                    {
                        continue;
                    }

                    // handle lines with multiple delimiters (e.g. orc { name = "Bob"; } )
                    if (cleanedLine[i] == '{' || cleanedLine[i] == '}')
                    {
                        // check if unbalanced
                        if (cleanedLine[i] == '{')
                        {
                            openCurlyBraces++;
                        }
                        else
                        {
                            openCurlyBraces--;
                        }

                        if (openCurlyBraces < 0)
                        {
                            throw new UberScriptException(
                                      String.Format(
                                          "Parse: brace mismatch detected in '{0}' at line {1}:\n{2}", fileName, currentLineNumber, cleanedLine));
                        }

                        // add everything before the { or } (if there is anything)
                        if (i > 0)
                        {
                            cleanedStrings.Add(new CleanLine(currentLineNumber, sb.ToString()));
                        }

                        cleanedStrings.Add(new CleanLine(currentLineNumber, cleanedLine[i].ToString(CultureInfo.InvariantCulture)));

                        // add { or } on separate "line" (it's processed as a line)
                        cleanedLine = cleanedLine.Substring(i + 1);
                        i           = -1;
                        sb.Clear();

                        continue;
                    }

                    if (cleanedLine[i] == ';')
                    {
                        if (cleanedLine.Length == i + 1)
                        {
                            break;
                        }                         // we are at the end of the loop, ignore lines ending in semicolon

                        string stringPreviousToSemiColon = sb.ToString();

                        if (stringPreviousToSemiColon.Contains("for"))
                        {
                            if (stringPreviousToSemiColon.Contains("foreach("))
                            {
                                forLoopRemainingSemiColons += 1;
                            }
                            else if (stringPreviousToSemiColon.Contains("for("))                             // for loop has 2 semicolons
                            {
                                forLoopRemainingSemiColons += 2;
                            }
                        }

                        if (forLoopRemainingSemiColons == 0)
                        {
                            // we have encountered a statement-separating semi-colon!
                            // add everything before the { or } (if there is anything)
                            if (i > 0)
                            {
                                cleanedStrings.Add(new CleanLine(currentLineNumber, sb.ToString()));
                            }

                            cleanedLine = cleanedLine.Substring(i + 1);
                            i           = -1;
                            sb.Clear();

                            continue;
                        }

                        forLoopRemainingSemiColons--;
                    }

                    sb.Append(cleanedLine[i]);
                }

                cleanedLine = sb.ToString();

                if (!String.IsNullOrWhiteSpace(cleanedLine) && !cleanedLine.StartsWith("//"))
                {
                    cleanedStrings.Add(new CleanLine(currentLineNumber, sb.ToString()));
                }
            }

            foreach (CleanLine cleanedString in cleanedStrings)
            {
                // i have to use this CleanLine object to keep track of line numbers
                // in spite of {, }, and ; characters splitting the lines up!
                currentLineNumber = cleanedString.LineNumber;

                string cleanedLine = cleanedString.Value;

                if (cleanedLine == "" || cleanedLine.StartsWith("//"))
                {
                    continue;
                }

                if (cleanedLine == "{")
                {
                    balanceStack.Push(current);

                    if (prev != null)
                    {
                        current = prev;
                    }

                    continue;
                }

                if (cleanedLine == "}")
                {
                    if (balanceStack.Count > 0)
                    {
                        current = balanceStack.Pop();

                        if (current is RootNode)
                        {
                            // likely we have finished procesinto a spawn nodes (ChildRoots)
                            // and therefore need to go back to the spawn node's root
                            // so triggers are correctly assigned to it
                            currentRoot = current.GetRootNode;
                        }

                        continue;
                    }

                    throw new UberScriptException(
                              String.Format(
                                  "Parse: brace mismatch detected in '{0}' at line {1}:\n{2}", fileName, currentLineNumber, cleanedLine));
                }
                // remove ending ";" characters (doesn't matter if you end with ; or not)
                // CANNOT do more than one statement on a line, though.

                // determine which type of node it is
                string lowerCase = cleanedLine.ToLower();

                if (UberScriptTriggers.HasTrigger(lowerCase))
                {
                    prev = new TriggerNode(current, lowerCase);

                    //Console.WriteLine(current + "->" + prev);

                    currentRoot.TriggerNodes.Add(prev as TriggerNode);
                }
                else if (char.IsDigit(cleanedLine[0]))                 // must be a sequence node
                {
                    int stage;

                    if (!Int32.TryParse(cleanedLine, out stage))
                    {
                        throw new UberScriptException(
                                  String.Format(
                                      "Parse: incorrect sequence format, integer expected at line {0}:\n{1}", currentLineNumber, cleanedLine));
                    }

                    prev = new SequenceNode(current, cleanedLine, stage);
                }
                else if (cleanedLine.StartsWith("foreach"))
                {
                    /*
                     * objs.moblist = GETNEARBYMOBS(TRIGMOB(),5)
                     *
                     * foreach(objs.mob ; objs.moblist)
                     * {
                     * }
                     */

                    prev = new ForEachNode(current, cleanedLine, currentLineNumber);
                }
                else if (cleanedLine.StartsWith("for"))
                {
                    /*
                     * for(ints.i = 0; ints.i < TRIGMOB().hits; ints.i = ints.i + 1)
                     * {
                     * }
                     */

                    prev = new ForLoopNode(current, cleanedLine, currentLineNumber);
                }
                else if (cleanedLine.StartsWith("if") || cleanedLine.StartsWith("elif") || cleanedLine.StartsWith("else") ||
                         cleanedLine.StartsWith("elseif"))
                {
                    prev = new ConditionalNode(current, cleanedLine, currentLineNumber);

                    //Console.WriteLine(current + "->" + prev);
                }
                else if (cleanedLine.StartsWith("return"))
                {
                    prev = new ReturnNode(current, cleanedLine);

                    if (cleanedLine == "returnoverride")
                    {
                        ((ReturnNode)prev).Override = true;
                    }
                }
                else
                {
                    switch (cleanedLine)
                    {
                    case "break":
                    {
                        // check whether it has a foreach / for ancestor
                        UberNode testParent           = current;
                        bool     foundForNodeAncestor = false;

                        while (testParent != null)
                        {
                            if (testParent is ForEachNode || testParent is ForLoopNode)
                            {
                                foundForNodeAncestor = true;
                                break;
                            }
                            testParent = testParent.Parent;
                        }

                        if (!foundForNodeAncestor)
                        {
                            throw new UberScriptException(
                                      String.Format("Parse: unexpected 'break' statement at line {0}:\n{1}", currentLineNumber, cleanedLine));
                        }

                        prev = new BreakNode(current, cleanedLine);
                    }
                    break;

                    case "continue":
                    {
                        // check whether it has a foreach / for ancestor
                        UberNode testParent           = current;
                        bool     foundForNodeAncestor = false;

                        while (testParent != null)
                        {
                            if (testParent is ForEachNode || testParent is ForLoopNode)
                            {
                                foundForNodeAncestor = true;
                                break;
                            }

                            testParent = testParent.Parent;
                        }

                        if (!foundForNodeAncestor)
                        {
                            throw new UberScriptException(
                                      String.Format("Parse: unexpected 'continue' statement at line {0}:\n{1}", currentLineNumber, cleanedLine));
                        }

                        prev = new ContinueNode(current, cleanedLine);
                    }
                    break;

                    default:
                    {
                        if (cleanedLine.StartsWith("pause"))
                        {
                            double pauseDuration;

                            if (!Double.TryParse(cleanedLine.Substring(5), out pauseDuration))
                            {
                                pauseDuration = 0;
                            }

                            prev = new PauseNode(current, cleanedLine, pauseDuration);
                        }
                        else if (cleanedLine.StartsWith("function"))
                        {
                            prev = new UserDefinedFunctionNode(current, lowerCase);
                            //Console.WriteLine(current + "->" + prev);
                            root.UserDefinedFunctionNodes.Add(prev as UserDefinedFunctionNode);
                        }

                        /*
                         * else if (cleanedLine.StartsWith("spawngroup"))
                         * {
                         *      prev = new SpawnGroupNode
                         * }
                         * else if (cleanedLine.StartsWith("spawnregion"))
                         * {
                         *
                         * }
                         * else if (cleanedLine.StartsWith("spawnentry"))
                         * {
                         *
                         * }
                         */
                        else
                        {
                            int equalCount = 0;
                            //char beforeChar = '\0';
                            int  numOpenParentheses = 0;
                            bool inQuotes           = false;

                            for (int i = 0; i < cleanedLine.Length; i++)
                            {
                                if (!inQuotes)
                                {
                                    if (cleanedLine[i] == '=' && numOpenParentheses == 0)
                                    {
                                        equalCount++;
                                    }
                                    else
                                    {
                                        switch (cleanedLine[i])
                                        {
                                        case '(':
                                            numOpenParentheses++;
                                            break;

                                        case ')':
                                        {
                                            numOpenParentheses--;

                                            if (numOpenParentheses < 0)
                                            {
                                                throw new UberScriptException(
                                                          String.Format(
                                                              "Parse: parentheses mismatch detected in '{0}' at line {1}:\n{2}",
                                                              fileName,
                                                              currentLineNumber,
                                                              cleanedLine));
                                            }
                                        }
                                        break;
                                        }
                                    }
                                }

                                if (cleanedLine[i] != '"')
                                {
                                    continue;
                                }

                                inQuotes = !inQuotes;                                         // assume that it's not an escaped quotation

                                // determine if it is an escaped quotation (and that there aren't escaped backslashes preceding it)
                                for (int ix = i - 1; ix >= 0 && cleanedLine[ix] == '\\'; ix--)
                                {
                                    inQuotes = !inQuotes;                                             // for each backslash behind, unescape or escape accordingly
                                }
                            }

                            if (equalCount == 1)                                     // it's a statement node
                            {
                                prev = new StatementNode(current, cleanedLine, currentLineNumber);
                                //Console.WriteLine(current + "->" + prev);

                                if (((StatementNode)prev).ContainsSpawnNode)
                                {
                                    // global_objs.test = orc
                                    // {
                                    //      name = goober
                                    // }
                                    prev.LineNumber = currentLineNumber;                                    // we "continue" here so we set this later
                                    current.Children.Add(prev);                                             // we "continue" here so we don't add it later
                                    //Console.WriteLine(current + "->" + prev + "... adding spawn node to statement node!");

                                    prev = prev.Children[1];                                             // should contain a spawn node
                                    currentRoot.ChildRoots.Add(prev as RootNode);
                                    currentRoot = prev as RootNode;                                      // spawn node become the new root node
                                    continue;
                                }
                            }
                            else if (UberScriptFunctions.IsFunctionString(cleanedLine))
                            {
                                prev = new FunctionNode(current, cleanedLine, currentLineNumber);
                                //Console.WriteLine(current + "->" + prev);
                            }
                            else if (UserDefinedFunctionNode.GetUserDefinedFunctionString(cleanedLine, root) != null)
                            {
                                prev = new UserDefinedFunctionExectueNode(current, cleanedLine, currentLineNumber);

                                ((UserDefinedFunctionExectueNode)prev).UserDefinedFunction =
                                    UserDefinedFunctionNode.GetUserDefinedFunctionString(cleanedLine, root);
                            }
                            else
                            {
                                // the string might have commas (indicating a spawn type with a constructor accepting arguments
                                // such as "static,100"
                                int commaIndex = cleanedLine.IndexOf(',');

                                Type spawnType =
                                    ScriptCompiler.FindTypeByName(commaIndex > 0 ? cleanedLine.Substring(0, commaIndex) : cleanedLine);

                                if (spawnType != null && typeof(Mobile).IsAssignableFrom(spawnType) || typeof(Item).IsAssignableFrom(spawnType))
                                {
                                    prev = new RootNode(current, cleanedLine);
                                    // keep a list of child root nodes so that spawned creatures that have triggers
                                    // specific to them can correctly point to the right place in the script e.g.
                                    // troll
                                    // {
                                    //      onDeath
                                    //      {
                                    //          orc
                                    //          {
                                    //              onDeath
                                    //              {
                                    //                  ...
                                    //              }
                                    //          }
                                    //      }
                                    // }
                                    // --> trigger nodes are only added to their closest root node
                                    currentRoot.ChildRoots.Add(prev as RootNode);
                                    //Console.WriteLine(current + "->" + prev);
                                    currentRoot = prev as RootNode;                                             // spawn node become the new root node
                                }
                                else
                                {
                                    throw new UberScriptException(
                                              String.Format("Parse: could not parse node at line {0}:\n{1}", currentLineNumber, cleanedLine));
                                }
                            }
                        }
                    }
                    break;
                    }
                }

                current.Children.Add(prev);
                prev.LineNumber = currentLineNumber;                 // used for debugging purposes
            }

            if (balanceStack.Count > 0)
            {
                throw new UberScriptException(
                          String.Format("Parse: brace mismatch detected in '{0}' at line {1}", fileName, currentLineNumber));
            }

            return(root);
        }