123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- using CommonAI.RTS;
- using CommonLang.Vector;
- using CommonAI.Zone.Helper;
- using CommonLang;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using CommonAI.Zone.Instance.Helper;
- using CommonAI.Data;
- namespace CommonAI.Zone.Instance
- {
- public class InstancePet : InstanceUnit, ISummonedUnit
- {
- protected InstanceUnit mMaster;
- protected StateFollowMaster mFollowMaster;
- public InstanceUnit Owner { get { return this; } }
- public InstancePet(InstanceZone zone, UnitInfo info, string name, int force, int level)
- : base(zone, info, name, force, level)
- {
- s_mFollowDistance = Templates.CFG.PET_FOLLOW_DISTANCE_MIN + (Templates.CFG.PET_FOLLOW_DISTANCE_MAX - Templates.CFG.PET_FOLLOW_DISTANCE_MIN) / 2;
- }
- public override bool IntersectMap { get { return Info.BodySize > 0; } }
- public override bool IntersectObj { get { return false; } }
- public override bool IsActive { get { return false; } }
- public override bool IsAttackable { get { return false; } }
- /// <summary>
- /// 获取主人
- /// </summary>
- public virtual InstanceUnit Master
- {
- get { return mMaster; }
- set { this.mMaster = value; this.mFollowMaster = new StateFollowMaster(this, mMaster); }
- }
- public virtual InstanceUnit SummonerUnit
- {
- get { return Master; }
- set { Master = value; }
- }
- /// <summary>
- /// IAO标记
- /// </summary>
- public override ObjectAoiStatus AoiStatus { get { return this.Master == null ? base.AoiStatus : this.Master.AoiStatus; } }
- // 跟随最大最小距离的中间值
- public static float s_mFollowDistance = 0;
- protected override void onUpdate(bool slowRefresh)
- {
- base.onUpdate(slowRefresh);
- OnPetUpdate();
- }
- protected virtual void OnPetUpdate()
- {
- if (mMaster != null)
- {
- if (mMaster.IsDead() || !mMaster.Enable)
- {
- this.kill(this);
- }
- else if (!CMath.includeRoundPoint(X, Y, Templates.CFG.PET_FOLLOW_DISTANCE_LIMIT, mMaster.X, mMaster.Y))
- {
- this.transportToMaster();
- }
- else if (!CMath.includeRoundPoint(X, Y, Templates.CFG.PET_FOLLOW_DISTANCE_MAX, mMaster.X, mMaster.Y))
- {
- this.followMaster();
- }
- }
- if (CurrentState is StateIdle)
- {
- doSomething2();
- }
- }
- protected void transportToMaster()
- {
- float dx, dy;
- CMath.RandomPosInRound(Parent.RandomN, mMaster.X, mMaster.Y, Templates.CFG.PET_FOLLOW_DISTANCE_MAX, out dx, out dy);
- if (IntersectMap && Parent.TryTouchMap(this, dx, dy))
- {
- dx = Master.X;
- dy = Master.Y;
- }
- this.Virtual.SetCombatState(BattleStatus.None);
- this.transport(dx, dy);
- this.followMaster();
- }
- protected void followMaster()
- {
- StateSkill skillState = this.CurrentState as StateSkill;
- if (skillState != null && skillState.Skill != null && !skillState.IsCancelableByMove)
- {
- return;
- }
- else if(CurrentState == mFollowMaster)
- {
- return;
- }
-
- //float distanceTemp = MathVector.getDistance(this.X, this.Y, this.Master.X, this.Master.Y);
- float speedChag = 1.01f;// (distanceTemp < s_mFollowDistance) ? 1.01f : 1.1f;
- this.followMasterChangeSpeed(speedChag);
- changeState(mFollowMaster);
- //System.Console.WriteLine("---followMaster: " + TimeUtil.GetTimestampMS() + speedChag);
- }
- protected virtual void followMasterChangeSpeed(float speedChag)
- {
- // 随从使用主人的速度
- if (this.Master != null)
- {
- this.SetMoveSpeed(this.Master.MoveSpeedSEC * speedChag);
- }
- }
- protected void doSomething2()
- {
- if (!IsNoneSkill)
- {
- using (var list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
- {
- //随机找个目标施法//
- Parent.getObjectsRoundRange<InstanceUnit>(Collider.Object_Pos_IncludeInRound, X, Y, Info.GuardRange, list, this.AoiStatus);
- DoAndRemoveCollection.UpdateAndRemove<InstanceUnit>(list, (InstanceUnit u) =>
- {
- return !u.IsActive;
- });
- CUtils.RandomList(Parent.RandomN, list);
- foreach (SkillState skill in SkillStatus)
- {
- if (skill.LaunchSkill.AutoLaunch && skill.TryLaunch())
- {
- foreach (InstanceUnit u in list)
- {
- if (Parent.IsAttackable(this, u, skill.Data.ExpectTarget, AttackReason.Look, skill.Data))
- {
- //检测是否有可释放技能//
- if (tryAutoLaunch(skill, u))
- {
- return;
- }
- }
- }
- }
- }
- }
- }
- }
- protected virtual bool tryAutoLaunch(SkillState st, InstanceUnit target)
- {
- if (st != null && st.LaunchSkill.AutoLaunch)
- {
- changeState(new StateFollowAndAttack(this, target, st.Data.ExpectTarget));
- return true;
- }
- return false;
- }
- protected override void Disposing()
- {
- mMaster = null;
- mFollowMaster = null;
- base.Disposing();
- }
- //----------------------------------------------------------------------------------------------------------
- protected override IUnitStatistic CreateUnitStatistic()
- {
- return new PetUnitStatistic(this);
- //return base.CreateUnitStatistic();
- }
- public class PetUnitStatistic : UnitStatistic
- {
- private InstancePet owner;
- public PetUnitStatistic(InstancePet owner) : base(owner)
- {
- this.owner = owner;
- }
- public override void onAttack(InstanceUnit target, int reduceHP)
- {
- //伤害统计重定向到主人//
- if (owner.Master != null)
- {
- owner.Master.Statistic.onAttack(target, reduceHP);
- }
- else
- {
- base.onAttack(target, reduceHP);
- }
- }
- public override void onKill(InstanceUnit target)
- {
- //击杀统计重定向到主人//
- if (owner.Master != null)
- {
- owner.Master.Statistic.onKill(target);
- }
- else
- {
- base.onKill(target);
- }
- }
- }
- //----------------------------------------------------------------------------------------------------------
- /// <summary>
- /// 移动状态
- /// </summary>
- public class StateFollowMaster : State
- {
- // 被追目标
- readonly private InstanceZoneObject master;
- private MoveAI move;
- public StateFollowMaster(InstancePet unit, InstanceZoneObject target)
- : base(unit)
- {
- this.master = target;
- this.move = new MoveAI(unit);
- }
- override public bool onBlock(State new_state)
- {
- if (new_state is StateDead)
- {
- return true;
- }
- if (new_state is StateFollowMaster)
- {
- return true;
- }
- float r = Math.Max(zone.Templates.CFG.PET_FOLLOW_DISTANCE_MIN, master.BodyBlockSize + unit.BodyBlockSize);
- if (CMath.includeRoundPoint(unit.X, unit.Y, r, master.X, master.Y))
- {
- unit.SetActionStatus(UnitActionStatus.Idle);
- return true;
- }
- StateSkill stateSkill = new_state as StateSkill;
- if(stateSkill != null && !stateSkill.IsCancelableByMove)
- {
- return true;
- }
- return false;
- }
- override protected void onStart()
- {
- unit.SetActionStatus(UnitActionStatus.Move);
- this.move.FindPath(master);
- }
- override protected void onUpdate()
- {
- float r = Math.Max(zone.Templates.CFG.PET_FOLLOW_DISTANCE_MIN, master.BodyBlockSize + unit.BodyBlockSize);
- if (CMath.includeRoundPoint(unit.X, unit.Y, r, master.X, master.Y))
- {
- unit.SetActionStatus(UnitActionStatus.Idle);
- unit.doSomething();
- }
- else
- {
- move.Update();
- if (move.IsNoWay)
- {
- (unit as InstancePet).transportToMaster();
- }
- }
- }
- override protected void onStop()
- {
- unit.SetActionStatus(UnitActionStatus.Idle);
- }
- }
- }
- }
|