498 lines
22 KiB
C#
498 lines
22 KiB
C#
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<SkillVisualInfo> SkillList = new List<SkillVisualInfo>();
|
|
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<String, int> nameTable = new Dictionary<string, int>();
|
|
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<int, int> idDic = new Dictionary<int, int>();
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
}
|