You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			164 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			164 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C#
		
	
| 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<uint, ElementReactFeature> _mElementReact;
 | |
|         static UtilElement()
 | |
|         {
 | |
|             _mElementReact = new Dictionary<uint, ElementReactFeature>();
 | |
|             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<Tuple<string, int, int>> elementEffectList, ArticyObject buffObj, int level, int owner)
 | |
|         {
 | |
|             if (buffObj != null)
 | |
|             {
 | |
|                 elementEffectList.Add(new Tuple<string, int, int>(buffObj.TechnicalName, level, owner));
 | |
|             }
 | |
|         }
 | |
|         public static uint ElementReact(uint elementMask, List<Tuple<EElementType, int>> elementList, List<Tuple<string, int, int>> 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<EElementType, int>(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<EElementType, int>(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<ElementReact>();
 | |
|             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;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| } |