/// <summary> /// 复制RemainInfo信息 /// </summary> /// <param name="remainInfo">被复制信息</param> /// <returns>复制数据</returns> public RemainInfo CopyRemainInfo([NotNull] RemainInfo remainInfo) { RemainInfo result = null; result = new RemainInfo(remainInfo.Num) { ActionTime = remainInfo.ActionTime, ActionCamp = remainInfo.ActionCamp, CouldActionOnAir = remainInfo.CouldActionOnAir, CouldActionOnBuilding = remainInfo.CouldActionOnBuilding, CouldActionOnSurface = remainInfo.CouldActionOnSurface, DataList = remainInfo.DataList, DuringTime = remainInfo.DuringTime, FixPostion = remainInfo.FixPostion, HasActionFormula = remainInfo.HasActionFormula, HasAttachFormula = remainInfo.HasAttachFormula, HasDetachFormula = remainInfo.HasDetachFormula, IsFollow = remainInfo.IsFollow, Range = remainInfo.Range, ReplaceSourceDataDic = remainInfo.ReplaceSourceDataDic }; result.AddActionFormulaItem(remainInfo.GetActionFormulaItem()); result.AddAttachFormulaItem(remainInfo.GetAttachFormulaItem()); result.AddDetachFormulaItem(remainInfo.GetDetachFormulaItem()); return(result); }
/// <summary> /// 添加remain原始类到缓存中 /// </summary> /// <param name="remainInfo">remain类</param> public void AddRemainInfo(RemainInfo remainInfo) { if (remainInfo == null) { throw new Exception("技能对象为空!"); } // 是否已存在remainID if (remainDic.ContainsKey(remainInfo.Num)) { throw new Exception("已存在remain编号:" + remainInfo.Num); } remainDic.Add(remainInfo.Num, remainInfo); }
/// <summary> /// 加载Remain类 /// 如果缓存中没有就从文件照片那个加载 /// </summary> /// <param name="remainId">RemainID</param> /// <param name="release">Remain的释放者</param> /// <param name="level">Remain等级</param> /// <returns></returns> public RemainInfo CreateRemainInfo(int remainId, DisplayOwner release, int level = 1) { RemainInfo result = null; // 验证技能ID的有效性 if (remainId > 0) { // 检查缓存 if (remainDic.ContainsKey(remainId)) { // 复制buff result = remainDic[remainId]; } else { // 加载文件内容 var buffTxt = GetRemainScript(remainId, SkillManager.Single.RunType); if (!string.IsNullOrEmpty(buffTxt)) { result = FormulaConstructor.RemainConstructor(buffTxt); // 将其放入缓存 AddRemainInfo(result); } } } if (result == null) { return(null); } result = CopyRemainInfo(result); result.ReplaceData(level); // 将实现放入实现列表 remainInstanceDic.Add(result.AddtionId, result); result.ReleaseMember = release; return(result); }
// 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); }
/// <summary> /// 解析Remain数据 /// </summary> /// <param name="remainInfo">Remain类</param> /// <param name="line">数据行</param> private static void TransData(RemainInfo remainInfo, string line) { // 解析数据 if (remainInfo == null) { throw new Exception("remainID未指定.remain类为空"); } var pos = GetSmallBraketPos(line, false); var start = pos[0]; var end = pos[1]; // 编号长度 var length = end - start - 1; if (end > 0 && start > 0) { var strVal = line.Substring(start + 1, length).Trim(); var symbol = line.Substring(0, start).Trim(); switch (symbol) { // 总持续时间 case "DuringTime": { remainInfo.DuringTime = remainInfo.GetDataOrReplace <float>("DuringTime", strVal); } break; // 作用时间间隔 case "ActionTime": { remainInfo.ActionTime = remainInfo.GetDataOrReplace <float>("ActionTime", strVal); } break; // 作用范围 case "Range": { remainInfo.Range = remainInfo.GetDataOrReplace <float>("Range", strVal); } break; // 是否跟随 case "IsFollow": { remainInfo.IsFollow = remainInfo.GetDataOrReplace <bool>("IsFollow", strVal); } break; // 作用阵营 case "ActionCamp": { remainInfo.ActionCamp = remainInfo.GetDataOrReplace <int>("ActionCamp", strVal); } break; // 是否可以作用到空中单位 case "CouldActionOnAir": { remainInfo.CouldActionOnAir = remainInfo.GetDataOrReplace <bool>("CouldActionOnAir", strVal); } break; // 是否可以作用到地面单位 case "CouldActionOnSurface": { remainInfo.CouldActionOnSurface = remainInfo.GetDataOrReplace <bool>("CouldActionOnSurface", strVal); } break; // 是否可以作用到建筑 case "CouldActionOnBuilding": { remainInfo.CouldActionOnBuilding = remainInfo.GetDataOrReplace <bool>("CouldActionOnBuilding", strVal); } break; } } else if (start < 0 && end < 0) { // 解析数据脚本 var dataArray = line.Split(','); var dataList = dataArray.ToList(); remainInfo.DataList.Add(dataList); } else { ValidSmallBraketIndex(start, end, line); } }
/// <summary> /// 初始化技能 /// </summary> private void InitSkill() { // 加载技能 string formulaStr = @"SkillNum(1001) { Point(1,test/ExplordScope,0,0,3,10,1,10), CollisionDetection(0, 10, 1, 0, -1, 10, 0, 0, -1, 1) { Skill(1, 1002, 1) //PointToObj(1,test/TrailPrj,10,0,10,1,10), //Point(1,test/ExplordScope,1,0,3,10,1,10), } }"; string formulaStr2 = @"SkillNum(1002) { PointToObj(1,test/TrailPrj,10,0,10,1,10), Point(1,test/ExplordScope,0,3,10,1,10), }"; string formulaStr3 = @"SkillNum(1003) { SlideCollisionDetection(1, 0, 2, 1, {%0}, 40, -1) { //PointToObj(1,test/TrailPrj,10,0,10,1,10), Point(1,test/ExplordScope,1,{%1},10,1,10), } } // 数据 [ TriggerLevel1(1) TriggerLevel2(1) 100, 5 ] "; string formulaStr4 = @"SkillNum(1004) { TargetPointSelector(1,3,90,0) //Move(1, 2, 3, false) SlideCollisionDetection(1, 0, 2, 1, 100, 40, -1) //PointToPoint(1,test/TrailPrj,0,2,10,0,10,1,10), } [ IsActive(true,101001) ] "; string formulaStr5 = @"SkillNum(1005) { SlideCollisionDetection(1, 0, 2, 1, {%0}, 40, -1) { //If(1, 0, Health, 0_100) //{ HealthChange(1,0,0,0,1) //PointToObj(1,test/TrailPrj,10,0,10,1,10), Point(1,test/ExplordScope,1,{%1},10,1,10), //} } } [ TriggerLevel1(1) TriggerLevel2(1) Description(哟哦哦{%0},哦哟哦哟{%1}) 100, 5 ] "; string formulaStr6 = @"SkillNum(1006) { HealthChange(1,0,0,0,1) } "; string formulaStr7 = @"SkillNum(1007) { SlideCollisionDetection(1, 0, 2, 1, {%0}, 40, -1) { //If(1, 0, Health, 0_100) //{ Buff(1,1007, 1) Buff(1,1008, 1) //PointToObj(1,test/TrailPrj,10,0,10,1,10), //Point(1,test/ExplordScope,1,{%1},10,1,10), //} } } [ CDTime(1) CDGroup(2) Icon(test/Icon1) ReleaseTime(10) TriggerLevel1(1) TriggerLevel2(1) Description(Test{%0},测试{%1}) 100, 5 ] "; string formulaStr8 = @"SkillNum(1008) { // 选择目标点 TargetPointSelector(1,3,<Attack1>+10,0) Remain(1, 2, 10000, false) } [ CDTime(1) CDGroup(2) Icon(test/Icon1) ReleaseTime(10) TriggerLevel1(1) TriggerLevel2(1) Description(Test{%0},测试{%1}) 10, 5 ] "; string formulaStr9 = @"SkillNum(1009) { CollisionDetection(0, 50, 1, 1, -1, 100, 100, 0, 101009, true) { //If(1,0,IsMechanic,false_true) //{ PointToObj(1,zidan1.prefab,10,0,10,1,10), //Point(1,test/ExplordScope,1,0,3,10,1,10), //} } // 选择目标点 // TargetPointSelector(1,0,10,10) // Remain(1, 2, 10000, false) } [ CDTime(1) CDGroup(2) Icon(test/Icon1) ReleaseTime(10) TriggerLevel1(1) TriggerLevel2(1) Description(Test{%0},测试{%1}) 100, 5 ] "; string formulaStr10 = @"SkillNum(1010) { Death(1,0) } "; string formulaStr11 = @"SkillNum(1011) { SummonedUnit(1,1,3,101001,1) } "; string formulaStr12 = @"SkillNum(10006) Action { } [ ChangeData(IsDambody, true, 0) ] "; string buffStr1 = @"BuffNum(1007) Action { HealthChange(1,0,0,0,1,1,0) } [ TickTime(1) BuffTime(10) TriggerLevel1(4) TriggerLevel2(18) BuffLevel(1) BuffGroup(1) ChangeData(CurrentHP,100,0) ] "; string buffStr2 = @"BuffNum(1008) Action { ResistDemage(1,3,1,true) { Point(1,test/ExplordScope,0,3,10,1,10), } } [ BuffTime(10) TriggerLevel1(3) TriggerLevel2(10) DetachTriggerLevel1(3) DetachTriggerLevel2(10) DetachQualified(ResistDemage,<=,0.0f) ] "; // 光环1 string remainStr1 = @"RemainNum(10000) Action { //Point(1,test/ExplordScope,0,3,10,1,10) } Enter { Point(1,test/ExplordScope,1,5,10,1,10) } Out { Point(1,test/ExplordScope,1,5,10,1,10) } [ Range(60) DuringTime(10) ActionTime(1) ActionCamp(1) IsFollow(false) ] "; //var skillInfo = FormulaConstructor.SkillConstructor(formulaStr); //var skillInfo2 = FormulaConstructor.SkillConstructor(formulaStr2); //var skillInfo3 = FormulaConstructor.SkillConstructor(formulaStr3); //var skillInfo4 = FormulaConstructor.SkillConstructor(formulaStr4); //var skillInfo5 = FormulaConstructor.SkillConstructor(formulaStr5); //var skillInfo7 = FormulaConstructor.SkillConstructor(formulaStr7); var skillInfo8 = FormulaConstructor.SkillConstructor(formulaStr8); var skillInfo9 = FormulaConstructor.SkillConstructor(formulaStr9); var skillInfo10 = FormulaConstructor.SkillConstructor(formulaStr10); var skillInfo11 = FormulaConstructor.SkillConstructor(formulaStr11); var skillInfo12 = FormulaConstructor.SkillConstructor(formulaStr12); var buffInfo1 = FormulaConstructor.BuffConstructor(buffStr1); var buffInfo2 = FormulaConstructor.BuffConstructor(buffStr2); remain = FormulaConstructor.RemainConstructor(remainStr1); //SkillManager.Single.AddSkillInfo(skillInfo); //SkillManager.Single.AddSkillInfo(skillInfo2); //SkillManager.Single.AddSkillInfo(skillInfo3); //SkillManager.Single.AddSkillInfo(skillInfo4); //SkillManager.Single.AddSkillInfo(skillInfo5); //SkillManager.Single.AddSkillInfo(skillInfo7); SkillManager.Single.AddSkillInfo(skillInfo8); SkillManager.Single.AddSkillInfo(skillInfo9); SkillManager.Single.AddSkillInfo(skillInfo10); SkillManager.Single.AddSkillInfo(skillInfo11); SkillManager.Single.AddSkillInfo(skillInfo12); BuffManager.Single.AddBuffInfo(buffInfo1); BuffManager.Single.AddBuffInfo(buffInfo2); RemainManager.Single.AddRemainInfo(remain); //Debug.Log(skillInfo5.GetReplacedDescription(1)); //foreach (var item in "{%1} + {%2}{%3}".Split('{', '}')) //{ // Debug.Log(item); //} }