2
0
Fork 0
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#

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;
}
}
}
}