123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- //------------------------------------------------------------
- // Game Framework
- // Copyright © 2013-2021 Jiang Yin. All rights reserved.
- // Homepage: https://gameframework.cn/
- // Feedback: mailto:ellan@gameframework.cn
- //------------------------------------------------------------
- using System;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using UnityEngine;
- using UnityGameFramework.Runtime;
- namespace MetaClient
- {
- /// <summary>
- /// AI 工具类。
- /// </summary>
- public static class AIUtility
- {
- private static Dictionary<CampPair, RelationType> s_CampPairToRelation = new Dictionary<CampPair, RelationType>();
- private static Dictionary<KeyValuePair<CampType, RelationType>, CampType[]> s_CampAndRelationToCamps = new Dictionary<KeyValuePair<CampType, RelationType>, CampType[]>();
- static AIUtility()
- {
- s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Player), RelationType.Friendly);
- s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Enemy), RelationType.Hostile);
- s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Neutral), RelationType.Neutral);
- s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Player2), RelationType.Hostile);
- s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Enemy2), RelationType.Hostile);
- s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Neutral2), RelationType.Neutral);
- s_CampPairToRelation.Add(new CampPair(CampType.Enemy, CampType.Enemy), RelationType.Friendly);
- s_CampPairToRelation.Add(new CampPair(CampType.Enemy, CampType.Neutral), RelationType.Neutral);
- s_CampPairToRelation.Add(new CampPair(CampType.Enemy, CampType.Player2), RelationType.Hostile);
- s_CampPairToRelation.Add(new CampPair(CampType.Enemy, CampType.Enemy2), RelationType.Hostile);
- s_CampPairToRelation.Add(new CampPair(CampType.Enemy, CampType.Neutral2), RelationType.Neutral);
- s_CampPairToRelation.Add(new CampPair(CampType.Neutral, CampType.Neutral), RelationType.Neutral);
- s_CampPairToRelation.Add(new CampPair(CampType.Neutral, CampType.Player2), RelationType.Neutral);
- s_CampPairToRelation.Add(new CampPair(CampType.Neutral, CampType.Enemy2), RelationType.Neutral);
- s_CampPairToRelation.Add(new CampPair(CampType.Neutral, CampType.Neutral2), RelationType.Hostile);
- s_CampPairToRelation.Add(new CampPair(CampType.Player2, CampType.Player2), RelationType.Friendly);
- s_CampPairToRelation.Add(new CampPair(CampType.Player2, CampType.Enemy2), RelationType.Hostile);
- s_CampPairToRelation.Add(new CampPair(CampType.Player2, CampType.Neutral2), RelationType.Neutral);
- s_CampPairToRelation.Add(new CampPair(CampType.Enemy2, CampType.Enemy2), RelationType.Friendly);
- s_CampPairToRelation.Add(new CampPair(CampType.Enemy2, CampType.Neutral2), RelationType.Neutral);
- s_CampPairToRelation.Add(new CampPair(CampType.Neutral2, CampType.Neutral2), RelationType.Neutral);
- }
- /// <summary>
- /// 获取两个阵营之间的关系。
- /// </summary>
- /// <param name="first">阵营一。</param>
- /// <param name="second">阵营二。</param>
- /// <returns>阵营间关系。</returns>
- public static RelationType GetRelation(CampType first, CampType second)
- {
- if (first > second)
- {
- CampType temp = first;
- first = second;
- second = temp;
- }
- RelationType relationType;
- if (s_CampPairToRelation.TryGetValue(new CampPair(first, second), out relationType))
- {
- return relationType;
- }
- Log.Warning("Unknown relation between '{0}' and '{1}'.", first.ToString(), second.ToString());
- return RelationType.Unknown;
- }
- /// <summary>
- /// 获取和指定具有特定关系的所有阵营。
- /// </summary>
- /// <param name="camp">指定阵营。</param>
- /// <param name="relation">关系。</param>
- /// <returns>满足条件的阵营数组。</returns>
- public static CampType[] GetCamps(CampType camp, RelationType relation)
- {
- KeyValuePair<CampType, RelationType> key = new KeyValuePair<CampType, RelationType>(camp, relation);
- CampType[] result = null;
- if (s_CampAndRelationToCamps.TryGetValue(key, out result))
- {
- return result;
- }
- // TODO: GC Alloc
- List<CampType> camps = new List<CampType>();
- Array campTypes = Enum.GetValues(typeof(CampType));
- for (int i = 0; i < campTypes.Length; i++)
- {
- CampType campType = (CampType)campTypes.GetValue(i);
- if (GetRelation(camp, campType) == relation)
- {
- camps.Add(campType);
- }
- }
- // TODO: GC Alloc
- result = camps.ToArray();
- s_CampAndRelationToCamps[key] = result;
- return result;
- }
- /// <summary>
- /// 获取实体间的距离。
- /// </summary>
- /// <returns>实体间的距离。</returns>
- public static float GetDistance(Entity fromEntity, Entity toEntity)
- {
- Transform fromTransform = fromEntity.CachedTransform;
- Transform toTransform = toEntity.CachedTransform;
- return (toTransform.position - fromTransform.position).magnitude;
- }
- public static void PerformCollision(TargetableObject entity, Entity other)
- {
- if (entity == null || other == null)
- {
- return;
- }
- TargetableObject target = other as TargetableObject;
- if (target != null)
- {
- ImpactData entityImpactData = entity.GetImpactData();
- ImpactData targetImpactData = target.GetImpactData();
- if (GetRelation(entityImpactData.Camp, targetImpactData.Camp) == RelationType.Friendly)
- {
- return;
- }
- int entityDamageHP = CalcDamageHP(targetImpactData.Attack, entityImpactData.Defense);
- int targetDamageHP = CalcDamageHP(entityImpactData.Attack, targetImpactData.Defense);
- int delta = Mathf.Min(entityImpactData.HP - entityDamageHP, targetImpactData.HP - targetDamageHP);
- if (delta > 0)
- {
- entityDamageHP += delta;
- targetDamageHP += delta;
- }
- entity.ApplyDamage(target, entityDamageHP);
- target.ApplyDamage(entity, targetDamageHP);
- return;
- }
- Bullet bullet = other as Bullet;
- if (bullet != null)
- {
- ImpactData entityImpactData = entity.GetImpactData();
- ImpactData bulletImpactData = bullet.GetImpactData();
- if (GetRelation(entityImpactData.Camp, bulletImpactData.Camp) == RelationType.Friendly)
- {
- return;
- }
- int entityDamageHP = CalcDamageHP(bulletImpactData.Attack, entityImpactData.Defense);
- entity.ApplyDamage(bullet, entityDamageHP);
- GameEntry.Entity.HideEntity(bullet);
- return;
- }
- }
- private static int CalcDamageHP(int attack, int defense)
- {
- if (attack <= 0)
- {
- return 0;
- }
- if (defense < 0)
- {
- defense = 0;
- }
- return attack * attack / (attack + defense);
- }
- [StructLayout(LayoutKind.Auto)]
- private struct CampPair
- {
- private readonly CampType m_First;
- private readonly CampType m_Second;
- public CampPair(CampType first, CampType second)
- {
- m_First = first;
- m_Second = second;
- }
- public CampType First
- {
- get
- {
- return m_First;
- }
- }
- public CampType Second
- {
- get
- {
- return m_Second;
- }
- }
- }
- }
- }
|