12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517 |
- 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;
- 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 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 = true;// 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 is InstanceSpell spell && spell.mInfo.MType == SpellTemplate.MotionType.Cannon)
- {
- return 0;
- }
- if (mLaunchData.FromUnitBody)
- {
- //TODO: 此时的Z并不是spell的实际高度位置
- return mSender.Z;
- }
- else
- {
- return mLaunchData.LaunchSpellHeight;
- }
- }
- }
- 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);
- }
- //public long mDisPosingTime = 0;
- //public long mDisPosingTime1 = 0;
- protected override void Disposing()
- {
- this.mSeekingCooldownTime = null;
- this.mKeyFrames = null;
- //mDisPosingTime = CommonLang.CUtils.localTimeMS;
- //mDisPosingTime1 = System.DateTime.Now.Ticks;
- if (this.mHittedUnits != null)
- {
- this.mHittedUnits.Clear();
- this.mHittedUnits = null;
- }
- this.mHitIntervalTicker = null;
- this.mCreateSpellData = null;
- if (this.mCurveSpellList != null)
- {
- this.mCurveSpellList.Clear();
- this.mCurveSpellList = null;
- }
- if (brothers != null)
- {
- for (int i = 0; i < brothers.Length; i++)
- {
- if (this == brothers[i])
- {
- brothers[i] = null;
- break;
- }
- }
- }
- this.AttackRange = null;
- base.Disposing();
- }
- 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);
- }
- }
- if (this.mKeyFrames != null)
- {
- updateKeyFrames(slowRefresh);
- }
- 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));
- }
- }
- this.checkAndLaunchCurveSpell();
- 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));
- }
- }
- /** 检测释放后续飞弹 */
- private void checkAndLaunchCurveSpell(bool force = false)
- {
- //////创建后续个飞弹
- if ((force || 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;
- }
- }
- 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, bool slowRefresh)
- {
- 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)
- {
- if(b != null)
- {
- b.foxfireSeekWait += timeValue;
- }
- }
- }
- /// <summary>
- /// 更新范围检测以及关键帧
- /// </summary>
- private void updateKeyFrames(bool slowRefresh)
- {
- 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);
- }
- this.checkAndLaunchCurveSpell(true);
- 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, slowRefresh);
- 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, slowRefresh);
- 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 (Info.SpecialEffect == SpellTemplate.SpecialAdditionalEffect.DragPath && Info.SpecialEffectParam != 0f)
- {
- updateDragPathKeyFramesRanged(slowRefresh);
- }
- else if (Info.SpecialEffect == SpellTemplate.SpecialAdditionalEffect.DarkHole && Info.SpecialEffectParam != 0f)
- {
- updateDarkHoleKeyFramesRanged(slowRefresh);
- }
- else
- {
- updateKeyFramesRanged(slowRefresh);
- }
- if (Finish)
- {
- Parent.RemoveObject(this);
- }
- 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(slowRefresh);
- }
- else if (Info.SpecialEffect == SpellTemplate.SpecialAdditionalEffect.DarkHole && Info.SpecialEffectParam != 0f)
- {
- updateDarkHoleKeyFramesRanged(slowRefresh);
- }
- else
- {
- updateKeyFramesRanged(slowRefresh);
- }
- }
- 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(bool slowRefresh)
- {
- using (var kfs = ListObjectPool<SpellTemplate.KeyFrame>.AllocAutoRelease())
- {
- //if(mKeyFrames == null)
- //{
- // long ltime1 = CommonLang.CUtils.localTimeMS - mDisPosingTime;
- // long ltime2 = System.DateTime.Now.Ticks - mDisPosingTime1;
- //}
- 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, slowRefresh);
- 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(bool slowRefresh)
- {
- using (var kfs = ListObjectPool<SpellTemplate.KeyFrame>.AllocAutoRelease())
- {
- using (var enemy_list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
- {
- getShapeAttackable(enemy_list, AttackReason.Attack, slowRefresh);
- 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(bool slowRefresh)
- {
- using (var kfs = ListObjectPool<SpellTemplate.KeyFrame>.AllocAutoRelease())
- {
- using (var enemy_list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
- {
- getShapeAttackable(enemy_list, AttackReason.Attack, slowRefresh);
- 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
- }
- }
- }
- }
- }
|