using CommonAI.Zone.Helper; using CommonAI.Zone.Instance; using CommonAI.Zone.Formula; using CommonAI.Zone.ZoneEditor; using CommonAI.Zone.ZoneEditor.EventTrigger; using CommonLang; using CommonLang.Log; using CommonLang.Property; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using CommonAI.Data; using CommonAI.ZoneServer.JSGModule; namespace CommonAI.Zone.EventTrigger { //--------------------------------------------------------------------------------- public class EventArguments { public InstanceUnit TriggingUnit { get; set; } public InstanceUnit AttackUnit { get; set; } public InstanceFlag TriggingFlag { get; set; } public InstanceItem TriggingItem { get; set; } public InstanceSpell TriggingSpell { get; set; } public ItemTemplate TriggingItemTemplate { get; set; } public BuffTemplate TriggingBuffTemplate { get; set; } public SkillTemplate TriggingSkillTemplate { get; set; } public SpellTemplate TriggingSpellTemplate { get; set; } public string TriggingQuestID { get; set; } public string TriggingQuestStatusValue { get; set; } public string TriggingQuestStatusKey { get; set; } //---------------------------------------------------------------- public ZoneRegion TriggingRegion { get { return TriggingFlag as ZoneRegion; } } public ZoneWayPoint TriggingPoint { get { return TriggingFlag as ZoneWayPoint; } } public ZoneDecoration TriggingDecoration { get { return TriggingFlag as ZoneDecoration; } } public ZoneArea TriggingArea { get { return TriggingFlag as ZoneArea; } } //---------------------------------------------------------------- public InstanceUnit IteratingUnit { get; set; } public InstanceItem IteratingItem { get; set; } public int IteratingInt32 { get; set; } //---------------------------------------------------------------- public void Set(EventArguments trigger) { this.TriggingUnit = trigger.TriggingUnit; this.TriggingFlag = trigger.TriggingFlag; this.TriggingItem = trigger.TriggingItem; this.TriggingSpell = trigger.TriggingSpell; this.TriggingItemTemplate = trigger.TriggingItemTemplate; this.TriggingBuffTemplate = trigger.TriggingBuffTemplate; this.TriggingSkillTemplate = trigger.TriggingSkillTemplate; this.TriggingSpellTemplate = trigger.TriggingSpellTemplate; this.TriggingQuestID = trigger.TriggingQuestID; this.TriggingQuestStatusValue = trigger.TriggingQuestStatusValue; this.TriggingQuestStatusKey = trigger.TriggingQuestStatusKey; this.IteratingUnit = trigger.IteratingUnit; this.IteratingItem = trigger.IteratingItem; this.IteratingInt32 = trigger.IteratingInt32; } public EventArguments Clone() { var ret = new EventArguments(); ret.Set(this); return ret; } } //--------------------------------------------------------------------------------- /// <summary> /// 抽象值数据接口 /// </summary> public abstract class IEditorValueAdapter : IDisposable { //---------------------------------------------------------------- protected HashMap<string, object> mAttributes = new HashMap<string, object>(); protected HashMap<string, object> mLocalVarMap = new HashMap<string, object>(); //---------------------------------------------------------------- public abstract TemplateManager Templates { get; } /// <summary> /// 场景触发器 /// </summary> public abstract InstanceZone ZoneAPI { get; } /// <summary> /// 单位触发器 /// </summary> public abstract InstanceUnit UnitAPI { get; } public abstract IEventTriggerCollection Group { get; } //---------------------------------------------------------------- public abstract bool IsActive { get; set; } //---------------------------------------------------------------- public void SetLocalVar(string key, object value) { if (!string.IsNullOrEmpty(key)) { mLocalVarMap.Put(key, value); } } public T GetLocalVarAs<T>(string key) { if (!string.IsNullOrEmpty(key)) { try { T ret = (T)mLocalVarMap[key]; return ret; } catch (Exception er) { Console.WriteLine("IEditorValueAdapter : " + key + ", catch: " + er); } } return default(T); } public bool IsAttribute(string key) { return mAttributes.ContainsKey(key); } public void SetAttribute(string key, object value) { mAttributes.Put(key, value); } public object GetAttribute(string key) { return mAttributes.Get(key); } public virtual void Dispose() { this.mAttributes.Clear(); this.mAttributes = null; this.mLocalVarMap.Clear(); this.mLocalVarMap = null; } } public interface IEventTriggerCollection : IDisposable { void Bind<T>(ICollection<T> events) where T : IEventDataNode; EventTriggerAdapter GetEditEvent(string name); void EventActive(string name, EventArguments args); void EventDeactive(string name, EventArguments args); } //--------------------------------------------------------------------------------- /// <summary> /// 执行事件触发器的数据接口 /// </summary> public abstract class EventTriggerAdapter : IEditorValueAdapter, IDisposable { public static int EXPECT_TEST_AND_DO_ACTION_TIME_MS = 10; private Logger log = LoggerFactory.GetLogger("ET"); private IEventDataNode mData; private IEventTriggerCollection mGroup; private List<TimeTaskMS> mTimes = new List<TimeTaskMS>(); private bool mActive = true; //------------------------------------------------------------------------- public string Name { get { return mData.EventName; } } public override IEventTriggerCollection Group { get { return mGroup; } } public override TemplateManager Templates { get { return ZoneAPI.Templates; } } //------------------------------------------------------------------------- public override bool IsActive { get { return mActive; } set { if (mActive != value) { mActive = value; if (mActive) { foreach (TimeTaskMS task in mTimes) { task.Resume(); } } else { foreach (TimeTaskMS task in mTimes) { task.Pause(); } } } } } //------------------------------------------------------------------------- public EventTriggerAdapter(IEventDataNode evt, IEventTriggerCollection group) { this.mData = evt; this.mGroup = group; this.mActive = evt.EventIsActive; } public override void Dispose() { foreach (var t in mData.EventTriggers) { if (t != null) t.Dispose(); } foreach (var t in mData.EventConditions) { if (t != null) t.Dispose(); } foreach (var t in mData.EventActions) { if (t != null) t.Dispose(); } foreach (TimeTaskMS task in mTimes) { task.Dispose(); } mTimes.Clear(); mTimes = null; if (mOnDisposed != null) { mOnDisposed.Invoke(this); } mOnDisposed = null; mOnActionBegin = null; mOnActionEnd = null; mData = null; mGroup = null; base.Dispose(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- internal void Start() { this.Listen(); if (!mActive) { foreach (TimeTaskMS task in mTimes) { task.Pause(); } } } private void Listen() { var args = new EventArguments(); foreach (AbstractTrigger t in mData.EventTriggers) { if (t != null) { t.Listen(this, args); } } } /// <summary> /// 测试并执行一次触发器 /// </summary> /// <returns></returns> public bool TestAndDoAction(EventArguments args) { if (!IsActive) { return false; } int timeUse = 0; #if JSGProfile int startTick = System.Environment.TickCount; bool isTrigger = true; #endif Stopwatch stopwatch = Stopwatch.StartNew(); try { InitLocalVars(args); foreach (AbstractCondition c in mData.EventConditions) { if (c != null && !c.Test(this, args)) { #if JSGProfile isTrigger = false; #endif return false; } } } finally { stopwatch.Stop(); PrintStopwatch(stopwatch, "Test"); #if JSGProfile if (!isTrigger) { timeUse = System.Environment.TickCount - startTick; JSGServerProfile.RecordTrigger(this.ZoneAPI, this.Name, timeUse, false); } #endif } if (mData.EventDelayTimeMS == 0) { RunInternal(args, timeUse); } else { var argst = args.Clone(); ZoneAPI.AddTimeDelayMS(mData.EventDelayTimeMS, (TimeTaskMS) => { RunInternal(argst, timeUse); }); } return true; } /// <summary> /// 重置TaskTimer(). /// </summary> public void ResetTimeTask() { foreach (TimeTaskMS task in mTimes) { task.Reset(); } } private void RunInternal(EventArguments args, int checkTimeUse) { #if JSGProfile int startTick = System.Environment.TickCount; #endif //if(this.Name.Equals("事件重置列表1") || this.Name.Equals("玉重置")) //{ // int i = 0; //} Stopwatch stopwatch = Stopwatch.StartNew(); try { if (mOnActionBegin != null) { mOnActionBegin.Invoke(this, args); } foreach (AbstractAction a in mData.EventActions) { if (a != null) { a.DoAction(this, args); } } if (mOnActionEnd != null) { mOnActionEnd.Invoke(this, args); } } finally { stopwatch.Stop(); PrintStopwatch(stopwatch, "RunInternal"); #if JSGProfile int timeUse = System.Environment.TickCount - startTick + checkTimeUse; bool needNotice = JSGServerProfile.RecordTrigger(this.ZoneAPI, this.Name, timeUse, true); if (!"单位受到伤害,发送战报".Equals(this.Name) || GlobalData.BattleReportEventLogCnt == 0) { if (GlobalData.GAME_BS_TEST) //内部测试标记开放了 { log.Warn("--事件: " + this.ZoneAPI.UUID + ", " + this.ZoneAPI.GetSceneID() + ", act:" + this.Name); } else if(needNotice) { log.Debug("--事件: " + this.ZoneAPI.UUID + ", " + this.ZoneAPI.GetSceneID() + ", act:" + this.Name); } } if ("单位受到伤害,发送战报".Equals(this.Name)) { GlobalData.BattleReportEventLogCnt += 1; } #endif } } public void ProcessActionActive(EventArguments args) { if (mOnActionActive != null) { mOnActionActive.Invoke(this, args); } } private void PrintStopwatch(Stopwatch stopwatch, string function) { if (stopwatch.ElapsedMilliseconds > EXPECT_TEST_AND_DO_ACTION_TIME_MS) { log.WarnFormat("[{0}] at scene[{1}] -> event[{2}] : usetime {3} > {4}ms, data{5}", function, (ZoneAPI as EditorScene).Data.ToString() + "-" + ZoneAPI.UUID, mData.EventName, stopwatch.ElapsedMilliseconds, EXPECT_TEST_AND_DO_ACTION_TIME_MS, ZoneAPI.GetInfo()); } } //----------------------------------------------------------------------------------------------- #region _局部变量_ private void InitLocalVars(EventArguments args) { mLocalVarMap.Clear(); foreach (LocalVar klv in mData.EventLocalVars) { object obj = klv.GetValue(this, args); mLocalVarMap.Put(klv.Key, obj); } } #endregion public delegate bool TryPickItemHandler(EventArguments args, InstanceUnit unit, InstanceItem item); public delegate void TimeTask(EventArguments args); //----------------------------------------------------------------------------------------------- #region _时间任务_ internal void listen_TimeDelaySEC(EventArguments args, float TimeSEC) { args = args.Clone(); TimeTaskMS task = ZoneAPI.AddTimeDelayMS((int)(TimeSEC * 1000), (time) => { TestAndDoAction(args); }); this.mTimes.Add(task); } internal void listen_TimePeriodicSEC(EventArguments args, float EveryTimeSEC) { args = args.Clone(); TimeTaskMS task = ZoneAPI.AddTimePeriodicMS((int)(EveryTimeSEC * 1000), (time) => { TestAndDoAction(args); }); if (task != null) { this.mTimes.Add(task); } } internal void listen_TimeTaskSEC(EventArguments args, float EveryTimeSEC, float DelayTimeSEC, int repeat) { args = args.Clone(); TimeTaskMS task = ZoneAPI.AddTimeTask((int)(EveryTimeSEC * 1000), (int)(DelayTimeSEC * 1000), repeat, (time) => { TestAndDoAction(args); }); this.mTimes.Add(task); } internal void listen_TimeTask(EventArguments args, int intervalMS, int delayMS, int repeat, TimeTask handler) { args = args.Clone(); TimeTaskMS task = ZoneAPI.AddTimeTask(intervalMS, delayMS, repeat, (t) => { handler(args); }); this.mTimes.Add(task); } #endregion //----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------- #region __监听_场景事件__ public void listen_SceneInit(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.InitHandler handler = new InstanceZone.InitHandler((z) => { TestAndDoAction(args); }); zone.OnInit += handler; this.OnDisposed += (api) => { zone.OnInit -= handler; }; } public void listen_TryPickItem(EventArguments args, InstanceZone zone, TryPickItemHandler action) { args = args.Clone(); InstanceZone.TryPickItemHandler handler = new InstanceZone.TryPickItemHandler((z, u, i) => { args.TriggingUnit = u; args.TriggingItem = i; args.TriggingItemTemplate = i.Info; TestAndDoAction(args); return action.Invoke(args, u, i); }); zone.OnTryPickItem += handler; this.OnDisposed += (api) => { zone.OnTryPickItem -= handler; }; } private List<InstanceUnit> _tmpList = new List<InstanceUnit>(); public void listen_RecvMessageFromGS(EventArguments args, InstanceZone zone, string msg, string triggerUnits) { args = args.Clone(); InstanceZone.RecvMessageR2BHandler handler = new InstanceZone.RecvMessageR2BHandler((z, m) => { if (m.Message == msg) { if (!string.IsNullOrEmpty(triggerUnits) || !string.IsNullOrEmpty(m.TriggerUnits)) { _tmpList.Clear(); if (!string.IsNullOrEmpty(m.TriggerUnits)) { //游戏发送过来的,要触发的单位列表:id1,id2... var sps = m.TriggerUnits.Split(','); foreach (var s in sps) { try { var id = System.Convert.ToUInt32(s); var unit = zone.getUnit(id); if (unit != null) { _tmpList.Add(unit); } } catch { } } } if (!string.IsNullOrEmpty(triggerUnits)) { //编辑器配置的,要触发的单位列表:类型1:数量1:阵营1;类型2:数量2:阵营2... var sps = triggerUnits.Split(';'); foreach (var s in sps) { var info = s.Split(':'); if (info.Length != 3) continue; try { int type = int.Parse(info[0]); int cnt = int.Parse(info[1]); int force = int.Parse(info[2]); if (cnt <= _tmpList.Count) break; switch(type) { case 1: //死亡单位 zone.getDeadUnit(cnt - _tmpList.Count, force, ref _tmpList); break; default: log.Error($"配置的触发单位类型不能识别: {triggerUnits}"); break; } } catch { } } } if (_tmpList.Count > 0) { foreach (var unit in _tmpList) { args.TriggingUnit = unit; TestAndDoAction(args); } _tmpList.Clear(); } } else { TestAndDoAction(args); } } }); zone.OnRecvMessageFromGS += handler; this.OnDisposed += (api) => { zone.OnRecvMessageFromGS -= handler; }; } public void listen_ItemAdded(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.ItemAddedHandler handler = new InstanceZone.ItemAddedHandler((z, i, u) => { args.TriggingItem = i; args.TriggingItemTemplate = i.Info; TestAndDoAction(args); }); zone.OnItemAdded += handler; this.OnDisposed += (api) => { zone.OnItemAdded -= handler; }; } #endregion //----------------------------------------------------------------------------------------------- #region __监听_FLAG事件__ public void listen_FlagOpened(EventArguments args, InstanceFlag flag) { args = args.Clone(); InstanceFlag.FlagEnabledHandler handler = new InstanceFlag.FlagEnabledHandler((f) => { args.TriggingFlag = f; TestAndDoAction(args); }); flag.OnFlagEnabled += handler; this.OnDisposed += (api) => { flag.OnFlagEnabled -= handler; }; } public void listen_FlagClosed(EventArguments args, InstanceFlag flag) { args = args.Clone(); InstanceFlag.FlagDisabledHandler handler = new InstanceFlag.FlagDisabledHandler((f) => { args.TriggingFlag = flag; TestAndDoAction(args); }); flag.OnFlagDisabled += handler; this.OnDisposed += (api) => { flag.OnFlagDisabled -= handler; }; } public void listen_RegionSpawnOver(EventArguments args, ZoneRegion region) { args = args.Clone(); ZoneRegion.SpawnOverHandler handler = new ZoneRegion.SpawnOverHandler((rg) => { args.TriggingFlag = rg; TestAndDoAction(args); }); region.OnSpawnOver += handler; this.OnDisposed += (api) => { region.OnSpawnOver -= handler; }; } public void listen_RegionEntered(EventArguments args, ZoneRegion region) { args = args.Clone(); ZoneRegion.UnitEnterHandler handler = new ZoneRegion.UnitEnterHandler((rg, u) => { args.TriggingFlag = rg; args.TriggingUnit = u as InstanceUnit; TestAndDoAction(args); }); region.OnUnitEnter += handler; this.OnDisposed += (api) => { region.OnUnitEnter -= handler; }; } public void listen_RegionLeft(EventArguments args, ZoneRegion region) { args = args.Clone(); ZoneRegion.UnitLeaveHandler handler = new ZoneRegion.UnitLeaveHandler((rg, u) => { args.TriggingFlag = rg; args.TriggingUnit = u as InstanceUnit; TestAndDoAction(args); }); region.OnUnitLeave += handler; this.OnDisposed += (api) => { region.OnUnitLeave -= handler; }; } public void listen_AreaEntered(EventArguments args, ZoneArea area) { args = args.Clone(); ZoneArea.UnitEnterHandler handler = new ZoneArea.UnitEnterHandler((rg, u) => { args.TriggingFlag = rg; args.TriggingUnit = u as InstanceUnit; TestAndDoAction(args); }); area.OnUnitEnter += handler; this.OnDisposed += (api) => { area.OnUnitEnter -= handler; }; } public void listen_AreaLeft(EventArguments args, ZoneArea area) { args = args.Clone(); ZoneArea.UnitLeaveHandler handler = new ZoneArea.UnitLeaveHandler((rg, u) => { args.TriggingFlag = rg; args.TriggingUnit = u as InstanceUnit; TestAndDoAction(args); }); area.OnUnitLeave += handler; this.OnDisposed += (api) => { area.OnUnitLeave -= handler; }; } #endregion //----------------------------------------------------------------------------------------------- #region __监听_单位事件__ public void listen_GenericUnitAdded(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitAddedHandler handler = new InstanceZone.UnitAddedHandler((z, u) => { args.TriggingUnit = u; TestAndDoAction(args); }); zone.OnUnitAdded += handler; this.OnDisposed += (api) => { zone.OnUnitAdded -= handler; }; } public void listen_GenericUnitRemoved(EventArguments args, InstanceZone zone) { InstanceZone.UnitRemovedHandler handler = new InstanceZone.UnitRemovedHandler((z, u) => { args.TriggingUnit = u; TestAndDoAction(args); }); zone.OnUnitRemoved += handler; this.OnDisposed += (api) => { zone.OnUnitRemoved -= handler; }; } public void listen_GenericUnitActivated(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitActivatedHandler handler = new InstanceZone.UnitActivatedHandler((z, u) => { args.TriggingUnit = u; TestAndDoAction(args); }); zone.OnUnitActivated += handler; this.OnDisposed += (api) => { zone.OnUnitActivated -= handler; }; } public void listen_GenericUnitDamaged(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitDamageHandler handler = new InstanceZone.UnitDamageHandler((z, u, attacker, reduceHP, attack) => { args.TriggingUnit = u; args.AttackUnit = attacker; args.TriggingSpell = attack.FromSpellUnit; args.TriggingSkillTemplate = attack.FromSkill; args.TriggingSpellTemplate = attack.FromSpell; args.TriggingBuffTemplate = attack.FromBuff; TestAndDoAction(args); }); zone.OnUnitDamage += handler; this.OnDisposed += (api) => { zone.OnUnitDamage -= handler; }; } public void listen_GenericUnitDead(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitDeadHandler handler = new InstanceZone.UnitDeadHandler((z, u, attacker) => { args.TriggingUnit = u; TestAndDoAction(args); }); zone.OnUnitDead += handler; this.OnDisposed += (api) => { zone.OnUnitDead -= handler; }; } public void listen_GenericUnitRebirth(EventArguments args, InstanceZone zone) { InstanceZone.UnitRebirthHandler handler = new InstanceZone.UnitRebirthHandler((z, u) => { args.TriggingUnit = u; TestAndDoAction(args); }); zone.OnUnitRebirth += handler; this.OnDisposed += (api) => { zone.OnUnitRebirth -= handler; }; } public void listen_GenericUnitGotInstanceItem(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitGotInstanceItemHandler handler = new InstanceZone.UnitGotInstanceItemHandler((z, u, i) => { args.TriggingUnit = u; args.TriggingItem = i; args.TriggingItemTemplate = i.Info; TestAndDoAction(args); }); zone.OnUnitGotInstanceItem += handler; this.OnDisposed += (api) => { zone.OnUnitGotInstanceItem -= handler; }; } public void listen_GenericUnitGotInventoryItem(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitGotInventoryItemHandler handler = new InstanceZone.UnitGotInventoryItemHandler((z, u, i, c) => { args.TriggingUnit = u; args.TriggingItemTemplate = i; TestAndDoAction(args); }); zone.OnUnitGotInventoryItem += handler; this.OnDisposed += (api) => { zone.OnUnitGotInventoryItem -= handler; }; } public void listen_GenericUnitLostInventoryItem(EventArguments args, InstanceZone zone) { InstanceZone.UnitLostInventoryItemHandler handler = new InstanceZone.UnitLostInventoryItemHandler((z, u, i, c) => { args.TriggingUnit = u; args.TriggingItemTemplate = i; TestAndDoAction(args); }); zone.OnUnitLostInventoryItem += handler; this.OnDisposed += (api) => { zone.OnUnitLostInventoryItem -= handler; }; } public void listen_GenericUnitUseItem(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitUseItemHandler handler = new InstanceZone.UnitUseItemHandler((z, u, i, c) => { args.TriggingUnit = u; args.TriggingItemTemplate = i; TestAndDoAction(args); }); zone.OnUnitUseItem += handler; this.OnDisposed += (api) => { zone.OnUnitUseItem -= handler; }; } public void listen_GenericUnitGotBuff(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitGotBuffHandler handler = new InstanceZone.UnitGotBuffHandler((z, u, b) => { args.TriggingUnit = u; args.TriggingBuffTemplate = b.Data; TestAndDoAction(args); }); zone.OnUnitGotBuff += handler; this.OnDisposed += (api) => { zone.OnUnitGotBuff -= handler; }; } public void listen_GenericUnitLostBuff(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitLostBuffHandler handler = new InstanceZone.UnitLostBuffHandler((z, u, b) => { args.TriggingUnit = u; args.TriggingBuffTemplate = b.Data; TestAndDoAction(args); }); zone.OnUnitLostBuff += handler; this.OnDisposed += (api) => { zone.OnUnitLostBuff -= handler; }; } public void listen_GenericUnitQuestAccepted(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.QuestAcceptedHandler handler = new InstanceZone.QuestAcceptedHandler((u, q) => { args.TriggingUnit = u; args.TriggingQuestID = q; TestAndDoAction(args); }); zone.OnQuestAccepted += handler; this.OnDisposed += (api) => { zone.OnQuestAccepted -= handler; }; } public void listen_GenericUnitQuestCompleted(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.QuestCommittedHandler handler = new InstanceZone.QuestCommittedHandler((u, q) => { args.TriggingUnit = u; args.TriggingQuestID = q; TestAndDoAction(args); }); zone.OnQuestCommitted += handler; this.OnDisposed += (api) => { zone.OnQuestCommitted -= handler; }; } public void listen_GenericUnitQuestDropped(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.QuestDroppedHandler handler = new InstanceZone.QuestDroppedHandler((u, q) => { args.TriggingUnit = u; args.TriggingQuestID = q; TestAndDoAction(args); }); zone.OnQuestDropped += handler; this.OnDisposed += (api) => { zone.OnQuestDropped -= handler; }; } public void listen_GenericUnitQuestStatusChanged(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.QuestStatusChangedHandler handler = new InstanceZone.QuestStatusChangedHandler((u, q, k, v) => { args.TriggingUnit = u; args.TriggingQuestID = q; TestAndDoAction(args); }); zone.OnQuestStatusChanged += handler; this.OnDisposed += (api) => { zone.OnQuestStatusChanged -= handler; }; } public void listen_GenericUnitPickUnit(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitPickUnitHandler handler = new InstanceZone.UnitPickUnitHandler((z, u, p) => { args.TriggingUnit = u; TestAndDoAction(args); }); zone.OnUnitPickUnit += handler; this.OnDisposed += (api) => { zone.OnUnitPickUnit -= handler; }; } public void listen_GenericUnitLaunchSkill(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.UnitLaunchSkillHandler handler = new InstanceZone.UnitLaunchSkillHandler((z, u, s) => { args.TriggingUnit = u; args.TriggingSkillTemplate = s.Data; TestAndDoAction(args); }); zone.OnUnitLaunchSkill += handler; this.OnDisposed += (api) => { zone.OnUnitLaunchSkill -= handler; }; } public void listen_GenericPlayerReady(EventArguments args, InstanceZone zone) { args = args.Clone(); InstanceZone.PlayerReadyHandler handler = new InstanceZone.PlayerReadyHandler((p) => { args.TriggingUnit = p; TestAndDoAction(args); }); zone.OnPlayerReady += handler; this.OnDisposed += (api) => { zone.OnPlayerReady -= handler; }; } ////////////////////////////////////////////////////////////////////////////////////// public void listen_PointUnitDead(EventArguments args, InstanceZone zone, string unitName, int UnitTemplateID = 0) { args = args.Clone(); InstanceZone.UnitDeadHandler handler = new InstanceZone.UnitDeadHandler((z, u, attacker) => { if (UnitTemplateID > 0) { if (u.Info.ID == UnitTemplateID) { args.TriggingUnit = u; TestAndDoAction(args); } } else { if (u.Name.Equals(unitName)) { args.TriggingUnit = u; TestAndDoAction(args); } } }); zone.OnUnitDead += handler; this.OnDisposed += (api) => { zone.OnUnitDead -= handler; }; } public void listen_PointUnitOutBattle(EventArguments args, InstanceZone zone, int unitID) { args = args.Clone(); InstanceZone.UnitOutBattleHandler handler = new InstanceZone.UnitOutBattleHandler((z, u) => { if (u.Info.ID == unitID) { args.TriggingUnit = u; TestAndDoAction(args); } }); zone.OnUnitOutBattle += handler; this.OnDisposed += (api) => { zone.OnUnitOutBattle -= handler; }; } ////////////////////////////////////////////////////////////////////////////////////// public void listen_SpecifyUnitActivated(EventArguments args, InstanceUnit unit) { args = args.Clone(); InstanceUnit.ActivatedHandler handler = new InstanceUnit.ActivatedHandler((u) => { args.TriggingUnit = u; TestAndDoAction(args); }); unit.OnActivated += handler; this.OnDisposed += (api) => { unit.OnActivated -= handler; }; } public void listen_SpecifyUnitAttack(EventArguments args, InstanceUnit unit) { args = args.Clone(); InstanceUnit.AttackHandler handler = new InstanceUnit.AttackHandler((u, t, hp, s) => { args.TriggingUnit = u; args.TriggingSpell = s.FromSpellUnit; args.TriggingSkillTemplate = s.FromSkill; args.TriggingSpellTemplate = s.FromSpell; args.TriggingBuffTemplate = s.FromBuff; TestAndDoAction(args); }); unit.OnAttack += handler; this.OnDisposed += (api) => { unit.OnAttack -= handler; }; } public void listen_PointUnitIDDamaged(EventArguments args, InstanceZone zone, int templateID) { args = args.Clone(); InstanceZone.UnitDamageHandler handler = new InstanceZone.UnitDamageHandler((z, u, attacker, reduceHP, attack) => { if (u.Info.ID == templateID) { args.TriggingUnit = u; args.AttackUnit = attacker; args.TriggingSpell = attack.FromSpellUnit; args.TriggingSkillTemplate = attack.FromSkill; args.TriggingSpellTemplate = attack.FromSpell; args.TriggingBuffTemplate = attack.FromBuff; TestAndDoAction(args); } }); zone.OnUnitDamage += handler; this.OnDisposed += (api) => { zone.OnUnitDamage -= handler; }; } public void listen_SpecifyUnitDamaged(EventArguments args, InstanceUnit unit) { args = args.Clone(); InstanceUnit.DamageHandler handler = new InstanceUnit.DamageHandler((u, a, hp, s) => { args.TriggingUnit = u; args.TriggingSpell = s.FromSpellUnit; args.TriggingSkillTemplate = s.FromSkill; args.TriggingSpellTemplate = s.FromSpell; args.TriggingBuffTemplate = s.FromBuff; TestAndDoAction(args); }); unit.OnDamage += handler; this.OnDisposed += (api) => { unit.OnDamage -= handler; }; } public void listen_SpecifyUnitDead(EventArguments args, InstanceUnit unit) { args = args.Clone(); InstanceUnit.DeadHandler handler = new InstanceUnit.DeadHandler((u, a) => { args.TriggingUnit = u; TestAndDoAction(args); }); unit.OnDead += handler; this.OnDisposed += (api) => { unit.OnDead -= handler; }; } public void listen_SpecifyUnitRebirth(EventArguments args, InstanceUnit unit) { InstanceUnit.RebirthHandler handler = new InstanceUnit.RebirthHandler((u) => { args.TriggingUnit = u; TestAndDoAction(args); }); unit.OnRebirth += handler; this.OnDisposed += (api) => { unit.OnRebirth -= handler; }; } public void listen_SpecifyUnitGotInstanceItem(EventArguments args, InstanceUnit unit) { args = args.Clone(); InstanceUnit.GotInstanceItemHandler handler = new InstanceUnit.GotInstanceItemHandler((u, i) => { args.TriggingUnit = u; args.TriggingItem = i; args.TriggingItemTemplate = i.Info; TestAndDoAction(args); }); unit.OnGotInstanceItem += handler; this.OnDisposed += (api) => { unit.OnGotInstanceItem -= handler; }; } public void listen_SpecifyUnitGotInventoryItem(EventArguments args, InstanceUnit unit) { args = args.Clone(); InstanceUnit.GotInventoryItemHandler handler = new InstanceUnit.GotInventoryItemHandler((u, i) => { args.TriggingUnit = u; args.TriggingItemTemplate = i; TestAndDoAction(args); }); unit.OnGotInventoryItem += handler; this.OnDisposed += (api) => { unit.OnGotInventoryItem -= handler; }; } public void listen_SpecifyUnitLostInventoryItem(EventArguments args, InstanceUnit unit) { InstanceUnit.LostInventoryItemHandler handler = new InstanceUnit.LostInventoryItemHandler((u, i) => { args.TriggingUnit = u; args.TriggingItemTemplate = i; TestAndDoAction(args); }); unit.OnLostInventoryItem += handler; this.OnDisposed += (api) => { unit.OnLostInventoryItem -= handler; }; } public void listen_SpecifyUnitUseItem(EventArguments args, InstanceUnit unit) { args = args.Clone(); InstanceUnit.UseItemHandler handler = new InstanceUnit.UseItemHandler((u, i, c) => { args.TriggingUnit = u; args.TriggingItemTemplate = i; TestAndDoAction(args); }); unit.OnUseItem += handler; this.OnDisposed += (api) => { unit.OnUseItem -= handler; }; } public void listen_SpecifyUnitGotBuff(EventArguments args, InstanceUnit unit) { args = args.Clone(); InstanceUnit.GotBuffHandler handler = new InstanceUnit.GotBuffHandler((u, b) => { args.TriggingUnit = u; args.TriggingBuffTemplate = b.Data; TestAndDoAction(args); }); unit.OnGotBuff += handler; this.OnDisposed += (api) => { unit.OnGotBuff -= handler; }; } public void listen_SpecifyUnitLostBuff(EventArguments args, InstanceUnit unit) { args = args.Clone(); InstanceUnit.LostBuffHandler handler = new InstanceUnit.LostBuffHandler((u, b) => { args.TriggingUnit = u; args.TriggingBuffTemplate = b.Data; TestAndDoAction(args); }); unit.OnLostBuff += handler; this.OnDisposed += (api) => { unit.OnLostBuff -= handler; }; } public void listen_SpecifyUnitLaunchSkill(EventArguments args, InstanceUnit unit) { args = args.Clone(); InstanceUnit.OnLaunchSkillHandler handler = new InstanceUnit.OnLaunchSkillHandler((u, s) => { args.TriggingUnit = u; args.TriggingSkillTemplate = s.Data; TestAndDoAction(args); }); unit.OnLaunchSkill += handler; this.OnDisposed += (api) => { unit.OnLaunchSkill -= handler; }; } #endregion //----------------------------------------------------------------------------------------------- #region __监听_触发器事件__ public void listen_EventActionBegin(EventArguments args, EventTriggerAdapter adapter) { args = args.Clone(); OnActionBeginHandler handler = new OnActionBeginHandler((a, g) => { TestAndDoAction(g); }); adapter.OnActionBegin += handler; this.OnDisposed += (api) => { adapter.OnActionBegin -= handler; }; } public void listen_EventActionEnd(EventArguments args, EventTriggerAdapter adapter) { args = args.Clone(); OnActionEndHandler handler = new OnActionEndHandler((a, g) => { TestAndDoAction(g); }); adapter.OnActionEnd += handler; this.OnDisposed += (api) => { adapter.OnActionEnd -= handler; }; } public void listen_EventActionActive(EventArguments args, EventTriggerAdapter adapter) { args = args.Clone(); OnActionActiveHandler handler = new OnActionActiveHandler((a, g) => { TestAndDoAction(g); }); adapter.mOnActionActive += handler; this.OnDisposed += (api) => { adapter.mOnActionActive -= handler; }; } #endregion //----------------------------------------------------------------------------------------------- #region Delegates public delegate void OnActionBeginHandler(EventTriggerAdapter trigger, EventArguments args); public delegate void OnActionEndHandler(EventTriggerAdapter trigger, EventArguments args); public delegate void OnActionActiveHandler(EventTriggerAdapter trigger, EventArguments args); public delegate void OnDisposedHandler(EventTriggerAdapter trigger); private OnActionBeginHandler mOnActionBegin; private OnActionEndHandler mOnActionEnd; private OnActionActiveHandler mOnActionActive; private OnDisposedHandler mOnDisposed; public event OnActionBeginHandler OnActionBegin { add { mOnActionBegin += value; } remove { mOnActionBegin -= value; } } public event OnActionEndHandler OnActionEnd { add { mOnActionEnd += value; } remove { mOnActionEnd -= value; } } public event OnActionActiveHandler OnActionActive { add { mOnActionActive += value; } remove { mOnActionActive -= value; } } public event OnDisposedHandler OnDisposed { add { mOnDisposed += value; } remove { mOnDisposed -= value; } } #endregion //----------------------------------------------------------------------------------------------- } //--------------------------------------------------------------------------------- /// <summary> /// 绑定环境变量用的数据接口 /// </summary> public class BindValuesAdapter : IEditorValueAdapter { private IEventTriggerCollection mGroup; private InstanceZone mZoneAPI; private InstanceUnit mUnitAPI; public BindValuesAdapter(EditorScene scene, IEventTriggerCollection group) { this.IsActive = true; this.mGroup = group; this.mZoneAPI = scene; this.mUnitAPI = null; } public override void Dispose() { this.mGroup = null; this.mZoneAPI = null; this.mUnitAPI = null; base.Dispose(); } public override bool IsActive { get; set; } public override TemplateManager Templates { get { return mZoneAPI.Templates; } } public override IEventTriggerCollection Group { get { return mGroup; } } public override InstanceZone ZoneAPI { get { return mZoneAPI; } } public override InstanceUnit UnitAPI { get { return mUnitAPI; } } } //--------------------------------------------------------------------------------- public class ZoneEventTriggerCollection : IEventTriggerCollection { private EditorScene mScene; private HashMap<string, EventTriggerAdapter> mEvents = new HashMap<string, EventTriggerAdapter>(); public ZoneEventTriggerCollection(EditorScene scene) { this.mScene = scene; } public void Dispose() { foreach (EventTriggerAdapter trigger in mEvents.Values) { trigger.Dispose(); } mEvents.Clear(); mEvents = null; mScene = null; } public void Bind<T>(ICollection<T> events) where T : IEventDataNode { foreach (IEventDataNode e in events) { ZoneEventTrigger trigger = new ZoneEventTrigger(mScene, e, this); mEvents.Put(e.EventName, trigger); } foreach (EventTriggerAdapter trigger in mEvents.Values) { trigger.Start(); } } public EventTriggerAdapter GetEditEvent(string name) { if (name == null) { return null; } return mEvents.Get(name); } public void EventActive(string name, EventArguments args) { EventTriggerAdapter apt = this.GetEditEvent(name); if (apt != null) { apt.IsActive = true; apt.ProcessActionActive(args); } } public void EventDeactive(string name, EventArguments args) { EventTriggerAdapter apt = this.GetEditEvent(name); if (apt != null) { apt.IsActive = false; } } public class ZoneEventTrigger : EventTriggerAdapter { private readonly EditorScene mScene; public override InstanceZone ZoneAPI { get { return mScene; } } public override InstanceUnit UnitAPI { get { return null; } } public ZoneEventTrigger(EditorScene scene, IEventDataNode evt, ZoneEventTriggerCollection group) : base(evt, group) { mScene = scene; } } } public class UnitEventTriggerCollection : IEventTriggerCollection { private InstanceUnit mUnit; private HashMap<string, EventTriggerAdapter> mEvents = new HashMap<string, EventTriggerAdapter>(); public UnitEventTriggerCollection(InstanceUnit unit) { this.mUnit = unit; } public void Dispose() { foreach (EventTriggerAdapter trigger in mEvents.Values) { trigger.Dispose(); } mEvents.Clear(); mEvents = null; mUnit = null; } public void Bind<T>(ICollection<T> events) where T : IEventDataNode { foreach (IEventDataNode e in events) { UnitEventTrigger trigger = new UnitEventTrigger(mUnit, e, this); mEvents.Put(e.EventName, trigger); } foreach (EventTriggerAdapter trigger in mEvents.Values) { trigger.Start(); } } public EventTriggerAdapter GetEditEvent(string name) { if (name == null) { return null; } return mEvents.Get(name); } public void EventActive(string name, EventArguments args) { EventTriggerAdapter apt = this.GetEditEvent(name); if (apt != null) { apt.IsActive = true; } } public void EventDeactive(string name, EventArguments args) { EventTriggerAdapter apt = this.GetEditEvent(name); if (apt != null) { apt.IsActive = false; } } public class UnitEventTrigger : EventTriggerAdapter { private readonly InstanceZone mScene; private readonly InstanceUnit mUnit; public override InstanceZone ZoneAPI { get { return mScene; } } public override InstanceUnit UnitAPI { get { return mUnit; } } public UnitEventTrigger(InstanceUnit unit, IEventDataNode evt, UnitEventTriggerCollection group) : base(evt, group) { mUnit = unit; mScene = unit.Parent; } } } //--------------------------------------------------------------------------------- }