Files
Main/Assets/Editor/DIY/SkillEditor/SkillEditorData.cs

498 lines
22 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
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();
}
}
}
}