예제 #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 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);
        }