/// <summary> /// Parses a string condition into condition objects /// </summary> /// <param name="parts"></param> /// <param name="i"></param> /// <returns></returns> private static Condition ParseCondition(List<Token> parts, ref int i) { ParseFunctions(ref parts); ConditionList List; for(; i < parts.Count; i++) { if (parts[i].Kind == TokenType.ConditionFunction) { // Default ConditionType Type = ConditionType.And; switch (parts[i].Value) { case "f_and": Type = ConditionType.And; break; case "f_or": Type = ConditionType.Or; break; case "f_not": Type = ConditionType.Not; break; case "f_plus": Type = ConditionType.Plus; break; case "f_div": Type = ConditionType.Div; break; } // Create the new condition list List = new ConditionList(Type); // Parse sub conditions i++; while(i < parts.Count && parts[i].Kind != TokenType.CloseParen) List.Add(ParseCondition(parts, ref i)); i++; // Return condition list return List; } else if (parts[i].Kind == TokenType.StatFunction) { List<string> Params = new List<string>(); string Name = parts[i].Value; for (; i < parts.Count; i++) { if (parts[i].Kind == TokenType.CloseParen) break; if (parts[i].Kind == TokenType.OpenParen) continue; Params.Add(parts[i].Value); } i++; // Create the condition switch (Name) { case "object_stat": return new ObjectStat(Params); case "global_stat": case "player_stat": return new PlayerStat(Params); case "has_medal": case "has_rank": return new MedalOrRankCondition(Params); case "global_stat_multiple_times": return new GlobalStatMultTimes(Params); } } else if (parts[i].Kind == TokenType.Literal) { ConditionValue V = new ConditionValue(parts[i].Value); i++; return V; } } return new ConditionList( ConditionType.And ); }
/// <summary> /// Converts the list to tree view. If there is only 1 sub criteria /// on an "And" or "Or" type list, then the list will not collapse into the /// sub criteria. Invalid Sub condition nodes will be highlighted in Red. /// </summary> /// <returns>A TreeNode representation of the Conditions in this list</returns> public override TreeNode ToTree() { // Define vars string Name = "Meets All Requirements:"; bool Trim = false; int i = 0; HasConditionErrors = false; // Build the name which will be displayed in the criteria view switch (this.Type) { case ConditionType.Div: if (SubConditions.Count == 3) { // If a div condition has 3 conditions, the last is always a condition value ConditionValue Cnd = (ConditionValue)SubConditions.Last(); Name = "Conditions Divided Equal to or Greater than " + Cnd.Value; Trim = true; } else { Name = "Divided Value Of:"; } break; case ConditionType.Not: Name = "Does Not Meet Criteria:"; break; case ConditionType.Or: Name = "Meets Any Criteria:"; break; case ConditionType.Plus: if (SubConditions.Count == 3) { // If a plus condition has 3 conditions, the last is always a condition value ConditionValue Cnd = (ConditionValue)SubConditions.Last(); Name = "Condtions Equal to or Greater than " + String.Format("{0:N0}", Int32.Parse(Cnd.Value)); Trim = true; } else { Name = "The Sum Of:"; } break; } // Start the TreeNode, and add this condition list in the tag TreeNode Me = new TreeNode(Name); Me.Tag = this; // Add sub conditions to the nodes of this condition's tree node foreach (Condition C in SubConditions) { // Obviously dont add null items if (C == null) { continue; } // Make sure not to add the last element on a plus conditionlist if (Trim && C is ConditionValue) { break; } // Convert sub-condition to tree TreeNode N = C.ToTree(); if (N == null) { continue; } // Nested errors if (!HasConditionErrors && C is ConditionList) { HasConditionErrors = (C as ConditionList).HasConditionErrors; } // Validation if (!ValidateParam(i, C.Returns())) { N.ForeColor = System.Drawing.Color.Red; HasConditionErrors = true; N.ToolTipText = "Invalid Return Type. "; N.ToolTipText += (C.Returns() == ReturnType.Bool) ? "A criteria value is required" : "Criteria value must be disabled"; } else { // Always reset this N.ToolTipText = ""; } // Add the node Me.Nodes.Add(N); i++; } return(Me); }
/// <summary> /// Parses a string condition into condition objects /// </summary> /// <param name="parts"></param> /// <param name="i"></param> /// <returns></returns> private static Condition ParseCondition(List <Token> parts, ref int i) { ParseFunctions(ref parts); ConditionList List; for (; i < parts.Count; i++) { if (parts[i].Kind == TokenType.ConditionFunction) { // Default ConditionType Type = ConditionType.And; switch (parts[i].Value) { case "f_and": Type = ConditionType.And; break; case "f_or": Type = ConditionType.Or; break; case "f_not": Type = ConditionType.Not; break; case "f_plus": Type = ConditionType.Plus; break; case "f_div": Type = ConditionType.Div; break; } // Create the new condition list List = new ConditionList(Type); // Parse sub conditions i++; while (i < parts.Count && parts[i].Kind != TokenType.CloseParen) { List.Add(ParseCondition(parts, ref i)); } i++; // Return condition list return(List); } else if (parts[i].Kind == TokenType.StatFunction) { List <string> Params = new List <string>(); string Name = parts[i].Value; for (; i < parts.Count; i++) { if (parts[i].Kind == TokenType.CloseParen) { break; } if (parts[i].Kind == TokenType.OpenParen) { continue; } Params.Add(parts[i].Value); } i++; // Create the condition switch (Name) { case "object_stat": return(new ObjectStat(Params)); case "global_stat": case "player_stat": case "player_score": return(new PlayerStat(Params)); case "has_medal": case "has_rank": return(new MedalOrRankCondition(Params)); case "global_stat_multiple_times": return(new GlobalStatMultTimes(Params)); } } else if (parts[i].Kind == TokenType.Literal) { ConditionValue V = new ConditionValue(parts[i].Value); i++; return(V); } } return(new ConditionList(ConditionType.And)); }