public void FunctionalTreeConverterTestArrayAndFunction() { string expression = $"{LConstants.ARRAY_F}(10,{LConstants.MAX_F}(10,20),10)"; double[] expected = { 10, 20, 10 }; double[] actual = MeVariable.ToDoubleArray(TreeResolver.Resolve(expression, Engine).Value.ToArray()); Assert.AreEqual(expected.Length, actual.Length); CollectionAssert.AreEqual(expected, actual); }
public Operator DefineOperator() { return (Utils.MakeOperator(LConstants.PROP_OP, 20, true, (values, op) => { op.CheckParamCount(values.Length); string key = values[1].ToMeString(); MeVariable var = values[0]; switch (var.Type) { case VariableType.Array: { if (key.Equals(LConstants.ARR_LENGTH)) { return var.ToArray().Length; } throw new MeException($"Attempting to retrieve undefined property \"{key}\" from array."); } case VariableType.Entity: { return new MeVariable() { Value = new Property(var.ToEntity(), key), Type = VariableType.Property }; } } throw new MeException($"Attempting to retrieve undefined property \"{key}\" from variable \"{var}\""); } , new Validator( (variables, operation) => { MeVariable var = variables[0]; string key = variables[1].ToMeString(); switch (var.Type) { case VariableType.Array: { return key.Equals(LConstants.ARR_LENGTH); } case VariableType.Entity: { Entity ent = var.ToEntity(); return ent.HasProperty(key); } default: { return false; } } }), 2)); }
public void VariableTestAssignOperatorWorks() { string varName = "testVar"; double number = 3.14; string expression = $"{varName} {LConstants.ASSIGN_OP} {number}"; MeNode tree = TreeConverter.Build(expression, Engine); tree.Resolve(); MeVariable result = Engine.GetVariable(varName); Assert.IsNotNull(result); Assert.AreEqual(number, result.ToDouble()); }
public MeVariable SanitizeSkill(string skill, Entity caster, Entity target) { string[] lines = skill.Split(LConstants.FUNCTION_SEPARATOR); MeVariable var = null; foreach (string expr in lines) { Token[] tokens = Tokenizer.Tokenize(expr); Token[] sanitizedTokens = ReplaceEntities(tokens, caster, target); var = TreeResolver.Resolve(sanitizedTokens, _engine).Value; } return(var); }
public void VariableTestAssignFromProperty() { string varName = "testVar"; string propKey = "STR"; double expected = BasePlayer.GetProperty(propKey).Value; string expression = $"{varName} {LConstants.ASSIGN_OP} {BasePlayer.Key}{LConstants.PROP_OP}{propKey}"; MeNode[] trees = Engine.GetSanitizer().SplitAndConvert(expression); foreach (MeNode node in trees) { node.Resolve(); } MeVariable result = Engine.GetVariable(varName); Assert.IsNotNull(result); Assert.AreEqual(expected, result.ToDouble()); }
public void VariableTestGetOperatorWorks() { string varName = "testVar"; string varName2 = "otherVar"; double number = 3.14; string expression = $"{varName} {LConstants.ASSIGN_OP} {number}; {varName2} {LConstants.ASSIGN_OP} {LConstants.GET_F}({varName});"; MeNode[] trees = Engine.GetSanitizer().SplitAndConvert(expression); foreach (MeNode node in trees) { node.Resolve(); } MeVariable result = Engine.GetVariable(varName); MeVariable other = Engine.GetVariable(varName2); Assert.IsNotNull(result); Assert.IsNotNull(other); Assert.AreEqual(other.ToDouble(), result.ToDouble()); }
public void VariableTestAssignFromFunction() { string varName = "testVar"; double[] numbers = { 10, 11, 12 }; StringBuilder sb = new StringBuilder(); foreach (double num in numbers) { sb.Append(num); sb.Append(","); } sb.Remove(sb.Length - 1, 1); string expression = $"{varName} {LConstants.ASSIGN_OP} {LConstants.MAX_F}({sb.ToString()})"; MeNode tree = TreeConverter.Build(expression, Engine); tree.Resolve(); MeVariable result = Engine.GetVariable(varName); Assert.IsNotNull(result); Assert.AreEqual(numbers.Max(), result.ToDouble()); }
public Operator DefineOperator() { return(Utils.MakeOperator(LConstants.ASSIGN_OP, -1, true, (values, op) => { op.CheckParamCount(values.Length); string key = values[0].ToMeString(); MeVariable leftSide = Definer.Instance().Engine.GetVariable(key); MeVariable rightSide = values[1]; if (rightSide.Type == VariableType.String) { rightSide = Definer.Instance().Engine.GetVariable(rightSide.Value.ToString()); } if (leftSide == null) { Definer.Instance().Engine.AddVariable(key, rightSide); } else { Definer.Instance().Engine.SetVariable(key, rightSide); } return null; }, new Validator( (variables, operation) => true), 2)); }
public void Init(IGameEngine engine) { if (_initialized) { return; } _initialized = true; IOperatorDefiner[] opDefiners = { new PlusOperator(), new MinusOperator(), new PropertyOperator(), new MultiplyOperator(), new PowerOperator(), new DivideOperator(), new NotOperator(), new GreaterOperator(), new LesserOperator(), new AssignOperator(), new NumEqualsOperator() }; foreach (IOperatorDefiner def in opDefiners) { AddOperator(def.DefineOperator()); } Engine = engine; AddFunction(LConstants.MAX_F, (values, func) => { func.CheckParamCount(values.Length); double[] parameters = MeVariable.ToDoubleArray(values); return(parameters.Max()); }); AddFunction(LConstants.FLOOR_F, (values, func) => { func.CheckParamCount(values.Length); return(Math.Floor(values[0].ToDouble())); }, 1); AddFunction(LConstants.MIN_F, (values, func) => { func.CheckParamCount(values.Length); double[] parameters = MeVariable.ToDoubleArray(values); return(parameters.Min()); }); AddFunction(LConstants.ABS_F, (values, func) => { func.CheckParamCount(values.Length); return(Math.Abs(values[0].ToDouble())); }, 1); AddFunction(LConstants.NON_NEG_F, (values, func) => { func.CheckParamCount(values.Length); double value = values[0].ToDouble(); return(value > 0 ? value : 0); }, 1); AddFunction(LConstants.RANDOM_F, (values, func) => { func.CheckParamCount(values.Length); return(new Random().Next((int)values[0].ToDouble(), (int)values[1].ToDouble())); }, 2); AddFunction(LConstants.HARM_F, (values, func) => { //func.CheckParamCount(values.Length); MeVariable[] targets = values[0].ToArray(); Entity source = values[1].ToEntity(); DamageTypeTemplate damageTypeTemplate = values[2].ToDamageType(); double amount = values[3].ToDouble(); bool periodic = false; if (values.Length > func.ParameterCount) { periodic = values[4].ToBoolean(); } double totalAmt = 0; foreach (MeVariable variable in targets) { totalAmt += variable.ToEntity().TakeDamage(amount, damageTypeTemplate, source, periodic); } return(totalAmt); }, 4); AddFunction(LConstants.HEAL_F, (values, func) => { func.CheckParamCount(values.Length); MeVariable[] targets = values[0].ToArray(); Entity source = values[1].ToEntity(); double amount = values[2].ToDouble(); double totalAmt = 0; foreach (MeVariable variable in targets) { totalAmt += variable.ToEntity().GetHealed(amount, source); } return(totalAmt); }, 3); AddFunction(LConstants.ARRAY_F, (values, func) => { func.CheckParamCount(values.Length); return(new MeVariable() { Type = VariableType.Array, Value = values }); }); AddFunction(LConstants.GET_PLAYERS_F, (values, func) => { func.CheckParamCount(values.Length); Entity[] players = Definer.Instance().Engine.GetAllPlayers(); List <MeVariable> playerList = new List <MeVariable>(); foreach (Entity entity in players) { playerList.Add(entity); } return(new MeVariable() { Value = playerList.ToArray(), Type = VariableType.Array }); }, 0); AddFunction(LConstants.GET_ACTIVE_PLAYERS_F, (values, func) => { func.CheckParamCount(values.Length); //TODO: Implement retrieving ONLY active players Entity[] players = Definer.Instance().Engine.GetAllPlayers(); List <MeVariable> playerList = new List <MeVariable>(); foreach (Entity entity in players) { playerList.Add(entity); } return(new MeVariable() { Value = playerList.ToArray(), Type = VariableType.Array }); }, 0); AddFunction(LConstants.GET_PROP_F, (values, func) => { func.CheckParamCount(values.Length); Entity entity = values[0].ToEntity(); string prop = values[1].ToMeString(); return(new MeVariable() { Value = new Property(entity, prop), Type = VariableType.Property }); ; }, 2); AddFunction(LConstants.IF_F, (values, func) => { //IF(CONDITION,THEN,ELSE) func.CheckParamCount(values.Length); bool condition = values[0].ToBoolean(); if (condition) { return(values[1].Execute()); } else { return(values[2].Execute()); } }, 3, new bool[] { true, false, false }); AddFunction(LConstants.ARR_RANDOM_F, (values, func) => { func.CheckParamCount(values.Length); MeVariable[] input = values[0].ToArray(); int index = new Random().Next(0, input.Length); return(input[index]); }, 1); AddFunction(LConstants.CHANCE_F, (values, func) => { func.CheckParamCount(values.Length); double chance = values[0].ToDouble() * 10; return(RPGEngine.Utils.Utility.Chance(chance)); }, 1); AddFunction(LConstants.CAST_F, (values, func) => { //CAST(CASTER,TARGET,SKILL) func.CheckParamCount(values.Length); Entity caster = values[0].ToEntity(); Entity target = values[1].ToEntity(); string skillKey = values[2].ToMeString(); caster.Cast(target, skillKey); return(null); }, 3); AddFunction(LConstants.ADD_MOD_F, (values, func) => { //MOD_VALUE(stat,Amount) func.CheckParamCount(values.Length); string stat = values[0].ToMeString(); double amount = values[1].ToDouble(); StatModifier mod = new StatModifier() { Amount = amount, StatKey = stat }; return(new MeVariable { Type = VariableType.StatModifier, Value = mod }); }, 2); AddFunction(LConstants.APPLY_F, (values, func) => { //APPLYSTATUS(target,Source,status_key,duration,amounts) func.CheckParamCount(values.Length); MeVariable[] targets = values[0].ToArray(); Entity source = values[1].ToEntity(); StatusTemplate effect = Definer.Instance().Engine.GetStatusByKey(values[2].ToMeString()); double duration = values[3].ToDouble(); double[] amounts = MeVariable.ToDoubleArray(values[4].ToArray()); func.CheckParamCount(values.Length); foreach (MeVariable target in targets) { target.ToEntity().ApplyStatus(effect, source, duration, amounts); } return(null); }, 5); AddFunction(LConstants.GET_F, (values, func) => { func.CheckParamCount(values.Length); string key = values[0].ToMeString(); return(Definer.Instance().Engine.GetVariable(key));; }, 1); AddFunction(LConstants.SAY_F, (values, func) => { func.CheckParamCount(values.Length); Entity entity = values[0].ToEntity(); string msg = values[1].ToMeString(); Engine.Log().LogSay(entity, msg); return(null); }, 2); AddFunction(LConstants.PUSH_BACK_F, (values, func) => { func.CheckParamCount(values.Length); MeVariable[] entity = values[0].ToArray(); long amount = values[1].ToLong(); foreach (MeVariable var in entity) { var.ToEntity().AddPushback(amount); } return(null); }, 2); AddFunction(LConstants.REVIVE_F, (values, func) => { func.CheckParamCount(values.Length); MeVariable[] entity = values[0].ToArray(); foreach (MeVariable var in entity) { var.ToEntity().Revive(); } return(null); }, 1); AddFunction(LConstants.ADD_TO_RESOURCE_F, (values, func) => { func.CheckParamCount(values.Length); MeVariable[] entity = values[0].ToArray(); string resourceKey = values[1].ToString(); double amount = values[2].ToDouble(); foreach (MeVariable var in entity) { var.ToEntity().AddToResource(resourceKey, amount); } return(null); }, 3); }
public MeInvalidCastException(MeVariable var, Type t) : base($"Invalid cast of {var}({var.GetType().Name}) to {(t == typeof(float) ? "Float" : t.Name)}") { }