Пример #1
0
        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);
        }
Пример #2
0
        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));
        }
Пример #3
0
        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());
        }
Пример #4
0
        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);
        }
Пример #5
0
        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());
        }
Пример #6
0
        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());
        }
Пример #7
0
        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());
        }
Пример #8
0
 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));
 }
Пример #9
0
        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);
        }
Пример #10
0
 public MeInvalidCastException(MeVariable var, Type t)
     : base($"Invalid cast of {var}({var.GetType().Name}) to {(t == typeof(float) ? "Float" : t.Name)}")
 {
 }