using Thousandto.Code.Logic; using Thousandto.Core.Base; using Thousandto.Core.Support; using Thousandto.SkillEditor; using Thousandto.SkillEditor.Support; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security; using System.Text; using UnityEditor; using UnityEngine; using MonoXmlUtils = UnityEngine.Gonbest.MagicCube.MonoXmlUtils; namespace Thousandto.SkillEditor.DIY { public class SkillEditorData { public static List SkillList = new List(); public static string[] SkillNames = new string[1]; public static SkillVisualInfo FindSkill(String name) { for (int i = 0; i < SkillList.Count; ++i) { if (SkillList[i].Name == name) return SkillList[i]; } return null; } public static bool CreateNewSkill(string name) { for (int i = 0; i < SkillList.Count; ++i) { if (SkillList[i].Name == name) return false; } SkillVisualInfo data = new SkillVisualInfo(); data.Name = name; data.FrameCount = 30; PlayAnimEventInfo playAnim = new PlayAnimEventInfo(); playAnim.EventFrame = 0; playAnim.EventType = SkillEventDefine.PlayAnimation; playAnim.EventID = 1; playAnim.ParseData(String.Empty); data.DataList.Add(playAnim); PlayVfxEventInfo playVfx = new PlayVfxEventInfo(); playVfx.EventFrame = 0; playVfx.EventType = SkillEventDefine.PlayVfx; playVfx.EventID = 2; playVfx.ParseData(String.Empty); data.DataList.Add(playVfx); DisableMoveEventInfo disMove = new DisableMoveEventInfo(); disMove.EventFrame = 0; disMove.EventType = SkillEventDefine.DisableMove; disMove.EventID = 3; disMove.ParseData(String.Empty); data.DataList.Add(disMove); DisableChangeDirEventInfo disDir = new DisableChangeDirEventInfo(); disDir.EventFrame = 0; disDir.EventType = SkillEventDefine.DisableChangeDir; disDir.EventID = 4; disDir.ParseData(String.Empty); data.DataList.Add(disDir); SkillList.Add(data); return true; } public static string CopyNewSkill(SkillVisualInfo skill) { SkillVisualInfo data = new SkillVisualInfo(); String newName = String.Empty; bool findName = true; int index = 1; while (findName) { bool haveName = false; newName = String.Format("{0}_{1}", skill.Name, index); for (int i = 0; i < SkillList.Count; ++i) { if (SkillList[i].Name == newName) { haveName = true; break; } } ++index; findName = haveName; } data.Name = newName; data.FrameCount = skill.FrameCount; for (int i = 0; i < skill.DataList.Count; ++i) { var enentData = skill.DataList[i]; SkillBaseEventInfo newEvent = SkillVisualInfoLoader.NewEventInfo(enentData.EventType); newEvent.EventID = enentData.EventID; newEvent.EventFrame = enentData.EventFrame; newEvent.EventType = enentData.EventType; newEvent.ParseData(enentData.ToString()); data.DataList.Add(newEvent); } SkillList.Add(data); return data.Name; } public static void RemoveSkill(int index) { if (index < 0 || index >= SkillList.Count) return; SkillList.RemoveAt(index); } public static void RemoveSkill(string name) { for (int i = 0; i < SkillList.Count; ++i) { if (SkillList[i].Name == name) { SkillList.RemoveAt(i); break; } } } //读取文件文本信息 public static string ReadFileText(string fullPath) { if (File.Exists(fullPath)) { return File.ReadAllText(fullPath); } return null; } public static void Load() { HitEffectInfo.ResetIDCouter(); SkillList.Clear(); var text = ReadFileText(SkillConstDefine.SkillCfgXMLFullPath); if (string.IsNullOrEmpty(text)) { UnityEngine.Debug.LogError(String.Format("dont found file: {0}", SkillConstDefine.SkillCfgXMLFullPath)); return; } var root = MonoXmlUtils.GetRootNodeFromString(text); if (root == null || root.Children == null) { return; } for (int i = 0; i < root.Children.Count && root.Children != null; i++) { var child = root.Children[i] as SecurityElement; var skillData = SkillVisualInfoLoader.Load(child); if (skillData != null) SkillList.Add(skillData); } SkillList.Sort((left, right) => { return left.Name.CompareTo(right.Name); }); } public static void Save() { Dictionary nameTable = new Dictionary(); SecurityElement rootElement = new SecurityElement("Root"); var iter = SkillList.GetEnumerator(); while (iter.MoveNext()) { var skill = iter.Current; if (!nameTable.ContainsKey(skill.Name)) { nameTable.Add(skill.Name, 1); } else { //重命名 String newName = String.Empty; bool findName = true; int index = 1; while (findName) { bool haveName = false; newName = String.Format("{0}_{1}", skill.Name, index); for (int i = 0; i < SkillList.Count; ++i) { if (SkillList[i].Name == newName) { haveName = true; break; } } ++index; findName = haveName; } skill.Name = newName; nameTable.Add(skill.Name, 1); } SecurityElement skillRoot = new SecurityElement("SkillInfo"); skillRoot.AddAttribute("Name", skill.Name); //技能名字 skillRoot.AddAttribute("FrameCount", skill.FrameCount.ToString()); skillRoot.AddAttribute("IsSkillObject", skill.IsSkillObject ? "1" : "0"); skillRoot.AddAttribute("IsPlayerValid", skill.IsPlayerValid ? "1" : "0"); skillRoot.AddAttribute("EndClearVfx", skill.EndClearVfx ? "1" : "0"); skillRoot.AddAttribute("WaitServerResult", skill.WaitServerResult ? "1" : "0"); skill.DataList.Sort((left, right) => { if (left.EventFrame == right.EventFrame) return left.EventID.CompareTo(right.EventID); return left.EventFrame.CompareTo(right.EventFrame); }); Dictionary idDic = new Dictionary(); for (int i = 0; i < skill.DataList.Count; ++i) { var evData = skill.DataList[i]; int idIndex = 1; if (idDic.TryGetValue(evData.EventFrame, out idIndex)) { ++idIndex; idDic[evData.EventFrame] = idIndex; } else { idDic.Add(evData.EventFrame, idIndex); } evData.EventID = evData.EventFrame * 1000 + idIndex; SecurityElement sevent = new SecurityElement("Event"); sevent.AddAttribute("ID", evData.EventID.ToString()); sevent.AddAttribute("Frame", evData.EventFrame.ToString()); int evID = (int)evData.EventType; sevent.AddAttribute("EventType", evID.ToString()); sevent.AddAttribute("Param", evData.ToString()); skillRoot.AddChild(sevent); } rootElement.AddChild(skillRoot); } if (!File.Exists(SkillConstDefine.SkillCfgXMLFullPath)) { var stream = File.Create(SkillConstDefine.SkillCfgXMLFullPath); if (stream != null) { stream.Close(); } } MonoXmlUtils.WriteSecurityElementToFile(rootElement, SkillConstDefine.SkillCfgXMLFullPath, "1.0", "utf-8"); AssetDatabase.SaveAssets(); } private static void FillUseNeedType(SkillVisualInfo visualInfo) { FindTargetInfo findInfo = null; visualInfo.UseNeedType = SkillUseNeedType.None; var hitEventList = visualInfo.FindEvent(SkillEventDefine.PlayHit); if(hitEventList.Count > 0) { //伤害事件 var info = hitEventList[0] as PlayHitEventInfo; if (findInfo == null || (findInfo.AreaType != info.FindInfo.AreaType && info.FindInfo.AreaType != SkillTargetArea.Round)) { findInfo = info.FindInfo; visualInfo.UseNeedType = SkillUseNeedType.Dir; switch (findInfo.AreaType) { case SkillTargetArea.Rectangle: //矩形,可以选择矩形方向 visualInfo.SelectFiledType = SkillSelectFiledType.SelectDir; visualInfo.SelectDirType = SkillSelectDirType.Rect; visualInfo.DirSelectParam1 = findInfo.RectHeight; visualInfo.DirSelectParam2 = findInfo.RectWidth; visualInfo.UseNeedDis = findInfo.RectHeight; break; case SkillTargetArea.FanShaped: //扇形,可以选择扇形方向 visualInfo.SelectFiledType = SkillSelectFiledType.SelectDir; visualInfo.SelectDirType = SkillSelectDirType.FanShaped; visualInfo.DirSelectParam1 = findInfo.SectorRadius; visualInfo.DirSelectParam2 = findInfo.SectorAngle; visualInfo.UseNeedDis = findInfo.SectorRadius; break; case SkillTargetArea.Round: //圆形,不需要选择 visualInfo.SelectFiledType = SkillSelectFiledType.None; visualInfo.UseNeedDis = findInfo.RoundRadius; break; } } } else { for (int i = 0; i < visualInfo.DataList.Count; ++i) { if (visualInfo.DataList[i].EventType == SkillEventDefine.PlayHit) { //伤害事件 var info = visualInfo.DataList[i] as PlayHitEventInfo; if (findInfo == null || (findInfo.AreaType != info.FindInfo.AreaType && info.FindInfo.AreaType != SkillTargetArea.Round)) { findInfo = info.FindInfo; visualInfo.UseNeedType = SkillUseNeedType.Dir; switch (findInfo.AreaType) { case SkillTargetArea.Rectangle: //矩形,可以选择矩形方向 visualInfo.SelectFiledType = SkillSelectFiledType.SelectDir; visualInfo.SelectDirType = SkillSelectDirType.Rect; visualInfo.DirSelectParam1 = findInfo.RectHeight; visualInfo.DirSelectParam2 = findInfo.RectWidth; visualInfo.UseNeedDis = findInfo.RectHeight; break; case SkillTargetArea.FanShaped: //扇形,可以选择扇形方向 visualInfo.SelectFiledType = SkillSelectFiledType.SelectDir; visualInfo.SelectDirType = SkillSelectDirType.FanShaped; visualInfo.DirSelectParam1 = findInfo.SectorRadius; visualInfo.DirSelectParam2 = findInfo.SectorAngle; visualInfo.UseNeedDis = findInfo.SectorRadius; break; case SkillTargetArea.Round: //圆形,不需要选择 visualInfo.SelectFiledType = SkillSelectFiledType.None; visualInfo.UseNeedDis = findInfo.RoundRadius; break; } } } else if (visualInfo.DataList[i].EventType == SkillEventDefine.PlayLockTrajectory) { //锁定弹道 var info = visualInfo.DataList[i] as PlayLockTrajectoryEventInfo; findInfo = info.FindInfo; visualInfo.UseNeedType = SkillUseNeedType.Target; visualInfo.SelectFiledType = SkillSelectFiledType.None; switch (findInfo.AreaType) { case SkillTargetArea.Rectangle: visualInfo.UseNeedDis = findInfo.RectHeight; break; case SkillTargetArea.FanShaped: visualInfo.UseNeedDis = findInfo.SectorRadius; break; case SkillTargetArea.Round: visualInfo.UseNeedDis = findInfo.RoundRadius; break; } break; } else if (visualInfo.DataList[i].EventType == SkillEventDefine.PlaySimpleSkillObject) { //简单召唤物 var info = visualInfo.DataList[i] as PlaySimpleSkillObjectEventInfo; if (info.PosType == 0) { visualInfo.UseNeedType = SkillUseNeedType.None; visualInfo.SelectFiledType = SkillSelectFiledType.None; } else { visualInfo.UseNeedType = SkillUseNeedType.Pos; visualInfo.SelectFiledType = SkillSelectFiledType.SelectPos; visualInfo.PosBigRoundSize = info.MaxDis; switch (info.FindInfo.AreaType) { case SkillTargetArea.Rectangle: visualInfo.PosSmallRoundSize = info.FindInfo.RectWidth; break; case SkillTargetArea.FanShaped: visualInfo.PosSmallRoundSize = info.FindInfo.SectorRadius; break; case SkillTargetArea.Round: visualInfo.PosSmallRoundSize = info.FindInfo.RoundRadius; break; } } visualInfo.UseNeedDis = info.MaxDis; break; } else if (visualInfo.DataList[i].EventType == SkillEventDefine.PlaySkillObject) { //复杂召唤物 var info = visualInfo.DataList[i] as PlaySkillObjectEventInfo; if (info.PosType == 0) { visualInfo.UseNeedType = SkillUseNeedType.None; visualInfo.SelectFiledType = SkillSelectFiledType.None; } else { visualInfo.UseNeedType = SkillUseNeedType.Pos; visualInfo.PosBigRoundSize = info.MaxDis; var objSkill = FindSkill(info.SkillName); if (objSkill != null) { var hitList = objSkill.FindEvent(SkillEventDefine.PlayHit); if (hitList.Count > 0) { visualInfo.SelectFiledType = SkillSelectFiledType.SelectPos; var objFindInfo = hitList[0] as PlayHitEventInfo; switch (objFindInfo.FindInfo.AreaType) { case SkillTargetArea.Rectangle: visualInfo.PosSmallRoundSize = objFindInfo.FindInfo.RectWidth; break; case SkillTargetArea.FanShaped: visualInfo.PosSmallRoundSize = objFindInfo.FindInfo.SectorRadius; break; case SkillTargetArea.Round: visualInfo.PosSmallRoundSize = objFindInfo.FindInfo.RoundRadius; break; } } else { visualInfo.SelectFiledType = SkillSelectFiledType.None; } } else { visualInfo.SelectFiledType = SkillSelectFiledType.None; } } visualInfo.UseNeedDis = info.MaxDis; break; } } } } public static void SaveBinary() { FileStream fs = null; try { fs = new FileStream(SkillConstDefine.SkillCfgBinaryFullPath, FileMode.Create, FileAccess.Write); var writer = new BinaryWriter(fs); BinarySerializer.Write_Int32(writer, SkillList.Count); for (int i = 0; i < SkillList.Count; ++i) { var skill = SkillList[i]; //填充技能使用需求 FillUseNeedType(skill); BinarySerializer.Write_String(writer, skill.Name); BinarySerializer.Write_Int32(writer, skill.FrameCount); BinarySerializer.Write_Int32(writer, skill.IsSkillObject ? 1 : 0); BinarySerializer.Write_Int32(writer, skill.IsPlayerValid ? 1 : 0); BinarySerializer.Write_Int32(writer, skill.EndClearVfx ? 1 : 0); BinarySerializer.Write_Int32(writer, skill.WaitServerResult ? 1 : 0); BinarySerializer.Write_Int32(writer, (int)skill.UseNeedType); BinarySerializer.Write_Single(writer, skill.UseNeedDis); BinarySerializer.Write_Int32(writer, (int)skill.SelectFiledType); BinarySerializer.Write_Int32(writer, (int)skill.SelectDirType); BinarySerializer.Write_Single(writer, skill.PosBigRoundSize); BinarySerializer.Write_Single(writer, skill.PosSmallRoundSize); BinarySerializer.Write_Single(writer, skill.DirSelectParam1); BinarySerializer.Write_Single(writer, skill.DirSelectParam2); BinarySerializer.Write_Int32(writer, skill.DataList.Count); for (int j = 0; j < skill.DataList.Count; ++j) { var skillevent = skill.DataList[j]; BinarySerializer.Write_Int32(writer, skillevent.EventID); BinarySerializer.Write_Int32(writer, skillevent.EventFrame); BinarySerializer.Write_Int32(writer, (int)skillevent.EventType); skillevent.WriteData(writer); } } } catch (IOException e) { Debug.LogError("Save Skill Binary data failed! " + e); } finally { if (fs != null) { fs.Close(); } AssetDatabase.SaveAssets(); } } } }