using CommonAI.Zone;
using CommonAI.Zone.Helper;
using CommonAI.Zone.Instance;
using CommonLang;
using XmdsCommon.Plugin;
using CommonLang.Vector;
using XmdsCommonServer.Plugin.Scene;
using System.Collections.Generic;
using System;
using CommonAI.Zone.Formula;
using static XmdsCommonServer.Plugin.XmdsVirtual;
using static CommonAI.Zone.AttackProp;
using XmdsCommon.Message;
using CommonAI.Data;
using CommonAI;
namespace XmdsCommonServer.Plugin.Units
{
public class XmdsInstanceMonster : InstanceGuard
{
///
/// 储存真正的单位ID.
///
private int mMonsterID = 0;
///
/// 获取怪物真正的ID.
///
///
public int MonsterID
{
set { mMonsterID = value; }
get { return mMonsterID; }
}
private float mGuardRangeLimit;
private float mGuardRange;
private TimeExpire mIdleMoveHoldTime;
private WanderConfig mWanderConfig = null;
public XmdsInstanceMonster(InstanceZone zone, UnitInfo info, string name, int force, int level)
: base(zone, info, name, force, level)
{
mGuardRangeLimit = info.GuardRangeLimit;
mGuardRange = info.GuardRange;
if (((zone as XmdsServerScene).Data != null))
{
XmdsServerSceneData data = ((zone as XmdsServerScene).Data.Properties as XmdsSceneProperties).ServerSceneData;
//只有野外地图生效.
if (data.SceneHard == XmdsServerSceneData.NORMAL_MAP)
{
mWanderConfig = (info.Properties as XmdsUnitProperties).WanderConfigData;
if (mWanderConfig == null)
{
//编辑器未配置时走默认.
mWanderConfig = new WanderConfig();
mWanderConfig.MaxHoldTimeMS = XmdsConfig.Instance.MAX_HOLD_TIMEMS;
mWanderConfig.MinHoldTimeMS = XmdsConfig.Instance.MIN_HOLD_TIMEMS;
mWanderConfig.MaxMoveTimeMS = XmdsConfig.Instance.MAX_MOVE_TIMEMS;
mWanderConfig.MinMoveTimeMS = XmdsConfig.Instance.MIN_MOVE_TIMEMS;
mWanderConfig.WanderRange = XmdsConfig.Instance.WANDE_RRANGE;
}
if (mWanderConfig.MaxHoldTimeMS > 0)
{
mIdleMoveHoldTime =
new TimeExpire(Parent.RandomN.Next(mWanderConfig.MinHoldTimeMS, mWanderConfig.MaxHoldTimeMS));
}
}
}
}
protected override void onUpdate(bool slowRefresh)
{
base.onUpdate(slowRefresh);
this.updateIdle();
}
public HateSystem getHateSystem()
{
return this.mHateSystem;
}
protected override void OnBackToOrgin()
{
//DoUnitStateReset();
base.OnBackToOrgin();
}
public void AddEnemy(InstanceUnit target)
{
base.onAddEnemy(target, false, AttackReason.Look);
}
public override void doSomething()
{
base.doSomething();
}
public override bool IsMonster { get { return true; } }
protected override void updateBackToOrgin()
{
if (mBackToPosition != null)
{
if (mBackToPosition.IsDone)
{
mBackToPosition = null;
}
}
if (mGuardRangeLimit > mGuardRange)
{
//if (mCheckInGuardLimit.Update(Parent.UpdateIntervalMS))
if (mNextCheckGuardLimit != null && mNextCheckGuardLimit.IsTrigger())
{
//怪物会原地警戒
float mGuardRangeLimitTemp = mGuardRangeLimit + 1.5f;
if (!CMath.includeRoundPoint(X, Y, mGuardRangeLimitTemp, mOrginPosition.X, mOrginPosition.Y))
{
mHateSystem.forceRemoveAtkTraget();
//Console.WriteLine(" - - backToOrgin - 1 " + this.Info.Name);
//在自己的攻击范围内,找仇恨,目标
if(mHateSystem.updateHateList(mGuardRangeLimit, mOrginPosition) <= 0)
{
backToOrgin();
}
else
{
//boss寻找下一个攻击目标
mTracingTarget = null;
InstanceUnit unit = mHateSystem.GetHated();
if (unit is InstancePlayer)
{
}
followAndAttack(mHateSystem.GetHated(), AttackReason.Look);
}
//mHateSystem.print();
}
else if (mTracingTarget != null)
{
if (!mTracingTarget.IsActive || !CMath.intersectRound(
X, Y, mGuardRangeLimit,
mTracingTarget.TargetUnit.X,
mTracingTarget.TargetUnit.Y,
mTracingTarget.TargetUnit.BodyHitSize))
{
//Console.WriteLine(" - - backToOrgin - 2 " + this.Info.Name);
mHateSystem.Remove(mTracingTarget.TargetUnit);
if(mHateSystem.getHateSize() <= 0)
{
backToOrgin();
}else
{
//boss寻找下一个攻击目标
mTracingTarget = null;
followAndAttack(mHateSystem.GetHated(), AttackReason.Look);
}
return;
}
}
}
}
}
protected virtual void updateIdle()
{
//不能移动单位,也不游荡
if (CurrentActionStatus == UnitActionStatus.Idle && this.Moveable &&
(this.Virtual as XmdsVirtual).CombatState == BattleStatus.None)
{
if (mIdleMoveHoldTime != null && mIdleMoveHoldTime.Update(Parent.UpdateIntervalMS))
{
//发呆时间.
mIdleMoveHoldTime.Reset(Parent.RandomN.Next(mWanderConfig.MinHoldTimeMS, mWanderConfig.MaxHoldTimeMS));
//游荡时间、游荡范围.
idleMove(Parent.RandomN.Next(mWanderConfig.MinMoveTimeMS, mWanderConfig.MaxMoveTimeMS), mWanderConfig.WanderRange);
}
}
}
public override void guardInPosition(Vector2 pos)
{
if (this.IsDead() == false)
{
DoUnitStateReset();
}
if (CurrentState is StateIdleMove && pos == mOrginPosition)
{
// 浪切换到发呆,别回原点 //
base.guardInPosition(new Vector2(X, Y));
}
else
{
base.guardInPosition(pos);
}
}
//怪物返回原点时,状态重置.
private void DoUnitStateReset()
{
var v = this.Virtual as XmdsVirtual_Monster;
if (v != null)
{
v.DoUnitStateReset();
}
}
public void SetGuardRange(float r)
{
if (mViewTrigger is ViewTriggerRoundBody)
{
mGuardRange = r;
(mViewTrigger as ViewTriggerRoundBody).SetLookRange(r);
}
}
protected override void onNewStateBeginChange(State old_state, ref State new_state)
{
if (new_state is StateBackToPosition)
{
if(this.Info.Attributes != null && this.Info.Attributes.Length > 0)
{
//特殊的怪物不回血, 如要特殊处理,初始化就弄
// String par = this.Info.Attributes[0];
// if (par.Equals("noRecover"))
{
this.clearBuffs();
}
}
else
{
//回血.
this.AddHP(this.MaxHP, null);
this.AddMP(this.MaxMP, null);
this.Virtual.StartRecoverMP(true);
//去BUFF.
this.clearBuffs();
}
}
base.onNewStateBeginChange(old_state, ref new_state);
}
public override BuffState AddBuff(BuffTemplate buff, InstanceUnit sender, int pointMaxOverLayer = 0, bool forever = false, bool bMaxOverlayer = false,
int buffExt = 0, bool isControlBuf = false, bool bMaxRest = false, int addLayers = 0)
{
if (!buff.forceAdd && this.Virtual.IsBoss() && XmdsInstanceUtils.IsControlBuff_Monster(buff))//BOSS不吃控制
{
return null;
}
return base.AddBuff(buff, sender, pointMaxOverLayer, forever, bMaxOverlayer, buffExt, isControlBuf, bMaxRest, addLayers);
}
public override void InitSkills(LaunchSkill baseSkill, params LaunchSkill[] skills)
{
if (this.Virtual == null ||
(this.Virtual as XmdsVirtual).IsFinishSkillInit() == false)
{
return;
}
base.InitSkills(baseSkill, skills);
}
protected SkillState GetAvailableSkillExceptDefaultSkill()
{
SkillState ret = null;
List list = SkillStatus as List;
for (int si = list.Count - 1; si >= 0; --si)
{
SkillState sst = list[si];
if (DefaultSkill != null && sst.Data.ID != DefaultSkill.ID)
{
if (!sst.IsCD && sst.IsActive && sst.IsDone)
{
ret = sst;
break;
}
}
}
return ret;
}
public override void guard()
{
if (IsNoneSkill)
{
mTracingTarget = null;
base.startIdle();
return;
}
if (this.Info.GuardRange > 0)
{
InstanceUnit min = null;
float min_len = float.MaxValue;
bool isSpecial = false;
bool iamSpecial = Info.Properties is XmdsUnitProperties myprop && myprop.GameStatusType > XmdsUnitProperties.StatusType.Normal;
float guardRangSqua = mGuardRange * mGuardRange;
Parent.ForEachNearObjects(this.X, this.Y, this.Info.GuardRange, (InstanceUnit u, ref bool cancel) =>
{
float len = MathVector.getDistanceSquare(u.X, u.Y, this.X, this.Y);
if (len > guardRangSqua)
{
return;
}
if (!Parent.IsAttackable(this, u, SkillTemplate.CastTarget.Enemy, AttackReason.Look, Info))
{
return;
}
if (iamSpecial && u.Info.Properties is XmdsUnitProperties prop && prop.GameStatusType > XmdsUnitProperties.StatusType.Normal)
{
if (isSpecial)
{
if (len < min_len)
{
min = u;
min_len = len;
}
}
else
{
min = u;
min_len = len;
isSpecial = true;
}
}
else if (!isSpecial && min_len > len)
{
min_len = len;
min = u;
}
});
if (min != null)
{
changeState(new StateFollowAndAttack(this, min, SkillTemplate.CastTarget.Enemy));
return;
}
}
base.guard();
}
public override bool tryLaunchRandomSkillAndCancelCurrentSkill(InstanceUnit target, bool autoFocusNearTarget = false)
{
//自动战斗不允许中断当前技能施放.
return false;
}
protected override void onResetAI()
{
mTracingTarget = null;
doSomething();
}
protected override void Disposing()
{
mIdleMoveHoldTime = null;
mWanderConfig = null;
base.Disposing();
}
protected override void doHitAttack(InstanceUnit attacker, AttackSource source)
{
base.doHitAttack(attacker, source);
if (IsDead() && source.OutClientState == (int)UnitHitEventState.Crit && this.Weight < XmdsConstConfig.DEFAULT_WEIGHT
&& source.Attack.killHitMove!=null && source.Attack.killHitMove.enable)
{
HitMoveType moveType = source.Attack.killHitMove.moveType;
changeState(new StateDeadFuckFuck(this, source, attacker, moveType), true);
}
}
protected override void onBack2PositionStart()
{
(this.Virtual as XmdsVirtual_Monster).changeRunSpeed4back();
}
protected override void onBack2PositionEnd()
{
(this.Virtual as XmdsVirtual_Monster).onBack2PositionEnd();
}
protected override void onAddEnemy(InstanceUnit target, bool group, AttackReason reason)
{
var state = CurrentState;
InstanceUnit nowTarget = null;
if (state is StateFollowAndAttack attackstate)
{
nowTarget = attackstate.TargetUnit;
}
else if(state is StateSkill skillstate)
{
nowTarget = skillstate.TargetUnit;
}
//当前正在追踪/攻击一个价值更高的目标时,不理会小啰啰的攻击
if (nowTarget != null && nowTarget.Info.Properties is XmdsUnitProperties prop && prop.GameStatusType > XmdsUnitProperties.StatusType.Normal)
{
if(target.Info.Properties is XmdsUnitProperties propnew && propnew.GameStatusType > prop.GameStatusType)
{
}
else
{
return;
}
}
base.onAddEnemy(target, group, reason);
}
}
}