using System; using System.Collections.Generic; using Articy.Touhou; using Articy.Touhou.Features; using Articy.Unity; namespace Game { public enum EElementType { None, Arcane, Dark, Earth, Flame, Ice, Laya, Light, Lightning, Poison, Water, Max, Both = 99, } public partial class UtilElement { private static Dictionary _mElementReact; static UtilElement() { _mElementReact = new Dictionary(); InitElementReact(); } public static void ElementBuff(int owner, int target, string buffId, int level) { Util.AddBuff(owner, target, buffId, 0, level); } private static void AddBuff(List> elementEffectList, ArticyObject buffObj, int level, int owner) { if (buffObj != null) { elementEffectList.Add(new Tuple(buffObj.TechnicalName, level, owner)); } } public static uint ElementReact(uint elementMask, List> elementList, List> elementEffectList) { //反应规则: 1.新加入的先互相反应 2.不同元素优先反应 //反应新加入的元素 var isStable = false; while (!isStable) { isStable = true; for (int i = 0; i < elementList.Count; i++) { for (int j = i + 1; j < elementList.Count; j++) { var e1 = elementList[i]; var e2 = elementList[j]; var owner = e1.Item2 != 0 ? e1.Item2 : e2.Item2; var result = _mElementReact[Combine(e1.Item1, e2.Item1)]; var resultElement = (EElementType)result.ElementResult; if (resultElement == EElementType.Both) { continue; } isStable = false; elementList.RemoveAt(j); elementList.RemoveAt(i); if (resultElement != EElementType.None) { elementList.Add(new Tuple(resultElement, owner)); } AddBuff(elementEffectList, result.Buff, result.BuffLevel, owner); break; } if (!isStable) { break; } } } //反应不同元素 isStable = false; while (!isStable) { isStable = true; for (int i = 0; i < elementList.Count; i++) { var mask = Mask(elementList[i].Item1); if ((mask & elementMask) != 0) { //相同元素先排除 continue; } var maskNew = mask | elementMask;//新元素加入后的mask foreach (var item in _mElementReact) { var key = item.Key; if ((maskNew | key) == maskNew) { var result = _mElementReact[key]; var resultElement = (EElementType)result.ElementResult; if (resultElement == EElementType.Both) { //如果可以共存 直接加入 elementMask |= key; continue; } isStable = false; //不同元素必定反应 elementMask -= elementMask & key; //原elementMask是稳定的 if (resultElement != EElementType.None) { elementList.Add(new Tuple(resultElement, elementList[i].Item2));//生成的元素加入elementList等待下一轮反应 } AddBuff(elementEffectList, result.Buff, result.BuffLevel, elementList[i].Item2); elementList.RemoveAt(i); break; } } if (isStable) { //加入后仍然稳定 elementMask = maskNew; elementList.RemoveAt(i); } break; } } //反应相同元素 for (int i = 0; i < elementList.Count; i++) { var key = Combine(elementList[i].Item1, elementList[i].Item1); var result = _mElementReact[key]; AddBuff(elementEffectList, result.Buff, result.BuffLevel, elementList[i].Item2); } elementList.Clear(); return elementMask; } public static uint Combine(EElementType e1, EElementType e2) { if (e1 == e2) { return Mask(e1) << 16; } return Mask(e1) | Mask(e2); } public static uint Mask(EElementType e) { return (1u << (int)e); } private static void InitElementReact() { var reactList = ArticyDatabase.GetAllOfType(); foreach (var item in reactList) { var react = item.Template.ElementReact; var e1 = (EElementType)react.Element1; var e2 = (EElementType)react.Element2; _mElementReact[Combine(e1, e2)] = react; _mElementReact[Combine(e2, e1)] = react; } } } }