1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using CommonAI.RTS;
- using CommonLang.Vector;
- using CommonAI.ZoneClient;
- using CommonLang;
- using CommonAI.Zone.Formula;
- using CommonAI.Zone.Helper;
- using static CommonAI.Zone.Instance.InstanceUnit;
- using CommonAI.ZoneServer.JSGModule;
- using CommonAI.Data;
- namespace CommonAI.Zone.Instance
- {
- public class InstanceSpell : InstanceZoneObject
- {
- readonly protected SpellTemplate mInfo;
- readonly protected SyncSpellInfo mSyncInfo;
- readonly protected LaunchSpell mLaunchData;
- // 释放者
- readonly protected InstanceUnit mLauncherUnit;
- // 发出者
- readonly protected InstanceZoneObject mSender;
- readonly protected AttackRangeHelper AttackRange;
- protected Vector2 mStartPos;
- protected float mLaunchDirection;
- // 被跟踪目标
- protected InstanceUnit mTarget;
- protected Vector2 mTargetPos;
- protected TimeExpire<int> mSeekingCooldownTime;
- protected SpellChainLevelInfo mChainInfo;
- /// <summary>
- /// 如果是技能产生的伤害,就是该技能的类型(就算是法术,也要追根到技能)
- /// </summary>
- public readonly XmdsSkillType FromSkillType = XmdsSkillType.none;
- private float mBaseSize;
- private float mDistance;
- private float mSpeed;
- private PopupKeyFrames<SpellTemplate.KeyFrame> mKeyFrames;
- private Dictionary<uint, InstanceUnit> mHittedUnits;
- private bool Finish = false;
- private TimeInterval<SpellTemplate.KeyFrame> mHitIntervalTicker;
- private InstanceUnit.StateSkill mBindingSkill;
- private bool mClientVisible;
- private bool mSyncPos;
- private float mMoveDistance;
- //服务器专用的扩展字段
- private int actionIndex;
- private int mMaxAffectUnit;
- //法术创建时,玩家的AOI状态
- private byte aoiFlag = 0;
- //每隔N秒触发,触发次数
- private int mHitTotalTimes;
- //法术总时长
- private readonly int mSpellTotalTime; //法术的总时长
- // 飞弹各种奇葩数据记录, 法术数量可控
- private readonly JSGCreateSpellData mCreateSpellData; //法术创建信息(可变的,由技能数据确定)
- // 飞弹不同的法术id
- public List<LaunchSpell> mCurveSpellList;
- //连续飞弹
- private byte mCurveSpellIndex;
- private TVector2 mPrvePos = new TVector2();
- public InstanceSpell(
- InstanceZone zone,
- SpellTemplate data,
- LaunchSpell launch,
- InstanceUnit launcher,
- InstanceZoneObject sender,
- Dictionary<uint, InstanceUnit> damageList,
- XmdsSkillType fromSkillType = XmdsSkillType.none,
- int spellIndex = 0,
- JSGCreateSpellData createData = null)
- : base(zone, false)
- {
- this.mSpellTotalTime = data.LifeTimeMS;
- this.mCurveSpellIndex = (byte)spellIndex;
- SenderID = 0;
- if(sender!=null)
- {
- if (sender is InstanceUnit)
- SenderID = sender.ID;
- else if(sender is InstanceSpell)
- SenderID = (sender as InstanceSpell).SenderID;
- }
- //记录AOI状态
- if(sender.AoiStatus != null)
- {
- this.aoiFlag = 1;
- }
- this.FromSkillType = fromSkillType;
- this.mLaunchData = launch;
- if(createData == null)
- {
- this.mCreateSpellData = new JSGCreateSpellData();
- this.mCreateSpellData.mMaxSpellCount = launch.Count;
- }
- else
- {
- this.mCreateSpellData = createData;
- }
-
- this.mKeyFrames = new PopupKeyFrames<SpellTemplate.KeyFrame>();
- this.mKeyFrames.AddRange(data.KeyFrames);
- this.mInfo = data;
- this.mLauncherUnit = launcher;
- this.mSender = sender;
- this.mBaseSize = data.BodySize;
- this.mDistance = data.Distance;
- this.faceTo(launcher.Direction);
- this.IsAffectNearChange = false;
- this.mSyncInfo = new SyncSpellInfo(zone.IsHalfSync);
- this.mSyncInfo.TemplateID = mInfo.ID;
- this.mSyncInfo.Force = launcher.Force;
- if (mInfo.HitIntervalMS <= 0)
- {
- this.mHittedUnits = (damageList == null ? new Dictionary<uint, InstanceUnit>() : damageList);
- }
- this.mClientVisible = mInfo.ClientVisible;
- this.mSyncPos = zone.SyncPos;
- this.mHitIntervalTicker = new TimeInterval<SpellTemplate.KeyFrame>(data.HitIntervalMS);
- this.mHitIntervalTicker.Tag = data.HitIntervalKeyFrame;
- this.mHitTotalTimes = 0;
- this.AttackRange = new AttackRangeHelper(launcher);
- this.mSpeed = mInfo.MSpeedSEC;
- this.mMoveDistance = 0;
- if(launcher.AoiStatus != null)
- {
- this.setAoiStatus(launcher.AoiStatus);
- }
- }
- public SpellTemplate Info { get { return mInfo; } }
- public LaunchSpell LaunchData { get { return mLaunchData; } }
- /// <summary>
- /// 最先技能的发起者
- /// </summary>
- public InstanceUnit Launcher { get { return mLauncherUnit; } }
- public uint LauncherID { get { return mLauncherUnit.ID; } }
- /// <summary>
- /// 技能的出口,比如技能触发技能,则Sender就是一个Spell
- /// </summary>
- public InstanceZoneObject Sender { get { return mSender; } }
- public InstanceUnit Target { get { return mTarget; } }
- public override bool IntersectMap { get { return false; } }
- public override bool IntersectObj { get { return false; } }
- public override bool Moveable { get { return true; } }
- public override float BodyBlockSize { get { return mBaseSize; } }
- public override float BodyHitSize { get { return mBaseSize; } }
- public override float BodyHeight { get { return mInfo.BodySize; } }
- public override float Weight { get { return 0; } }
- public override bool ClientVisible { get { return mClientVisible; } }
- public override bool SyncPos { get { return mSyncPos; } }
- public int BindActionIndex {get{ return actionIndex; } set { this.actionIndex = value; } }
- public int MaxAffectUnit { get { return mMaxAffectUnit; } set { this.mMaxAffectUnit = value; } }
- /** 获取触发次数 */
- public int GetHitTimes()
- {
- return this.mHitTotalTimes;
- }
- /// <summary>
- /// 连锁等级
- /// </summary>
- public int ChainLevel { get { return (mChainInfo != null) ? mChainInfo.Level : 0; } }
- public SpellChainLevelInfo ChainInfo { get { return mChainInfo; } }
- public uint SenderID;
- public uint TargetID { get { return (mTarget != null) ? mTarget.ID : 0; } }
- public Vector2 TargetPos { get { return mTargetPos; } }
- public float LaunchHeightZ
- {
- get
- {
- if (mSender != null && mSender is InstanceSpell)
- {
- var obj = mSender as InstanceSpell;
- if (obj.mInfo.MType == SpellTemplate.MotionType.Cannon)
- {
- return 0;
- }
- else
- {
- return mSender.Z;
- }
- }
- float h = mLaunchData.LaunchSpellHeight;
- if (mLaunchData.FromUnitBody)
- {
- h = Launcher.Info.LaunchSpellHeight;
- }
- return h;
- }
- }
- public override SyncObjectInfo GenSyncInfo(bool net)
- {
- return GenSyncSpellInfo(net);
- }
- public SyncSpellInfo GenSyncSpellInfo(bool net = false)
- {
- mSyncInfo.x = X;
- mSyncInfo.y = Y;
- mSyncInfo.direction = this.Direction;
- mSyncInfo.HasSpeed = mInfo.IsMoveable && mSpeed != mInfo.MSpeedSEC;
- mSyncInfo.CurSpeed = mSpeed;
- return mSyncInfo;
- }
- // 如果是导弹类型,则需要目标
- public void setTarget(InstanceUnit target)
- {
- this.mTarget = target;
- }
- public void setTargetPos(Vector2 targetPos)
- {
- this.mTargetPos = targetPos;
- }
- public void setChainInfo(SpellChainLevelInfo c)
- {
- this.mChainInfo = c;
- }
- protected override void onAdded(bool pointLv)
- {
- if (mLaunchData.IsAutoSeekingTarget && mLaunchData.PType != LaunchSpell.PosType.POS_TYPE_AREA)
- {
- //目标不存在,或者已死亡才重新寻找, 不能打开,弹射逻辑
- //if(mTarget == null || mTarget.IsDead())
- {
- mTarget = Parent.SeekSpellAttackable(this.Launcher, this.Info, this.Launcher.AoiStatus,
- X, Y, mLaunchData.SeekingTargetRange, Info.ExpectTarget, mLaunchData.SeekingTargetExpect, mChainInfo);
- //Console.WriteLine("重新索敌:" + mTarget.ID);
- }
- }
- this.mSyncInfo.ObjectID = base.ID;
- this.mLaunchDirection = this.Direction;
- float radius = mLaunchData.LaunchSpellRadius;
- if (mLaunchData.FromUnitBody && (Sender is InstanceUnit))
- {
- radius = (Sender as InstanceUnit).Info.LaunchSpellRadius;
- }
- mStartPos = new Vector2(X, Y);
- switch (mInfo.MType)
- {
- case SpellTemplate.MotionType.SelectTarget:
- if (mTarget != null)
- {
- mStartPos.SetX(mTarget.X);
- mStartPos.SetY(mTarget.Y);
- }
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- break;
- case SpellTemplate.MotionType.SelectLauncher:
- if (mLauncherUnit != null)
- {
- mStartPos.SetX(mLauncherUnit.X);
- mStartPos.SetY(mLauncherUnit.Y);
- }
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- break;
- case SpellTemplate.MotionType.Immovability:
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- break;
- case SpellTemplate.MotionType.Cannon:
- if (mTargetPos != null)
- {
- MathVector.moveTo(mStartPos, mTargetPos.X, mTargetPos.Y, radius);
- }
- else if (mTarget != null)
- {
- mTargetPos = new Vector2(mTarget.X, mTarget.Y);
- MathVector.moveTo(mStartPos, mTargetPos.X, mTargetPos.Y, radius);
- }
- break;
- case SpellTemplate.MotionType.AOE:
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- break;
- case SpellTemplate.MotionType.AOE_Binding:
- break;
- case SpellTemplate.MotionType.AOE_BindingTarget:
- break;
- case SpellTemplate.MotionType.Straight:
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- break;
- case SpellTemplate.MotionType.Binding:
- break;
- case SpellTemplate.MotionType.BindingTarget:
- break;
- case SpellTemplate.MotionType.Missile:
- if (mTarget != null)
- {
- MathVector.moveTo(mStartPos, mTarget.X, mTarget.Y, radius);
- }
- else
- {
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- }
- break;
- case SpellTemplate.MotionType.MissileAttackRoute:
- if (mTarget != null)
- {
- MathVector.moveTo(mStartPos, mTarget.X, mTarget.Y, radius);
- }
- else
- {
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- }
- //设置索敌间隔
- if(this.Info.SeekingCooldownMS > XmdsConstConfig.GAME_UPDATE_INTERVAL_MS)
- {
- this.mSeekingCooldownTime = new TimeExpire<int>(mInfo.SeekingCooldownMS);
- }
- else
- {
- log.Error("法术:" + this.Info.ID + ", 索敌间隔配置异常!");
- }
- break;
- case SpellTemplate.MotionType.SeekerMissile:
- if (mTarget != null)
- {
- MathVector.moveTo(mStartPos, mTarget.X, mTarget.Y, radius);
- }
- else
- {
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- if (mInfo.SeekingCooldownMS == 0)
- {
- mTarget = seekAttackable(mInfo.SeekingRange);
- }
- else
- {
- this.mSeekingCooldownTime = new TimeExpire<int>(mInfo.SeekingCooldownMS);
- }
- }
- break;
- case SpellTemplate.MotionType.SeekerSelectTarget:
- if (mTarget == null)
- {
- if (mInfo.SeekingCooldownMS == 0)
- {
- mTarget = seekAttackable(mInfo.SeekingRange);
- if (mTarget != null)
- {
- mStartPos.SetX(mTarget.X);
- mStartPos.SetY(mTarget.Y);
- }
- }
- else
- {
- this.mSeekingCooldownTime = new TimeExpire<int>(mInfo.SeekingCooldownMS);
- }
- }
- break;
- case SpellTemplate.MotionType.Chain:
- if (mSender != null)
- {
- mStartPos.SetX(mSender.X);
- mStartPos.SetY(mSender.Y);
- }
- break;
- case SpellTemplate.MotionType.Boomerang1:
- case SpellTemplate.MotionType.Boomerang2:
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- break;
- case SpellTemplate.MotionType.CurveMissile:
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- if (mInfo.SeekingCooldownMS > 0)
- {
- this.mSeekingCooldownTime = new TimeExpire<int>(mInfo.SeekingCooldownMS);
- }
- break;
- case SpellTemplate.MotionType.Foxfire:
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- mTarget = null;
- foxfireSeekWait = 0;
- break;
- case SpellTemplate.MotionType.StraightAndStop:
- MathVector.movePolar(mStartPos, mLaunchDirection, radius);
- break;
- }
- setPos(mStartPos.X, mStartPos.Y, this.LaunchHeightZ);
- }
- protected override void onRemoved()
- {
- if (mInfo.StopBindingSkillOnRemoved)
- {
- if (this.Launcher != null && this.Launcher.CurrentState is InstanceUnit.StateSkill)
- {
- (this.Launcher.CurrentState as InstanceUnit.StateSkill).block();
- this.Launcher.doSomething();
- }
- }
- }
- override protected void onUpdate(bool slowRefresh)
- {
- if (IsPaused) { return; }
- if (Info.MaxMoveDistance == 0 || mMoveDistance < Info.MaxMoveDistance)
- {
- updateMotion();
- if (mInfo.IsMoveable)
- {
- MoveHelper.UpdateSpeed(Parent.UpdateIntervalMS, ref mSpeed, mInfo.MSpeedAdd, mInfo.MSpeedAcc, mInfo.MSpeed_MIN, mInfo.MSpeed_MAX);
- MoveHelper.UpdateMoveDistance(Parent.UpdateIntervalMS, ref mMoveDistance, mSpeed);
- }
- }
-
- updateKeyFrames();
- if (mInfo.MType == SpellTemplate.MotionType.Foxfire && mTarget != null)
- {
- }
- else if(mInfo.MType == SpellTemplate.MotionType.CurveMissile && mTarget != null)
- {
- }
- else if (mInfo.MType == SpellTemplate.MotionType.Boomerang1 || mInfo.MType == SpellTemplate.MotionType.Boomerang2)
- {
- }
- else if (mInfo.MType == SpellTemplate.MotionType.Binding)//绑定自身的spell才在自己死亡时移除
- {
- if (!Sender.Enable || Sender.IsDead())
- {
- Parent.RemoveObject(this);
- }
- else if((Sender.AoiStatus == null && this.aoiFlag == 1) || (Sender.AoiStatus != null && this.aoiFlag == 0))
- {
- //玩家AOI状态改变了,也要清一下
- Parent.RemoveObject(this);
- }
- StateSkill skill = this.mLauncherUnit.CurrentState as StateSkill;
- if (skill != null && skill.Skill != null && skill.SkillData.ActionQueue.Count > 1)
- {
- //UnitActionData curSkillAction = skill.Skill.GetCurAction();
- if (skill.CurrentActionIndex != this.actionIndex
- && (0 <= this.actionIndex && this.actionIndex < skill.SkillData.ActionQueue.Count)
- && skill.SkillData.ActionQueue[this.actionIndex].IsCancelBySkillNext)
- {
- Parent.RemoveObject(this);
- }
- }
- }
- if (PassTimeMS >= this.mSpellTotalTime)
- {
- Parent.RemoveObject(this);//Parent.RemoveObjectByID(ID);
- }
- }
- /// <summary>
- /// 更新移动行为
- /// </summary>
- private void updateMotion()
- {
- this.mPrvePos.SetX(X);
- this.mPrvePos.SetY(Y);
- switch (mInfo.MType)
- {
- case SpellTemplate.MotionType.Immovability:
- case SpellTemplate.MotionType.SelectTarget:
- case SpellTemplate.MotionType.SelectLauncher:
- break;
- case SpellTemplate.MotionType.Cannon:
- if (mTargetPos != null)
- {
- if(flyToTarget(mTargetPos.X, mTargetPos.Y, mSpeed, Parent.UpdateIntervalMS))
- {
- this.Finish = true;
- }
- }
- else if(PassTimeMS + Parent.UpdateIntervalMS >= this.mSpellTotalTime)//没有目标,结束时触发下
- {
- if(Parent.UpdateIntervalMS > 0)
- {
- this.Finish = true;
- }
- }
- break;
- case SpellTemplate.MotionType.Straight:
- flyTo(mLaunchDirection, mSpeed, Parent.UpdateIntervalMS);
- break;
- case SpellTemplate.MotionType.AOE:
- updateAOE();
- break;
- case SpellTemplate.MotionType.AOE_Binding:
- updateAOE();
- if (mSender != null && mSender.Enable)
- {
- updateBinding(mSender);
- }
- else
- {
- Parent.RemoveObject(this);
- }
- break;
- case SpellTemplate.MotionType.AOE_BindingTarget:
- updateAOE();
- if (mTarget != null && mTarget.IsActive)
- {
- updateBinding(mTarget);
- }
- else
- {
- Parent.RemoveObject(this);
- }
- break;
- case SpellTemplate.MotionType.Binding:
- if (mSender != null && mSender.Enable)
- {
- updateBinding(mSender);
- }
- else
- {
- Parent.RemoveObject(this);
- }
- break;
- case SpellTemplate.MotionType.BindingTarget:
- if (mTarget != null && mTarget.IsActive)
- {
- updateBinding(mTarget);
- }
- else
- {
- Parent.RemoveObject(this);
- }
- break;
- case SpellTemplate.MotionType.Missile:
- case SpellTemplate.MotionType.MissileAttackRoute:
- if (mTarget != null)
- {
- if (mInfo.RotateSpeedSEC == 0)
- {
- faceTo(mTarget.X, mTarget.Y);
- }
- flyToTarget(mTarget.X, mTarget.Y, mSpeed, Parent.UpdateIntervalMS);
- }
- else
- {
- flyTo(mLaunchDirection, mSpeed, Parent.UpdateIntervalMS);
- }
- break;
- case SpellTemplate.MotionType.SeekerMissile:
- if (mTarget != null)
- {
- if (mInfo.SeekingTurningAngleSEC != 0)
- {
- flyToTargetTunning(mTarget.X, mTarget.Y, mSpeed, mInfo.SeekingTurningAngleSEC, Parent.UpdateIntervalMS);
- }
- else
- {
- faceTo(mTarget.X, mTarget.Y);
- flyToTarget(mTarget.X, mTarget.Y, mSpeed, Parent.UpdateIntervalMS);
- }
- }
- else
- {
- flyTo(mLaunchDirection, mSpeed, Parent.UpdateIntervalMS);
- if (mSeekingCooldownTime == null || mSeekingCooldownTime.Update(Parent.UpdateIntervalMS))
- {
- mTarget = seekAttackable(mInfo.SeekingRange);
- if (mTarget != null)
- {
- Parent.queueObjectEvent(this, new SpellLockTargetEvent(ID, mTarget.ID, X, Y));
- }
- }
- }
- break;
- case SpellTemplate.MotionType.SeekerSelectTarget:
- if (mTarget == null)
- {
- if (mSeekingCooldownTime == null || mSeekingCooldownTime.Update(Parent.UpdateIntervalMS))
- {
- mTarget = seekAttackable(mInfo.SeekingRange);
- if (mTarget != null)
- {
- this.setPos(mTarget.X, mTarget.Y);
- Parent.queueObjectEvent(this, new SpellLockTargetEvent(ID, mTarget.ID, X, Y));
- }
- }
- }
- break;
- case SpellTemplate.MotionType.Chain:
- if (mSender != null && mSender.Enable && mTarget != null && mTarget.IsActive)
- {
- setPos(mSender.X, mSender.Y);
- faceTo(mTarget.X, mTarget.Y);
- updateBinding(mTarget);
- }
- else
- {
- Parent.RemoveObject(this);
- }
- break;
- case SpellTemplate.MotionType.Boomerang1:
- if (PassTimeMS < mInfo.BoomerangFlyTime)
- {
- flyTo(mLaunchDirection, mSpeed, Parent.UpdateIntervalMS);
- }
- else if (PassTimeMS > mInfo.BoomerangFlyTime + mInfo.BoomerangHangtime)
- {
- if (flyToTarget(mLauncherUnit.X, mLauncherUnit.Y, mSpeed * 1.4f, Parent.UpdateIntervalMS))
- {
- this.Finish = true;
- }
- }
- break;
- case SpellTemplate.MotionType.Boomerang2:
- if (PassTimeMS < mInfo.BoomerangFlyTime)
- {
- flyTo(mLaunchDirection, mSpeed, Parent.UpdateIntervalMS);
- }
- else if (PassTimeMS > mInfo.BoomerangFlyTime + mInfo.BoomerangHangtime)
- {
- if (flyToTarget(mStartPos.X, mStartPos.Y, mSpeed * 1.4f, Parent.UpdateIntervalMS))
- {
- this.Finish = true;
- }
- }
- break;
- case SpellTemplate.MotionType.CurveMissile:
- //IPosBase targetPos = mTargetPos;
- IPosBase targetPos = (mTarget != null) ? (IPosBase)mTarget : (IPosBase)mTargetPos;
- if (targetPos == null)
- {
- flyTo(mLaunchDirection, mSpeed, Parent.UpdateIntervalMS);
- }
- else if (mInfo.SeekingTurningAngleSEC != 0)
- {
- flyToTargetTunning(targetPos.X, targetPos.Y, mSpeed, mInfo.SeekingTurningAngleSEC, Parent.UpdateIntervalMS);
- }
- else
- {
- faceTo(targetPos.X, targetPos.Y);
- flyToTarget(targetPos.X, targetPos.Y, mSpeed, Parent.UpdateIntervalMS);
- }
- if (mTarget == null && (mSeekingCooldownTime == null || mSeekingCooldownTime.Update(Parent.UpdateIntervalMS)))
- {
- mTarget = seekAttackable(mInfo.SeekingRange);
- if (mTarget != null)
- {
- Parent.queueObjectEvent(this, new SpellLockTargetEvent(ID, mTarget.ID, X, Y));
- }
- }
- //////创建后续个飞弹
- if (PassTimeMS >= XmdsConstConfig.GAME_UPDATE_INTERVAL_MS && mCurveSpellIndex > 0 && this.Launcher.IsActive)
- {
- int nextSpellIndex = Math.Max(0, mCurveSpellIndex - 1);
- int flag = (this.mCreateSpellData.mMaxSpellCount - mCurveSpellIndex) % 2 == 0 ? 2 : -2;
- //float angleOffset = (this.Target == null ? this.LaunchData.StartAngle / 3 : this.LaunchData.StartAngle);
- float angleOffset = JSGModule.GetCurveStartAngleOffect(mLauncherUnit, this.mTarget, this.LaunchData.StartAngle, this.Info.SeekingRange);
- float startDirection = this.mLaunchDirection + angleOffset * flag;
- float launchX = this.Launcher.X - (float)(1.0f * Math.Cos(this.Launcher.Direction));
- float launchY = this.Launcher.Y - (float)(1.0f * Math.Sin(this.Launcher.Direction));
- LaunchSpell launchSpell = this.LaunchData;
- if (mCurveSpellList != null && mCurveSpellList.Count > mCurveSpellIndex)
- {
- launchSpell = mCurveSpellList[mCurveSpellIndex];
- }
- InstanceSpell addSpell = this.Parent.AddSpell(this.FromSkillType, this.Info, launchSpell, this.Sender, this.mLauncherUnit, (this.mTarget == null ? 0 : this.mTarget.ID),
- JSGModule.GetCurveDefaultTargetPos(mLauncherUnit, this.Info.SeekingRange), launchX, launchY, startDirection, null, -1, 0, null, nextSpellIndex);
- addSpell.mCurveSpellList = this.mCurveSpellList;
- mCurveSpellIndex = 0;
- }
- break;
- case SpellTemplate.MotionType.Foxfire:
- if (mTarget == null)
- {
- foxfireRoundAngle = mLaunchDirection + PassTimeMS * 0.001f * 3;
- var x = mLauncherUnit.X + (float)(Math.Cos(foxfireRoundAngle + 0.3f) * mLaunchData.LaunchSpellRadius);
- var y = mLauncherUnit.Y + (float)(Math.Sin(foxfireRoundAngle + 0.3f) * mLaunchData.LaunchSpellRadius);
- flyToTarget(x, y, mSpeed, Parent.UpdateIntervalMS);
- if (mInfo.RotateSpeedSEC == 0)
- {
- faceTo(foxfireRoundAngle + (float)Math.PI * 0.25f);
- }
- if (foxfireSeekWait >= this.Info.SeekingCooldownMS && PassTimeMS < this.mSpellTotalTime - 500)
- {
- var tar = seekAttackable(mInfo.SeekingRange);
- if (tar != null && tar != mLauncherUnit)
- {
- changeBrotherSeekWait(-250);
- Parent.queueObjectEvent(this, new SpellLockTargetEvent(ID, tar.ID, X, Y));
- mTarget = tar;
- }
- }
- foxfireSeekWait += Parent.UpdateIntervalMS;
- }
- else
- {
- if (mInfo.SeekingTurningAngleSEC != 0)
- {
- flyToTargetTunning(mTarget.X, mTarget.Y, mSpeed, mInfo.SeekingTurningAngleSEC, Parent.UpdateIntervalMS);
- }
- else
- {
- faceTo(mTarget.X, mTarget.Y);
- flyToTarget(mTarget.X, mTarget.Y, mSpeed, Parent.UpdateIntervalMS);
- }
- }
- break;
- case SpellTemplate.MotionType.StraightAndStop:
- if (PassTimeMS < mInfo.BoomerangFlyTime)
- {
- flyTo(mLaunchDirection, mSpeed, Parent.UpdateIntervalMS);
- }
- //else if (PassTimeMS > mInfo.BoomerangFlyTime + mInfo.BoomerangHangtime)
- //{
- // if (flyToTarget(mLauncherUnit.X, mLauncherUnit.Y, mSpeed * 1.8f, Parent.UpdateIntervalMS))
- // {
- // this.Finish = true;
- // }
- //}
- break;
- }
- if (mInfo.BodyShape == SpellTemplate.Shape.LineToTarget)
- {
- if (mTarget != null)
- {
- this.faceTo(mTarget.X, mTarget.Y);
- }
- }
- else if (mInfo.BodyShape == SpellTemplate.Shape.LineToStart)
- {
- this.faceTo(mStartPos.X, mStartPos.Y);
- }
- else if (mInfo.RotateSpeedSEC != 0 && mInfo.MType != SpellTemplate.MotionType.SeekerMissile)
- {
- this.turn(MoveHelper.GetDistance(Parent.UpdateIntervalMS, mInfo.RotateSpeedSEC));
- }
- }
- public static double AngleBetween(Vector2 vector1, Vector2 vector2)
- {
- double sin = vector1.X * vector2.Y - vector2.X * vector1.Y;
- double cos = vector1.X * vector2.X + vector1.Y * vector2.Y;
- return Math.Atan2(sin, cos);
- }
- private void updateAOE()
- {
- switch (Info.BodyShape)
- {
- case SpellTemplate.Shape.LineToTarget:
- case SpellTemplate.Shape.LineToStart:
- case SpellTemplate.Shape.Strip:
- case SpellTemplate.Shape.StripRay:
- case SpellTemplate.Shape.StripRayTouchEnd:
- case SpellTemplate.Shape.RectStrip:
- case SpellTemplate.Shape.RectStripRay:
- updateAoeMotion(Info.Distance, ref mDistance);
- break;
- default:
- updateAoeMotion(Info.BodySize, ref mBaseSize);
- break;
- }
- }
- private void updateAoeMotion(float base_value, ref float value)
- {
- switch (Info.AOEMType)
- {
- case SpellTemplate.AoeMotionType.Sine:
- value = (float)Math.Sin(CMath.PI_F * PassTimeMS / (float)this.mSpellTotalTime) * base_value;
- break;
- case SpellTemplate.AoeMotionType.Linear:
- default:
- value += MoveHelper.GetDistance(Parent.UpdateIntervalMS, mSpeed);
- break;
- }
- }
- private void updateBinding(InstanceZoneObject target)
- {
- if ((target is InstanceUnit))
- {
- var target_unit = target as InstanceUnit;
- if (mInfo.RemoveOnBindingUncontrollable)
- {
- // 目标不可操控,停止法术 //
- if (target_unit.IsControllable == false)
- {
- Parent.RemoveObject(this);
- return;
- }
- }
- if (mInfo.RemoveOnBindingSkillOver)
- {
- // 目标非技能状态,停止法术 //
- if (target_unit.CurrentState is InstanceUnit.StateSkill)
- {
- if (mBindingSkill == null)
- {
- mBindingSkill = target_unit.CurrentState as InstanceUnit.StateSkill;
- }
- else if (mBindingSkill != target_unit.CurrentState)
- {
- Parent.RemoveObject(this);
- return;
- }
- }
- else
- {
- Parent.RemoveObject(this);
- return;
- }
- }
- }
- if (mInfo.IsBinding)
- {
- if (mInfo.IsBindingDirection)
- {
- this.faceTo(target.Direction);
- }
- if (mInfo.IsBindingOrbit)
- {
- float dadd = mInfo.OrbitDistance;
- float ox = (float)Math.Cos(Direction) * dadd;
- float oy = (float)Math.Sin(Direction) * dadd;
- this.setPos(target.X + ox, target.Y + oy);
- }
- else
- {
- float xChanage, yChange;
- this.LaunchData.GetXModify(this.Launcher, out xChanage, out yChange);
- this.setPos(target.X + xChanage, target.Y + yChange);
- }
- }
- }
- private void affectToSingle(InstanceUnit target, SpellTemplate.KeyFrame kf)
- {
- if (kf == null) return;
- if (kf.Effect != null)
- {
- Parent.queueObjectEvent(this, new UnitEffectEvent(this.ID, kf.Effect));
- }
- // 法术造成伤害
- if (kf.Attack != null)
- {
- Parent.unitAttackSingle(mLauncherUnit, new AttackSource(this, kf.Attack), target, mInfo.ExpectTarget);
- }
- // 法术产生法术
- if (kf.Spell != null)
- {
- Parent.spellLaunchSpell(this.FromSkillType, this, kf.Spell, this.X, this.Y, target.ID);
- //Parent.spellLaunchSpell(this, kf.Spell, mLauncherUnit.X + 5, mLauncherUnit.Y + 5, target.ID);
- }
- // 召唤
- if (kf.Summon != null)
- {
- Parent.spellSummonUnit(this, kf.Summon);
- }
- }
- private void affectToMulti(List<InstanceUnit> list, SpellTemplate.KeyFrame kf, bool effect)
- {
- if (kf == null) return;
- if (effect && kf.Effect != null)
- {
- Parent.queueObjectEvent(this, new UnitEffectEvent(this.ID, kf.Effect));
- }
- uint targetUnitID = 0;
- if (list.Count > 0)
- {
- targetUnitID = list[0].ID;
- // 法术造成伤害
- if (kf.Attack != null)
- {
- Parent.unitAttackDirect(mLauncherUnit, new AttackSource(this, kf.Attack), list);
- }
- }
- // 法术产生法术
- if (kf.Spell != null)
- {
- Parent.spellLaunchSpell(this.FromSkillType, this, kf.Spell, this.X, this.Y, targetUnitID);
- //System.Console.WriteLine("------法术产生法术: " + kf.Spell.SpellID + ", " + this.X + ", " + this.Y);
- }
- // 召唤
- if (kf.Summon != null)
- {
- Parent.spellSummonUnit(this, kf.Summon);
- }
- }
- #region __检测范围内目标__
- // 跟踪导弹查找附近单位 //
- public InstanceUnit seekAttackable(float range)
- {
- return Parent.SeekSpellAttackable(this.Launcher, this.Info, this.AoiStatus,
- X, Y, range, mInfo.ExpectTarget, mInfo.SeekingExpectTarget, mChainInfo);
- }
- // 范围伤害,碰撞检测 //
- private void getShapeAttackable(List<InstanceUnit> ret, AttackReason reason)
- {
- AttackRange.Shape = (AttackShape)mInfo.BodyShape;
- AttackRange.BodySize = this.mBaseSize;
- AttackRange.Direction = this.Direction;
- AttackRange.Distance = this.mDistance;
- AttackRange.ExpectTarget = mInfo.ExpectTarget;
- AttackRange.FanAngle = this.mInfo.FanAngle;
- AttackRange.StripWide = this.mInfo.RectWide;
- float prv_x = this.X;
- float prv_y = this.Y;
- if (mInfo.MType == SpellTemplate.MotionType.Straight || mInfo.MType == SpellTemplate.MotionType.StraightAndStop)
- {
- prv_x = mPrvePos.X;
- prv_y = mPrvePos.Y;
- }
- AttackRange.GetShapeAttackable(ret, reason, this.Info, X, Y, prv_x, prv_y, mInfo.MaxAffectUnit, AoiStatus);
- }
- #endregion
- float foxfireRoundAngle = 0f;
- int foxfireSeekWait = 0;
- public InstanceSpell[] brothers = null;
- void changeBrotherSeekWait(int timeValue)
- {
- if (brothers == null)
- {
- return;
- }
- foreach (var b in brothers)
- {
- b.foxfireSeekWait += timeValue;
- }
- }
- /// <summary>
- /// 更新范围检测以及关键帧
- /// </summary>
- private void updateKeyFrames()
- {
- switch (Info.MType)
- {
- case SpellTemplate.MotionType.Missile:
- case SpellTemplate.MotionType.SeekerMissile:
- //【战斗】Missile类技能,在目标消失后失效//
- if (mTarget != null && CMath.includeRoundPoint(mTarget.X, mTarget.Y, mTarget.BodyHitSize, this.X, this.Y))
- {
- if (mTarget.IsActive)
- {
- affectToSingle(mTarget, mInfo.HitOnExplosionKeyFrame);
- }
- Parent.RemoveObject(this);
- }
- break;
- case SpellTemplate.MotionType.CurveMissile:
- //【战斗】Missile类技能,在目标消失后失效//
- if (mTarget != null && CMath.includeRoundPoint(mTarget.X, mTarget.Y, mTarget.BodyHitSize + this.BodyHitSize, this.X, this.Y))
- {
- if (mTarget.IsActive)
- {
- affectToSingle(mTarget, mInfo.HitOnExplosionKeyFrame);
- }
- Parent.RemoveObject(this);
- }
- break;
- case SpellTemplate.MotionType.MissileAttackRoute:
- if (mTarget != null && CMath.includeRoundPoint(mTarget.X, mTarget.Y, mTarget.BodyHitSize, this.X, this.Y))
- {
- if (mTarget.IsActive)
- {
- affectToSingle(mTarget, mInfo.HitOnExplosionKeyFrame);
- }
- Parent.RemoveObject(this);
- }
- else if (mSeekingCooldownTime.Update(Parent.UpdateIntervalMS))
- {
- using (var enemy_list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
- {
- getShapeAttackable(enemy_list, AttackReason.Attack);
- if (enemy_list.Count > 0)
- {
- InstanceUnit target = enemy_list[0];
- if (target.IsActive)
- {
- affectToSingle(target, mInfo.HitOnExplosionKeyFrame);
- }
- mSeekingCooldownTime.Reset();
- }
- }
- }
- break;
- case SpellTemplate.MotionType.Cannon:
- if (Finish)
- {
- SpellTemplate.KeyFrame kf = mInfo.HitOnExplosionKeyFrame;
- if (kf != null)
- {
- using (var list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
- {
- getShapeAttackable(list, AttackReason.Attack);
- affectToMulti(list, kf, true);
- }
- }
- Parent.RemoveObject(this);
- }
- break;
- case SpellTemplate.MotionType.Chain:
- if (mTarget != null)
- {
- if (Collider.Object_Pos_IncludeInRound(mTarget, this.X, this.Y, this.mDistance))
- {
- updateKeyFrameSingleTarget(mTarget, true);
- }
- else
- {
- Parent.RemoveObject(this);
- }
- }
- break;
- case SpellTemplate.MotionType.Boomerang1:
- case SpellTemplate.MotionType.Boomerang2:
- if (Finish)
- {
- Parent.RemoveObject(this);
- }
- if (Info.SpecialEffect == SpellTemplate.SpecialAdditionalEffect.DragPath && Info.SpecialEffectParam != 0f)
- {
- updateDragPathKeyFramesRanged();
- }
- else if (Info.SpecialEffect == SpellTemplate.SpecialAdditionalEffect.DarkHole && Info.SpecialEffectParam != 0f)
- {
- updateDarkHoleKeyFramesRanged();
- }
- else
- {
- updateKeyFramesRanged();
- }
- break;
- case SpellTemplate.MotionType.Foxfire:
- if (mTarget != null && CMath.includeRoundPoint(mTarget.X, mTarget.Y, mTarget.BodyHitSize, this.X, this.Y))
- {
- if (mTarget.IsActive)
- {
- affectToSingle(mTarget, mInfo.HitOnExplosionKeyFrame);
- }
- Parent.RemoveObject(this);
- }
- break;
- default:
- if (Info.BodyShape == SpellTemplate.Shape.LineToTarget || Info.BodyShape == SpellTemplate.Shape.LineToStart)
- {
- if (mTarget != null && Collider.Object_Pos_IncludeInRound(mTarget, this.X, this.Y, this.mDistance))
- {
- updateKeyFrameSingleTarget(mTarget, true);
- }
- else
- {
- updateKeyFrameSingleTarget(mTarget, false);
- }
- }
- else
- {
- if (Info.SpecialEffect == SpellTemplate.SpecialAdditionalEffect.DragPath && Info.SpecialEffectParam != 0f)
- {
- updateDragPathKeyFramesRanged();
- }
- else if (Info.SpecialEffect == SpellTemplate.SpecialAdditionalEffect.DarkHole && Info.SpecialEffectParam != 0f)
- {
- updateDarkHoleKeyFramesRanged();
- }
- else
- {
- updateKeyFramesRanged();
- }
- }
- break;
- }
- }
- private void updateKeyFrameSingleTarget(InstanceUnit enemy, bool affect)
- {
- using (var kfs = ListObjectPool<SpellTemplate.KeyFrame>.AllocAutoRelease())
- {
- int kfs_count = mKeyFrames.PopKeyFrames(PassTimeMS, kfs);
- bool is_interval_test = mHitIntervalTicker.Update(Parent.UpdateIntervalMS);
- if (affect)
- {
- if (kfs_count > 0 || is_interval_test || mInfo.HitIntervalMS == 0)
- {
- if (kfs_count > 0)
- {
- for (int i = 0; i < kfs.Count; i++)
- {
- affectToSingle(enemy, kfs[i]);
- }
- }
- if (mInfo.HitOnExplosion)
- {
- // 击中后爆炸
- affectToSingle(enemy, mInfo.HitOnExplosionKeyFrame);
- Parent.RemoveObject(this);
- }
- else if (mInfo.HitIntervalKeyFrame != null)
- {
- if (mInfo.HitIntervalMS == 0)
- {
- // 只在接触后第一次产生效果
- if (!mHittedUnits.ContainsKey(enemy.ID))
- {
- affectToSingle(enemy, mInfo.HitIntervalKeyFrame);
- mHittedUnits.Add(enemy.ID, enemy);
- }
- }
- else if (is_interval_test)
- {
- // 间隔产生效果
- affectToSingle(enemy, mInfo.HitIntervalKeyFrame);
- }
- }
- }
- }
- }
- }
- private void updateKeyFramesRanged()
- {
- using (var kfs = ListObjectPool<SpellTemplate.KeyFrame>.AllocAutoRelease())
- {
- int kfs_count = mKeyFrames.PopKeyFrames(PassTimeMS, kfs);
- bool is_interval_test = mHitIntervalTicker.Update(Parent.UpdateIntervalMS);
- //此处修正 加入触发次数上限检测
- if (is_interval_test && mInfo.HitIntervalMS > 0 && mHitIntervalTicker.TotalTickCount > (this.mSpellTotalTime / mInfo.HitIntervalMS))
- {
- is_interval_test = false;
- }
- if (kfs_count > 0 || is_interval_test || mInfo.HitIntervalMS == 0)
- {
- this.mHitTotalTimes++;
- using (var enemy_list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
- {
- getShapeAttackable(enemy_list, AttackReason.Attack);
- if (kfs_count > 0)
- {
- // 单Frame情况下,如果是Attack。进行唯一敌人判定(X型拼接法术, 需要伤害只生效一次)
- //if (kfs_count == 1 && mInfo.HitIntervalMS == 0 && this.mInfo.KeyFrames.Count == 1 && kfs[0].Attack != null && this.mInfo.HitIntervalKeyFrame == null)
- if(this.LaunchData.PType == LaunchSpell.PosType.POS_TYPE_X)
- {
- if(this.refreshHitUnit(enemy_list))
- {
- for (int i = 0; i < kfs.Count; i++)
- {
- affectToMulti(enemy_list, kfs[i], true);
- }
- }
- }
- else
- {
- for (int i = 0; i < kfs.Count; i++)
- {
- affectToMulti(enemy_list, kfs[i], true);
- }
- }
- }
- if (mInfo.HitOnExplosion)
- {
- if (enemy_list.Count > 0)
- {
- // 击中后爆炸
- affectToMulti(enemy_list, mInfo.HitOnExplosionKeyFrame, true);
- Parent.RemoveObject(this);
- }
- }
- else if(mInfo.HitIntervalKeyFrame != null)
- {
- if (mInfo.HitIntervalMS == 0)
- {
- // 只在接触后第一次产生效果
- if (enemy_list.Count > 0 && this.refreshHitUnit(enemy_list))
- {
- affectToMulti(enemy_list, mInfo.HitIntervalKeyFrame, true);
- }
- }
- else if (is_interval_test)
- {
- // 间隔产生效果
- affectToMulti(enemy_list, mInfo.HitIntervalKeyFrame, false);
- }
- }
- }
- }
- }
- }
- private void updateDarkHoleKeyFramesRanged()
- {
- using (var kfs = ListObjectPool<SpellTemplate.KeyFrame>.AllocAutoRelease())
- {
- using (var enemy_list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
- {
- getShapeAttackable(enemy_list, AttackReason.Attack);
- for (int i = enemy_list.Count - 1; i >= 0; --i)
- {
- if(enemy_list[i].IsIgnoreControl)
- {
- continue;
- }
- float angle, distance, offset, dx, dy;
- if (enemy_list[i].Weight < XmdsConstConfig.DEFAULT_WEIGHT)
- {
- offset = MoveHelper.GetDistance(Parent.UpdateIntervalMS, Info.SpecialEffectParam);
- dx = this.X - enemy_list[i].X;
- dy = this.Y - enemy_list[i].Y;
- distance = dx * dx + dy * dy;
- if (offset * offset < distance)
- {
- angle = MathVector.getDegree(dx, dy);
- enemy_list[i].moveLinearMap(offset, angle);
- }
- else
- {
- enemy_list[i].moveLinearMap2(dx, dy);
- }
- enemy_list[i].SetStunTimeMS(100);
- }
- }
- int kfs_count = mKeyFrames.PopKeyFrames(PassTimeMS, kfs);
- bool is_interval_test = mHitIntervalTicker.Update(Parent.UpdateIntervalMS);
- #region <<关键帧逻辑>>
- if (kfs_count > 0 || is_interval_test || mInfo.HitIntervalMS == 0)
- {
- //getShapeAttackable(enemy_list, AttackReason.Attack);
- if (kfs_count > 0)
- {
- for (int i = 0; i < kfs.Count; i++)
- {
- affectToMulti(enemy_list, kfs[i], false);
- }
- }
- if (mInfo.HitOnExplosion)
- {
- if (enemy_list.Count > 0)
- {
- // 击中后爆炸
- affectToMulti(enemy_list, mInfo.HitOnExplosionKeyFrame, true);
- Parent.RemoveObject(this);
- }
- }
- else if(mInfo.HitIntervalKeyFrame != null)
- {
- if (mInfo.HitIntervalMS == 0)
- {
- // 只在接触后第一次产生效果
- if (enemy_list.Count > 0 && this.refreshHitUnit(enemy_list))
- {
- affectToMulti(enemy_list, mInfo.HitIntervalKeyFrame, true);
- }
- }
- else if (is_interval_test)
- {
- // 间隔产生效果
- affectToMulti(enemy_list, mInfo.HitIntervalKeyFrame, false);
- }
- }
- }
- #endregion
- }
- }
- }
- public override String GetTemplateData()
- {
- return "Spell:" + this.Info.ID;
- }
- private bool refreshHitUnit(CommonLang.ListObjectPool<InstanceUnit>.AutoReleaseList<InstanceUnit> enemy_list)
- {
- if(enemy_list.Count <= 0)
- {
- return true;
- }
- foreach (InstanceUnit u in mHittedUnits.Values)
- {
- enemy_list.Remove(u);
- }
- if (enemy_list.Count > 0)
- {
- for (int i = enemy_list.Count - 1; i >= 0; --i)
- {
- InstanceUnit u = enemy_list[i];
- mHittedUnits.Add(u.ID, u);
- }
- return true;
- }
- return false;
- }
- public const float Pi = (float)Math.PI;
- public const float PiOver2 = (float)(Math.PI / 2.0);
- public const float PiOver36 = (float)(Math.PI / 36.0);
- public const float TwoPi = (float)(Math.PI * 2.0);
- private void updateDragPathKeyFramesRanged()
- {
- using (var kfs = ListObjectPool<SpellTemplate.KeyFrame>.AllocAutoRelease())
- {
- using (var enemy_list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
- {
- getShapeAttackable(enemy_list, AttackReason.Attack);
- float _a, _b, _angle, offset, dx, dy , dis;
- for (int i = enemy_list.Count - 1; i >= 0; --i)
- {
- if (enemy_list[i].IsIgnoreControl)
- {
- continue;
- }
- if (enemy_list[i].Weight < XmdsConstConfig.DEFAULT_WEIGHT)
- {
- dx = enemy_list[i].X - this.X;
- dy = enemy_list[i].Y - this.Y;
- _a = MathVector.getDegree(dx, dy);
- _b = this.Direction - _a;
- if (_b < -Pi)
- {
- _b += TwoPi;
- }
- else if(_b > Pi)
- {
- _b -= TwoPi;
- }
- if (Math.Abs(_b) < PiOver36)
- {
- continue;
- }
- if(_b > 0)
- {
- if(_b > PiOver2)
- {
- continue;
- }
- _angle = this.Direction + PiOver2;
- }
- else
- {
- if (_b < -PiOver2)
- {
- continue;
- }
- _angle = this.Direction - PiOver2;
- }
- dis = Math.Abs((float)(dy * Math.Sin(_angle) / Math.Sin(_a)));
- offset = MoveHelper.GetDistance(Parent.UpdateIntervalMS, Info.SpecialEffectParam);
- if(offset > dis)
- {
- offset = dis;
- }
- enemy_list[i].moveLinearMap(offset, _angle);
- enemy_list[i].SetStunTimeMS(100);
- }
- }
- int kfs_count = mKeyFrames.PopKeyFrames(PassTimeMS, kfs);
- bool is_interval_test = mHitIntervalTicker.Update(Parent.UpdateIntervalMS);
- #region <<关键帧逻辑>>
- if (kfs_count > 0 || is_interval_test || mInfo.HitIntervalMS == 0)
- {
- //getShapeAttackable(enemy_list, AttackReason.Attack);
- if (kfs_count > 0)
- {
- for (int i = 0; i < kfs.Count; i++)
- {
- affectToMulti(enemy_list, kfs[i], false);
- }
- }
- if (mInfo.HitOnExplosion)
- {
- if (enemy_list.Count > 0)
- {
- // 击中后爆炸
- affectToMulti(enemy_list, mInfo.HitOnExplosionKeyFrame, true);
- Parent.RemoveObject(this);
- }
- }
- else if (mInfo.HitIntervalKeyFrame != null)
- {
- if (mInfo.HitIntervalMS == 0)
- {
- // 只在接触后第一次产生效果
- if (enemy_list.Count > 0 && this.refreshHitUnit(enemy_list))
- {
- affectToMulti(enemy_list, mInfo.HitIntervalKeyFrame, true);
- }
- }
- else if (is_interval_test)
- {
- // 间隔产生效果
- affectToMulti(enemy_list, mInfo.HitIntervalKeyFrame, false);
- }
- }
- }
- #endregion
- }
- }
- }
- }
- }
|