public void EntityTestModifierStatusEffectsRemoved() { BaseEntity ent = new MockEntity(Engine) { Name = "MOCK_PLAYER", Key = "MOCK_KEY" }; string expression = $"{LConstants.ADD_MOD_F}(STR,$0)"; MeNode[] statuses = Engine.GetSanitizer().SplitAndConvert(expression); StatusTemplate test = new StatusTemplate(statuses) { Interval = TreeConverter.Build("0", Engine) }; test.Key = "TEST_STATUS_KEY10"; double[] values = { 10 }; int duration = 5; double expected = ent.GetProperty("STR").Value + 10; double removedExpected = ent.GetProperty("STR").Value; ent.ApplyStatus(test, ent, duration, values); MockTimer timer = (MockTimer)Engine.GetTimer(); Assert.AreEqual(expected, ent.GetProperty("STR").Value); for (int i = 0; i <= duration; ++i) { timer.ForceTick(); } ent.Update(); Assert.AreEqual(removedExpected, ent.GetProperty("STR").Value); }
private void AddStatusFromTemplate(StatusTemplate status, Entity source, double duration, double[] values) { long removeTime = GetRemoveTime(duration); AppliedStatus newStatus = new AppliedStatus() { Source = source, LastTick = 0, RemovalTime = removeTime, Template = status, NumericValues = values }; MeNode intervalTree = Sanitizer.ReplaceTargetAndSource(status.Interval, source, this); newStatus.Interval = intervalTree.Resolve().Value.ToLong(); Statuses.Add(newStatus); foreach (MeNode tree in newStatus.Template.Modifiers) { StatModifier mod = Engine.GetSanitizer().ResolveStatus(tree, newStatus.NumericValues).ToModifier(); newStatus.MyMods.Add(mod); Attributes[mod.StatKey].Modifiers.Add(mod); } RefreshProperties(); int stackCount = 0; foreach (AppliedStatus sts in Statuses) { if (sts.Template.Key.Equals(newStatus.Template.Key)) { ++stackCount; } } Engine.Log().Log($"[{Name}] Affected by {status.Name}[{stackCount}]."); }
public void EntityTestPropertyTypeUpdatesWithFunction() { //initial test string strKey = "STR"; string expression = $"{LConstants.GET_PROP_F}({BaseEntity.Key},{strKey})"; double expected = BaseEntity.GetProperty(strKey).Value; MeNode tree = TreeConverter.Build(expression, Engine); MeNode partiallyResolved = TreeResolver.ResolveGivenOperations(tree, new string[1] { LConstants.GET_PROP_F }); Assert.AreEqual(expected, partiallyResolved.Value.ToDouble()); //apply a status that modifies the value string expression2 = $"{LConstants.ADD_MOD_F}(STR,$0)"; MeNode[] statuses = Engine.GetSanitizer().SplitAndConvert(expression2); StatusTemplate test = new StatusTemplate(statuses) { Interval = TreeConverter.Build("0", Engine) }; test.Key = "TEST_STATUS_KEY33"; double[] values = { 10 }; BaseEntity.ApplyStatus(test, BaseEntity, 10, values); BaseEntity.Update(); //test again expected = BaseEntity.GetProperty(strKey).Value; Assert.AreEqual(expected, partiallyResolved.Value.ToDouble()); BaseEntity.Cleanse(); }
public void EntityTestModifierHarmTickrate() { BaseEntity ent = new MockEntity(Engine) { Name = "MOCK_PLAYER", Key = "MOCK_KEY" }; int[] timeValues = { 10, 5 }; string expression = $"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.TargetKeyword},T,$0)"; MeNode[] statuses = Engine.GetSanitizer().SplitAndConvert(expression); StatusTemplate test = new StatusTemplate(statuses) { Interval = TreeConverter.Build(timeValues[0].ToString(), Engine) }; test.Key = "TEST_STATUS_KEY4"; double[] values = { 20 }; ent.ApplyStatus(test, ent, timeValues[0], values); double expectedHp = ent.GetProperty(Entity.HP_KEY).Value - values[0]; MockTimer timer = (MockTimer)Engine.GetTimer(); ent.Update(); Assert.AreEqual(expectedHp, ent.GetProperty(Entity.HP_KEY).Value); timer.ForceTick(); timer.ForceTick(); ent.Update(); Assert.AreEqual(expectedHp, ent.GetProperty(Entity.HP_KEY).Value); }
public void EntityTestHarmStatusIntervalIsFormula() { BaseEntity ent = new MockEntity(Engine) { Name = "MOCK_PLAYER", Key = "MOCK_KEY" }; double damage = 10; string expression = $"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.TargetKeyword},T,{damage})"; MeNode[] statuses = Engine.GetSanitizer().SplitAndConvert(expression); string intervalExpression = $"10-{LConstants.GET_PROP_F}({LConstants.SourceKeyword},INT)*2"; MeNode intervalNode = TreeConverter.Build(intervalExpression, Engine); StatusTemplate test = new StatusTemplate(statuses) { Interval = intervalNode }; test.Key = "TEST_STATUS_KEY2"; ent.ApplyStatus(test, ent, 5, null); double expectedHp = ent.GetProperty(Entity.HP_KEY).Value - damage; double expectedHp2 = ent.GetProperty(Entity.HP_KEY).Value - damage * 2; MockTimer timer = (MockTimer)Engine.GetTimer(); ent.Update(); timer.ForceTick(); Assert.AreEqual(expectedHp, ent.GetProperty(Entity.HP_KEY).Value); ent.Update(); Assert.AreEqual(expectedHp2, ent.GetProperty(Entity.HP_KEY).Value); }
public StatusTemplate FromJSON(JObject json) { MeNode[] formulas = Engine.GetSanitizer().SplitAndConvert(json[GcConstants.General.FORMULA].ToString()); StatusTemplate result = new StatusTemplate(formulas); result.LoadBase(json); result.MaxStacks = json.ContainsKey(GcConstants.Statuses.MAX_STACK) ? TreeConverter.Build(json[GcConstants.Statuses.MAX_STACK].ToString(), Engine) : new MeNode(1); ; result.Interval = json.ContainsKey(GcConstants.Statuses.INTERVAL) ? TreeConverter.Build(json[GcConstants.Statuses.INTERVAL].ToString(), Engine) : new MeNode(1); ; result.Type = json.ContainsKey(GcConstants.Statuses.STACK_TYPE) ? StatusTemplate.FromString(json[GcConstants.Statuses.STACK_TYPE].ToString()) : StackingType.Independent; return(result); }
public void EntityTestModifierAndHarm() { BaseEntity ent = new MockEntity(Engine) { Name = "MOCK_PLAYER", Key = "MOCK_KEY" }; string expression = $"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.TargetKeyword},T,$0);{LConstants.ADD_MOD_F}(STR,$1)"; MeNode[] statuses = Engine.GetSanitizer().SplitAndConvert(expression); StatusTemplate test = new StatusTemplate(statuses) { Interval = TreeConverter.Build("0", Engine) }; test.Key = "TEST_STATUS_KEY3"; double[] values = { 20, 10 }; double expectedHp = ent.GetProperty(Entity.HP_KEY).Value - values[0]; double expected = ent.GetProperty("STR").Value + values[1]; ent.ApplyStatus(test, ent, 5, values); ent.Update(); Assert.AreEqual(expectedHp, ent.GetProperty(Entity.HP_KEY).Value); Assert.AreEqual(expected, ent.GetProperty("STR").Value); }
public void EntityTestModifierMultipleStatusEffects() { BaseEntity ent = new MockEntity(Engine) { Name = "MOCK_PLAYER", Key = "MOCK_KEY" }; string expression = $"{LConstants.ADD_MOD_F}(STR,$0);{LConstants.ADD_MOD_F}(AGI,$1)"; MeNode[] statuses = Engine.GetSanitizer().SplitAndConvert(expression); StatusTemplate test = new StatusTemplate(statuses) { Interval = TreeConverter.Build("0", Engine) }; test.Key = "TEST_STATUS_KEY5"; double[] values = { 10, 5 }; double expectedStr = ent.GetProperty("STR").Value + values[0]; double expetedDex = ent.GetProperty("AGI").Value + values[1]; ent.ApplyStatus(test, ent, 5, values); MockTimer timer = (MockTimer)Engine.GetTimer(); ent.Update(); Assert.AreEqual(expectedStr, ent.GetProperty("STR").Value); Assert.AreEqual(expetedDex, ent.GetProperty("AGI").Value); }
public void AddStatus(StatusTemplate status) { if (Statuses.ContainsKey(status.Key)) { throw new MeException($"Duplicate key for {status.Key}({status.Name})."); } Statuses.Add(status.Key, status); }
public void LoadStatusesFromFile(string path) { StatusReader reader = new StatusReader(Engine); JArray json = FileHandler.FromPath <JArray>(path); foreach (JToken entry in json) { if (entry.Type != JTokenType.Object) { throw new MeException($"Expected a json object \"{path}\"at \"{entry}\"."); } StatusTemplate newEntry = reader.FromJSON(entry.ToObject <JObject>()); AddStatus(newEntry); } }
public async Task <IActionResult> AddNewStatus([FromBody] StatusModel status) { string str = "Create Status Template Successfully"; StatusTemplate statusTemp = new StatusTemplate(); foreach (var item in status.statusData) { statusTemp.StatusName = item.StatusName; statusTemp.Serial = item.Serial; statusTemp.TemplateId = item.TemplateId; statusTemp.Relation = 0; } _context.StatusTemplate.Add(statusTemp); await _context.SaveChangesAsync(); var result = JsonConvert.SerializeObject(new { result = str }); return(Ok(result)); }
public override void ApplyStatus(StatusTemplate status, Entity source, double duration, double[] values) { switch (status.Type) { case StackingType.Refresh: { AppliedStatus refresh = GetStatusInstance(status.Key); if (refresh != null) { refresh.RemovalTime = Engine.GetTimer().GetNow() + (long)duration * 1000; } else { AddStatusFromTemplate(status, source, duration, values); } break; } case StackingType.None: { AppliedStatus refresh = GetStatusInstance(status.Key); if (refresh == null) { AddStatusFromTemplate(status, source, duration, values); } break; } case StackingType.Independent: { long maxStacks = status.MaxStacks.Resolve().Value.ToLong(); int currentStacks = GetStatusStackCount(status.Key); if (maxStacks == 0 || maxStacks > currentStacks) { AddStatusFromTemplate(status, source, duration, values); } break; } } }
public void EntityTestHarmStatusEffect() { BaseEntity ent = new MockEntity(Engine) { Name = "MOCK_PLAYER", Key = "MOCK_KEY" }; double damage = 10; string expression = $"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.TargetKeyword},T,{damage})"; MeNode[] statuses = Engine.GetSanitizer().SplitAndConvert(expression); StatusTemplate test = new StatusTemplate(statuses) { Interval = TreeConverter.Build("0", Engine) }; test.Key = "TEST_STATUS_KEY"; ent.ApplyStatus(test, ent, 5, null); double expectedHp = ent.GetProperty(Entity.HP_KEY).Value - damage; ent.Update(); Assert.AreEqual(expectedHp, ent.GetProperty(Entity.HP_KEY).Value); }
public void EntityTestModifierStatusEffect() { BaseEntity ent = new MockEntity(Engine) { Name = "MOCK_PLAYER", Key = "MOCK_KEY" }; string expression = $"{LConstants.ADD_MOD_F}(STR,$0)"; MeNode[] statuses = Engine.GetSanitizer().SplitAndConvert(expression); StatusTemplate test = new StatusTemplate(statuses) { Interval = TreeConverter.Build("0", Engine) }; test.Key = "TEST_STATUS_KEY6"; double[] values = { 10 }; double expected = ent.GetProperty("STR").Value + 10; ent.ApplyStatus(test, ent, 5, values); ent.Update(); Assert.AreEqual(expected, ent.GetProperty("STR").Value); }
public void StatusReaderTestAllValues() { string key = "TEST_KEY"; double maxStack = 10; double interval = 10; StackingType type = StackingType.Refresh; string intervalFormula = $"{LConstants.MAX_F}(10,5)"; string formula = $"{ LConstants.HARM_F }({ LConstants.TargetKeyword},{ LConstants.TargetKeyword},T,$0)"; string jsonStr = $"{{\"{GcConstants.General.KEY}\":\"{key}\","; jsonStr += $"\"{GcConstants.Statuses.MAX_STACK}\":\"{maxStack}\","; jsonStr += $"\"{GcConstants.Statuses.STACK_TYPE}\":\"{type.ToString().ToLower()}\","; jsonStr += $"\"{GcConstants.Statuses.INTERVAL}\":\"{intervalFormula}\","; jsonStr += $"\"{GcConstants.General.FORMULA}\":\"{formula}\"}}"; JObject json = JObject.Parse(jsonStr); StatusTemplate status = Reader.FromJSON(json); Assert.AreEqual(maxStack, status.MaxStacks.Resolve().Value.ToDouble()); Assert.AreEqual(interval, status.Interval.Resolve().Value.ToDouble()); Assert.AreEqual(type, status.Type); Assert.AreEqual(interval, status.Interval.Resolve().Value.ToDouble()); }
public void AddStatus(StatusTemplate status, string key) { status.Key = key; _statusManager.AddStatus(status); }
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 abstract void ApplyStatus(StatusTemplate status, Entity source, double duration, double[] values);