/// <summary> /// 解析行为 /// </summary> /// <param name="line">脚本行</param> /// <param name="tmpItem">行为生成类</param> /// <returns></returns> private static IFormulaItem TransBehavior(string line, IFormulaItem tmpItem) { // 解析内容 // TODO 判断Formula的stack等级是否与当前stack等级一直? 不一致则新建将其加入上一级formula的子集 // 参数列表内容 var pos = GetSmallBraketPos(line); var start = pos[0]; var end = pos[1]; // 行为类型 var type = line.Substring(0, start); // 行为参数 var args = line.Substring(start + 1, end - start - 1); // 消除参数空格 args = args.Replace(" ", ""); // 使用参数+名称获取IFormula var item = GetFormula(type, args); // formula加入暂停item var pauseItem = GetFormula("Pause", "1"); tmpItem = tmpItem == null ? pauseItem : tmpItem.After(pauseItem); tmpItem = tmpItem.After(item); return(tmpItem); }
/// <summary> /// 获取行为链 /// </summary> /// <param name="paramsPacker">构造数据</param> /// <param name="formulaItem">行为链构造器</param> /// <returns></returns> protected IFormula GetIFormula(FormulaParamsPacker paramsPacker, IFormulaItem formulaItem) { IFormula result = null; // 循环构建行为链构造器 var tmpItem = formulaItem; // 数据列表放入packer中 paramsPacker.DataList = DataList; // 技能ID放入packer中 paramsPacker.SkillNum = Num; while (tmpItem != null) { if (result != null) { result = result.After(tmpItem.GetFormula(paramsPacker)); } else { result = tmpItem.GetFormula(paramsPacker); } tmpItem = tmpItem.NextFormulaItem; } // 构造器不为空 if (result != null) { // 获取构造器链head result = result.GetFirst(); // 设置行为链链头的数据域 result.DataScope = DataScope; } return(result); }
// remain结构例子 /* * RemainNum(10000) * // remain时间行为 * Action * { * PointToPoint(1,key,0,1,10,1,1), // 需要等待其结束, 特效key(对应key,或特效path), 释放位置, 命中位置, 速度10, 飞行轨迹类型 * Point(0,key,1,0,3), // 不需要等待其结束, 特效key(对应key,或特效path), 释放位置, 播放速度, 持续3秒 * CollisionDetection(1, 1, 10, 0, 10001) * { * Calculate(1,0,%0) * } * } * // 进入remain时行为 * Enter * { * XXXXXXXXXXXXXXXX * } * // 出remain时行为 * Out * { * XXXXXXXXXXXXXXXXXXX * } * [ * Range // 作用范围 * DuringTime // 作用总时间 * ActionTime // Action时间间隔 * IsFollow // 是否跟随释放者 * ActionCamp // 作用阵营 * CouldActionOnAir // 是否可以作用到空中单位 * CouldActionOnSurface // 是否可以作用到地面单位 * CouldActionOnBuilding // 是否可以作用到建筑单位 * // 数据 * 1, 100,,,,, * 2, 200 * * ] */ /// <summary> /// 获取行为链 /// </summary> /// <param name="type">行为类型名称</param> /// <param name="args">行为</param> /// TODO 封装施法者与目标对象 /// <returns></returns> private static IFormulaItem GetFormula(string type, string args) { IFormulaItem result = null; // 错误消息 string errorMsg = null; if (string.IsNullOrEmpty(type)) { errorMsg = "函数类型为空"; } if (string.IsNullOrEmpty(errorMsg)) { // 分割数据 var argsArray = args.Split(','); // 注册列表中是否包含该类型 if (registerFormulaItem.ContainsKey(type)) { // 获取该行为的Type var formulaItemType = registerFormulaItem[type]; // 反射方式实例化行为链构造器(因为实例化的是构造器, 所以不用担心效率问题, 实际技能是使用构造器生产产生) result = (IFormulaItem)formulaItemType.InvokeMember("", BindingFlags.Public | BindingFlags.CreateInstance, null, null, new object[] { argsArray }); } else { throw new Exception("未知行为类型: " + type); } } // 如果错误信息不为空则抛出错误 if (!string.IsNullOrEmpty(errorMsg)) { throw new Exception(errorMsg); } return(result); }
/// <summary> /// 获得行为链的head /// </summary> /// <returns>行为链Head</returns> public IFormulaItem GetFirst() { IFormulaItem result = this; while (result.PreviewFormulaItem != null) { result = result.PreviewFormulaItem; } return(result); }
/// <summary> /// 添加子集行为链 /// </summary> /// <param name="formulaItem">被添加行为链</param> public void AddSubFormulaItem(IFormulaItem formulaItem) { if (formulaItem == null) { throw new Exception("行为节点为空"); } else { subFormulaItems.Add(formulaItem); } }
static int AddDetachFormulaItem(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); AbilityBase obj = (AbilityBase)ToLua.CheckObject(L, 1, typeof(AbilityBase)); IFormulaItem arg0 = (IFormulaItem)ToLua.CheckObject(L, 2, typeof(IFormulaItem)); obj.AddDetachFormulaItem(arg0); return(0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
static int GetDetachFormulaItem(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); AbilityBase obj = (AbilityBase)ToLua.CheckObject(L, 1, typeof(AbilityBase)); IFormulaItem o = obj.GetDetachFormulaItem(); ToLua.PushObject(L, o); return(1); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
static int AddSubFormulaItem(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); SkillInfo obj = (SkillInfo)ToLua.CheckObject(L, 1, typeof(SkillInfo)); IFormulaItem arg0 = (IFormulaItem)ToLua.CheckObject(L, 2, typeof(IFormulaItem)); obj.AddSubFormulaItem(arg0); return(0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
/// <summary> /// 添加触发行为生成器 /// </summary> /// <param name="formulaItem">行为单元生成器</param> public void AddActionFormulaItem(IFormulaItem formulaItem) { //if (formulaItem == null) //{ // throw new Exception("行为节点为空"); //} if (actionFormulaItem == null) { actionFormulaItem = formulaItem; } else { actionFormulaItem.After(formulaItem); } }
/// <summary> /// 添加销毁行为生成器 /// </summary> /// <param name="formulaItem">行为单元生成器</param> public void AddDetachFormulaItem(IFormulaItem formulaItem) { if (formulaItem == null) { throw new Exception("行为节点为空"); } if (detachFormulaItem == null) { detachFormulaItem = formulaItem; } else { detachFormulaItem.After(formulaItem); } }
/// <summary> /// 增加子集行为 /// </summary> /// <param name="formulaItem">被添加进行为链的节点, 不能为null</param> /// <returns>当前被添加节点</returns> public IFormulaItem AddSubFormulaItem(IFormulaItem formulaItem) { if (formulaItem == null) { throw new Exception("行为节点为空"); } if (SubFormulaItem == null) { SubFormulaItem = formulaItem; } else { SubFormulaItem.After(formulaItem); } return(formulaItem); }
/// <summary> /// 添加下一节点 /// </summary> /// <param name="nextBehavior">下一节点</param> /// <returns>当前节点</returns> public IFormulaItem After(IFormulaItem nextBehavior) { if (nextBehavior != null) { // 如果后一个单位不为空则向后移 if (NextFormulaItem != null) { NextFormulaItem.After(NextFormulaItem); } NextFormulaItem = nextBehavior; nextBehavior.PreviewFormulaItem = this; return(nextBehavior); } return(this); }
// ---------------------------私有方法----------------------------- /// <summary> /// 针对单位列表执行行为 /// </summary> /// <param name="formulaItem"></param> /// <param name="memberList"></param> private void DoActionWithList(IFormulaItem formulaItem, IEnumerable <PositionObject> memberList) { foreach (var notExistMember in memberList) { var memberDisplayOwner = DisplayerManager.Single.GetElementById(notExistMember.AllData.MemberData.ObjID); // 构建FormulaParamsPacker var packer = FormulaParamsPackerFactroy.Single.GetFormulaParamsPacker( ReleaseMember, memberDisplayOwner, null, -1); packer.SkillLevel = Level; formulaItem = formulaItem.GetFirst(); SkillManager.Single.DoFormula(GetIFormula(packer, formulaItem)); } }
// buff结构例子 /* * BuffNum(10000) * // buff被触发时行为 * Action * { * PointToPoint(1,key,0,1,10,1,1), // 需要等待其结束, 特效key(对应key,或特效path), 释放位置, 命中位置, 速度10, 飞行轨迹类型 * Point(0,key,1,0,3), // 不需要等待其结束, 特效key(对应key,或特效path), 释放位置, 播放速度, 持续3秒 * CollisionDetection(1, 1, 10, 0, 10001) * { * Calculate(1,0,%0) * } * } * // buff 创建时行为 * Attach * { * XXXXXXXXXXXXXXXX * } * // buff消失时行为 * Detach * { * XXXXXXXXXXXXXXXXXXX * } * [ * // 触发事件Level1 * TriggerLevel1(1) * // 触发事件Level2 * TriggerLevel2(1) * * // buff结束事件Level1 * DetachTriggerLevel1(1) * // buff结束事件Level2 * DetachTriggerLevel2(1) * * // buff存在时间 * BuffTime(10) * // buff检测时间 * TickTime(1) * // buff类型 * BuffType(1) * // buffLevel, 如果buff互斥则level高的会替换掉level低的, 反之不会 * BuffLevel(10) * BuffGroup(1) * // 是否为增益buff * IsBeneficial(true) * // 调整值 * ChangeData(属性名称(对应类里的属性名),变更值, 数据变更类型(0:绝对值(加), 1: 百分比(乘))) * // 数值变更类型 0: 绝对值(加), 1: 百分比(乘) * // ChangeDataType(0) * // 是否死亡消失 * IsDeadDisappear(true) * // 是否不致死 默认致死 * IsNotLethal(true) * // detach条件 key为每个节点存储在技能中的数据, 操作符判断相等与大小, 值 * DetachQualified(key,<,10) * * Description(交换空间撒很快就阿萨德阖家安康收到货%0, %1) * // 数据 * 1, 100,,,,, * 2, 200 * * ] */ /// <summary> /// 解析Remain /// </summary> /// <param name="info">字符串数据源</param> /// <returns>Remain类</returns> public static RemainInfo RemainConstructor(string info) { RemainInfo result = null; if (info != null) { // 技能ID var remainId = 0; // 数据括号 var dataBraket = false; // 当前行为栈层级 var stackLevel = 0; // 创建临时堆栈, 存储不同层级的行为链 var stack = new Stack <IFormulaItem>(); // Remain触发时行为 IFormulaItem actionFormulaItem = new PauseFormulaItem(); // Remain创建行为 IFormulaItem attachFormulaItem = new PauseFormulaItem(); // Remain销毁行为 IFormulaItem detachFormulaItem = new PauseFormulaItem(); IFormulaItem tmpItem = null; var isAction = false; var isAttach = false; var isDetach = false; // 解析字符串 // 根据对应行为列表创建Formula var infoLines = info.Split('\n'); for (var i = 0; i < infoLines.Length; i++) { var line = infoLines[i]; // 消除空格 line = line.Trim(); // 跳过空行 if (string.IsNullOrEmpty(line)) { continue; } // 跳过注释行 if (line.StartsWith("//")) { continue; } // 如果是技能描述开始 if (line.StartsWith("RemainNum")) { // 读取技能号 var pos = GetSmallBraketPos(line); var start = pos[0]; var end = pos[1]; // 读取技能ID var strSkillId = line.Substring(start + 1, end - start - 1); remainId = Convert.ToInt32(strSkillId); // 创建新技能 result = new RemainInfo(remainId); } else if (line.Equals("Action")) { // Remain触发时行为 //tmpItem = actionFormulaItem; isAction = true; isAttach = false; isDetach = false; } else if (line.Equals("Enter")) { // Remain 创建时行为 //tmpItem = attachFormulaItem; isAction = false; isAttach = true; isDetach = false; } else if (line.Equals("Out")) { // Remain 销毁时行为 //tmpItem = detachFormulaItem; isAction = false; isAttach = false; isDetach = true; } else if (line.StartsWith("{")) { // 开始括号内容 stackLevel++; // 将上级FormulaItem push进堆栈 stack.Push(tmpItem); // 如果是第一级的则根据不同行为分派不同formulaItem if (stackLevel == 1) { if (isAttach) { tmpItem = attachFormulaItem; result.HasAttachFormula = true; } else if (isAction) { tmpItem = actionFormulaItem; result.HasActionFormula = true; } else if (isDetach) { tmpItem = detachFormulaItem; result.HasDetachFormula = true; } } else { tmpItem = null; } } else if (line.StartsWith("}")) { // 关闭括号内容 stackLevel--; // 将上级FormulaItem pop出来 var prvLevelItem = stack.Pop(); if (prvLevelItem != null && tmpItem != null) { prvLevelItem.AddSubFormulaItem(tmpItem.GetFirst()); tmpItem = prvLevelItem; } else { tmpItem = null; } } else if (line.StartsWith("[")) { // 数据开始 dataBraket = true; } else if (line.StartsWith("]")) { // 数据结束 dataBraket = true; } else if (stackLevel > 0) { // 解析行为脚本 tmpItem = TransBehavior(line, tmpItem); } else if (dataBraket) { // 解析数据脚本 TransData(result, line); } } if (result == null) { throw new Exception("技能没有编号!"); } // remain触发(时间)行为 actionFormulaItem = actionFormulaItem.GetFirst(); result.AddActionFormulaItem(actionFormulaItem); // remain进入范围行为 attachFormulaItem = attachFormulaItem.GetFirst(); result.AddAttachFormulaItem(attachFormulaItem); // remain出范围行为 detachFormulaItem = detachFormulaItem.GetFirst(); result.AddDetachFormulaItem(detachFormulaItem); } return(result); }