using System; using System.Collections.Generic; using System.Text; using CommonLang; using CommonAI.RTS; using CommonLang.Vector; using CommonAI.RTS.Manhattan; using CommonAI.Zone.Helper; using CommonAI.Zone.ZoneEditor; using CommonLang.Log; namespace CommonAI.Zone.Instance { public class Ability : IDisposable { public InstanceZone Zone { get; private set; } public Ability(InstanceZone zone) { this.Zone = zone; } public virtual void Dispose() { } } //------------------------------------------------------------------------------------------- public class TransportUnitTrigger : Ability { public string Name { get; private set; } public string NextPositionName; public UnitInfo.UnitType AcceptUnitType = UnitInfo.UnitType.TYPE_PLAYER; public bool AcceptUnitTypeForAll = false; public byte AcceptForce = 0; public bool AcceptForceForAll = false; public LaunchEffect TransportEffect; private InstanceFlag mNext; private ZoneRegion mOwner; public TransportUnitTrigger(InstanceZone zone, string name) : base(zone) { this.Name = name; } public void bindToRegion(ZoneRegion region) { InstanceZone zone = region.Parent; this.mNext = zone.getFlag(this.NextPositionName); this.mOwner = region; if (mNext != null) { region.OnUnitEnter += this.onUnitEnter; } } private bool Select(InstanceUnit unit) { if (!AcceptUnitTypeForAll && unit.Info.UType != this.AcceptUnitType) { return false; } if (!AcceptForceForAll && unit.Force != this.AcceptForce) { return false; } return true; } private void onUnitEnter(ZoneRegion region, InstanceUnit obj) { if (Select(obj)) { if (TransportEffect != null) { mOwner.Parent.queueEvent(new AddEffectEvent(0, region.X, region.Y, region.Direction, TransportEffect)); } obj.transport(mNext.X, mNext.Y); obj.resetAI(); ZoneRegion rg = mNext as ZoneRegion; if (rg != null) { rg.addInRegionViewed(obj); } } } } public class RegionDamageTrigger : Ability { public static Logger log = LoggerFactory.GetDefLogger(); private RegionDamageAbilityData mData; // 间隔触发器 private TimeTaskMS mTimeTask; //初始化标记 private bool mInit; //区域内单位 private List mReginUnit = new List(); public RegionDamageTrigger(InstanceZone scene, RegionDamageAbilityData data) : base(scene) { this.mData = data; //修正数据 if(data.interval < 300) { mData.interval = 300; log.Warn("RegionDamageTrigger触发间隔错误:" + data.Name + ", " + data.interval); } } public void bindToRegion(ZoneRegion region) { if (this.mInit) { return; } this.mInit = true; mTimeTask = region.Parent.AddTimeTask(mData.interval, mData.interval, 0, OnTimeTrigger); region.OnFlagDisabled += this.onRegionStop; region.OnFlagEnabled += this.onRegionStart; region.OnUnitEnter += this.onUnitEnter; region.OnUnitLeave += this.onUnitLeave; if (!region.Enable) { this.mTimeTask.Pause(); } } private void onRegionStart(InstanceFlag region) { ZoneRegion zoneRegion = region as ZoneRegion; if(zoneRegion == null) { return; } //统计下区域内单位数量 mReginUnit.Clear(); this.mTimeTask.Resume(); } private void onRegionStop(InstanceFlag region) { this.mTimeTask.Pause(); } private bool Select(InstanceUnit unit) { return mData.force == -1 || unit.Virtual.GetForceID() == mData.force; } private void onUnitEnter(ZoneRegion region, InstanceUnit obj) { if (Select(obj)) { this.mReginUnit.Add(obj); } } private void onUnitLeave(ZoneRegion region, InstanceUnit obj) { if (Select(obj)) { this.mReginUnit.Remove(obj); } } private void OnTimeTrigger(TimeTaskMS task) { //开始处理伤害 foreach (InstanceUnit unit in this.mReginUnit) { if(!unit.IsActive) { continue; } if (this.mData.attack != 0) { unit.AddHP(-this.mData.attack, unit); } if (this.mData.attackPer != 0) { int addValue = CUtils.CastInt(unit.MaxHP * 0.0001f * this.mData.attackPer); if(addValue == 0) { addValue = this.mData.attackPer > 0 ? 1 : -1; } //扣血| 非满血加血 if(addValue > 0 || unit.CurrentHP < unit.MaxHP) { unit.AddHP(-addValue, unit); } } if (this.mData.DoBuff != null) { unit.AddBuff(mData.DoBuff, unit); } } } } }