using CommonAI.Zone.Formula;
using CommonAI.Zone.Helper;
using CommonAI.Zone.Instance;
using CommonLang;
using System.Collections.Generic;
using XmdsCommon.Plugin;
using CommonLang.Log;
namespace XmdsCommonServer.Plugin
{
public class XmdsHateSystem : HateSystem
{
//private readonly Logger log = LoggerFactory.GetLogger("XmdsHateSystem");
public readonly XmdsVirtual Virtual;
///
/// 继承者.
///
private XmdsVirtual mHeirs;
//是否寻找继承人.
private bool mFindHeirs = false;
//分享列表.
private List mSharedList = null;
//hatesystem添加单位通知.
public delegate void OnTargetAddEvent(HateInfo target);
public event OnTargetAddEvent OnHandleTargetAddEvent;
///
/// 击杀助攻列表.
///
private List mAtkAssistantList = null;
protected TimeExpire mSwithHeirsExpire;//切换归属者
public XmdsHateSystem(XmdsVirtual owner)
: base(owner.mUnit)
{
Virtual = owner;
this.mSwithHeirsExpire = new TimeExpire(10000);// 6秒切归属者
}
///
/// 设置是否计算归属权.
///
///
public void SetFindHeirs(bool flag)
{
if (flag == false && mFindHeirs != flag)
{
RemoveHeirs();
}
mFindHeirs = flag;
}
public override void Update(int intervalMS)
{
base.Update(intervalMS);
if (mHeirs != null)
{
if (this.mSwithHeirsExpire.Update(intervalMS))
{
RemoveHeirs();
}
}
}
public override void Sort()
{
base.Sort();
}
public override int Compare(HateSystem.HateInfo x, HateSystem.HateInfo y)
{
//先根据仇恨值排序.
int v = base.Compare(x, y);
//仇恨值相同时,就近原则.
if (v == 0)
{
//重载后根据距离判断,距离近的在前.
float d1 = CMath.getDistance(Virtual.mUnit.X, Virtual.mUnit.Y, x.Unit.X, x.Unit.Y);
float d2 = CMath.getDistance(Virtual.mUnit.X, Virtual.mUnit.Y, y.Unit.X, y.Unit.Y);
v = (int)(d1 - d2);
}
return v;
}
//获取攻击对象.
public override InstanceUnit GetHated(bool onlyMonster = false)
{
InstanceUnit ret = base.GetHated(onlyMonster);
if (ret != null)
{
ret = Virtual.GetAtkTarget(ret);
}
return ret;
}
///
/// 强制删除buff追击目标,只能怪物调用(怪物有攻击圈)
///
public override void forceRemoveAtkTraget() {
Virtual.forceRemoveAtkTarget();
}
protected override void onTargetAdded(HateInfo target)
{
if (this.Owner.IsDead() == false)
{
if (OnHandleTargetAddEvent != null)
{
OnHandleTargetAddEvent.Invoke(target);
}
base.onTargetAdded(target);
}
}
public void MockingInheritHatred(XmdsVirtual attacker)
{
if(unitList.Count > 1)
{
HateInfo info = unitList[0];
XmdsVirtual hateVirtual = (XmdsVirtual)info.Unit.Virtual;
long hateValue = System.Math.Min((long)(info.HateValue * 1.3), info.HateValue + hateVirtual.MirrorProp.GetFinalAttack(true) * 100);
this.SetHateInfo(attacker, hateValue);
}
else
{
this.SetHateInfo(attacker, CUtils.CastInt(attacker.MirrorProp.MaxHP));
}
}
protected override void onTargetRemoved(HateInfo target)
{
base.onTargetRemoved(target);
if (mHeirs != null)
{
if (mHeirs.mUnit.ID == target.Unit.ID)
{
if (Virtual.mUnit.IsDead() == false)
{
//移除归属者.
RemoveHeirs();
}
else
{
//移除归属者监听.
RemoveHeirsListener();
}
}
}
}
protected override void onOwnerHitted(HateInfo attacker, AttackSource attack, int reduceHP)
{
//不使用底层仇恨机制.
base.onOwnerHitted(attacker, attack, reduceHP);
}
///
/// 设置归属者,同时设置监听.
///
///
private void AddHeirs(XmdsVirtual zv)
{
if (zv is XmdsVirtual_Player)
{
if ((zv.mUnit.Info.Properties as XmdsUnitProperties).BotTestTemplate == false)
{
//log.Error("AddHeirs - " + System.DateTime.Now);
mHeirs = zv;
if (mHeirs != null)
{
int hpPercent = mHeirs.mUnit.get_current_hp()*10000/ mHeirs.mProp.ServerData.Prop.MaxHP;
Virtual.SyncHeirsInfo(mHeirs.mProp.ServerData.BaseInfo.name, hpPercent,mHeirs.mProp.ServerData.BaseInfo.ProType);
//加血监听.
mHeirs.OnHealEventHandle += MHeres_OnHealEventHandle;
//脱战监听.
mHeirs.OnCombatStateChangeHandle += MHeres_OnCombatStateChangeHandle;
}
this.mSwithHeirsExpire.Reset();
}
}
}
///
/// 移除归属者以及对应的监听.
///
private void RemoveHeirs()
{
if (mHeirs != null)
{
//log.Error("RemoveHeirs - " + System.DateTime.Now);
mHeirs.OnHealEventHandle -= MHeres_OnHealEventHandle;
mHeirs.OnCombatStateChangeHandle -= MHeres_OnCombatStateChangeHandle;
Virtual.SyncHeirsInfo(null, 0,mHeirs.mProp.ServerData.BaseInfo.ProType);
mHeirs = null;
}
}
private void RemoveHeirsListener()
{
if (mHeirs != null)
{
mHeirs.OnHealEventHandle -= MHeres_OnHealEventHandle;
mHeirs.OnCombatStateChangeHandle -= MHeres_OnCombatStateChangeHandle;
}
}
///
/// 脱战监听.
///
///
///
private void MHeres_OnCombatStateChangeHandle(XmdsVirtual unit, bool status)
{
if (status == false)
{
RemoveHeirs();
}
}
///
/// 监听仇恨对象受治愈效果.
///
///
///
///
///
private void MHeres_OnHealEventHandle(XmdsVirtual attacker, XmdsVirtual hitter, int value, ref XmdsVirtual.AtkResult result)
{
if (value > 0 && result.ThreatValue > 0)
{
int ret = CalThreatValue(value, result.ThreatValue, result.ThreatValueChangePer, result.ThreatValueChangeModify);
addTarget(attacker, ret);
}
}
///
/// 添加仇恨对象,设置仇恨值.
///
///
///
private void addTarget(XmdsVirtual target, int threatValue)
{
HateInfo ret = null;
if (this.unitMap.TryGetValue(target.mUnit.ID, out ret))
{
//donothing.
}
else
{
//加入仇恨列表.
ret = Add(target.mUnit);
}
//增加对应仇恨.
ret.HateValue += threatValue;
}
///
/// 被攻击时调用.
///
///
///
///
///
public void OnHitted(XmdsVirtual attacker, XmdsVirtual hitter, int value, ref XmdsVirtual.AtkResult result)
{
int threat = value;
if (value > 0 && result.ThreatValue > 0)
{
threat = CalThreatValue(value, result.ThreatValue, result.ThreatValueChangePer, result.ThreatValueChangeModify);
}
//归属人设置.
if (mFindHeirs)
{
if(mHeirs == null)
{
//设置继承人.
XmdsVirtual temp = null;
if (attacker is XmdsVirtual_Player)
{
AddHeirs(attacker);
}
else if (attacker is XmdsVirtual_Pet)//是宠物找主人.
{
temp = (attacker as XmdsVirtual_Pet).GetMaster();
if (temp != null)
{
AddHeirs(temp);
}
}
else if (attacker is XmdsVirtual_SummonUnit)//是召唤物,找宿主.
{
temp = (attacker as XmdsVirtual_SummonUnit).GetPlayerUnit();
if (temp != null && temp is XmdsVirtual_Player)
{
AddHeirs(temp);
}
}
}
else
{
bool isFinded = mHeirs.GetPlayerUUID() == attacker.GetPlayerUUID();
if(!isFinded)
{
if (mHeirs is XmdsVirtual_Player && attacker is XmdsVirtual_Player)
{
List lt = mHeirs.TeamList as List;
if(lt != null)
{
for (int i = 0; i < lt.Count; i++)
{
if (attacker.GetPlayerUUID() == lt[i])
{
isFinded = true;
break;
}
}
}
}
}
if(isFinded)
{
this.mSwithHeirsExpire.Reset();
}
}
}
addTarget(attacker, threat);
}
public void AddTarget(XmdsVirtual zv)
{
addTarget(zv, 0);
}
///
/// 计算仇恨值.
///
///
///
///
private int CalThreatValue(int damage, int threatValue, int threatValuePer, int threatValueModify)
{
threatValue = threatValue + threatValuePer;
int ret = 0;
if (threatValue != 0)
{
ret = (int)(damage * (threatValue / XmdsSkillTemplate.DamageCalculator.XmdsDamageCalculator.PERER));
}
return ret;
}
///
/// 销毁仇恨系统.
///
public void Dispose()
{
if (mAtkAssistantList != null)
{
mAtkAssistantList.Clear();
}
OnHandleTargetAddEvent = null;
Clear();
ClearSharedList();
RemoveHeirs();
}
///
/// 取得继承人.
///
///
public InstanceUnit GetHeirs()
{
if (mHeirs != null)
{
return mHeirs.mUnit;
}
return null;
}
public void AddSharedList(string uuid)
{
if (mSharedList == null) { mSharedList = new List(); }
mSharedList.Add(uuid);
}
public List GetSharedList()
{
return mSharedList;
}
public void ClearSharedList()
{
if (mSharedList != null)
{
mSharedList.Clear();
}
}
public void CalAtkAssistantList(bool isShare)
{
if (mAtkAssistantList != null)
{
mAtkAssistantList.Clear();
}
else
{
mAtkAssistantList = new List();
}
string uuid = null;
//仇恨值大于0的单位.
foreach (var info in unitMap)
{
if (info.Value.HateValue > 0)
{
float dist = CMath.getDistance(Owner.X, Owner.Y, info.Value.Unit.X, info.Value.Unit.Y);
//单位在范围内.
if (dist <= XmdsConfig.Instance.SHARED_AWARD_MAX_RANGE)
{
uuid = ((info.Value.Unit.Virtual) as XmdsVirtual).GetPlayerUUID();
//过滤宠物、召唤单位宿主相同情况.
if (string.IsNullOrEmpty(uuid) == false && !mAtkAssistantList.Contains(uuid))
{
mAtkAssistantList.Add(uuid);
}
}
}
}
//if(isShare)
//{
// foreach (InstancePlayer info in this.Owner.Parent.AllPlayers)
// {
// float dist = CMath.getDistance(Owner.X, Owner.Y, info.X, info.Y);
// if (dist <= XmdsConfig.Instance.SHARED_AWARD_MAX_RANGE)
// {
// uuid = info.PlayerUUID;
// if (string.IsNullOrEmpty(uuid) == false && !mAtkAssistantList.Contains(uuid))
// {
// mAtkAssistantList.Add(uuid);
// }
// }
// }
//}
}
public List GetAtkAssistantList()
{
return mAtkAssistantList;
}
///
/// 设置指定单位仇恨值.
///
///
///
public void SetHateInfo(uint id, long threatValue)
{
HateInfo ret = null;
if (this.unitMap.TryGetValue(id, out ret))
{
ret.HateValue = threatValue;
}
}
///
/// 添加仇恨对象,设置仇恨值.
///
///
///
private void SetHateInfo(XmdsVirtual target, long threatValue)
{
HateInfo ret = null;
if (this.unitMap.TryGetValue(target.mUnit.ID, out ret))
{
//donothing.
}
else
{
//加入仇恨列表.
ret = Add(target.mUnit);
}
//增加对应仇恨.
ret.HateValue = threatValue;
}
public void ClearAllThreatValue()
{
if (unitMap != null)
{
foreach (var kvp in unitMap)
{
kvp.Value.HateValue = 0;
}
}
}
}
}