using CommonAI.Zone; using CommonAI.Zone.Helper; using CommonAI.ZoneClient; using ET; using ET.EventType; using Sirenix.Utilities; using System; using XmdsCommon.Plugin; public class BattleUnit : BattleObject { public BattleUnit() { } public ZoneUnit ZUnit { get { return ZoneObject as ZoneUnit; } } public bool IsDead { get { return ZUnit.CurrentState == UnitActionStatus.Dead; } } private EventDispatcher actionChangeHandler; public override void OnAwake(ZoneObject zo) { base.OnAwake(zo); actionChangeHandler = new(); registerActionHandler(); var zu = zo as ZoneUnit; zu.OnActionChanged += OnActionChanged; zu.OnSkillActionChanged += OnSkillActionChanged; zu.OnHPChanged += OnHPChanged; zu.OnMPChanged += OnMPChanged; zu.OnMaxHPChanged += OnMaxHPChanged; zu.OnMaxMPChanged += OnMaxMPChanged; zu.OnLaunchSkill += OnLaunchSkill; zu.OnBuffAdded += OnBuffAdded; zu.OnBuffRemoved += OnBuffRemoved; zu.OnBuffChanged += OnBuffChanged; zu.OnRemoveBuffByOverlayLevel += OnRemoveBuffByOverlayLevel; zu.OnActionSubStatusChanged += OnActionSubStatusChanged; } protected virtual void OnRemoveBuffByOverlayLevel(ZoneUnit unit, ZoneUnit.BuffState buff) { throw new NotImplementedException(); } protected virtual void OnBuffChanged(ZoneUnit unit, ZoneUnit.BuffState buff) { throw new NotImplementedException(); } protected virtual void OnBuffRemoved(ZoneUnit unit, ZoneUnit.BuffState buff) { throw new NotImplementedException(); } protected virtual void OnBuffAdded(ZoneUnit unit, ZoneUnit.BuffState buff) { throw new NotImplementedException(); } private static uint groupId = 1; protected static uint GroupId() { return ++ groupId; } protected virtual void OnLaunchSkill(ZoneUnit _, ZoneUnit.SkillState __, UnitLaunchSkillEvent ___) { CommonAI.ZoneClient.ZoneUnit.ISkillAction action = ZUnit.CurrentSkillAction; if(action == null) { Log.Warning("object's currentSkillAction = null, cannot launch skill"); return; } SkillTemplate skillTemplate = action.SkillData; var curActionIndex = action.CurrentActionIndex; if (skillTemplate.ActionQueue.Count <= curActionIndex) { Log.Error("Enter Skill state error> ({0})>CurrentActionIndex>{1}", skillTemplate.TemplateID, curActionIndex); return; } //Log.Debug($"OnLaunchSkill({Id}), skill({skillTemplate.TemplateID}), actionIndex:{curActionIndex}"); if (skillTemplate.IsSingleAction) { UnitActionData actdata = skillTemplate.ActionQueue[curActionIndex]; if (actdata.ActionName.IsNullOrWhitespace()) { Log.Debug($"ActionName is null @skill({skillTemplate.TemplateID}), actionIndex:{curActionIndex}"); return; } var duration = action.ActionTimeArray != null ? action.ActionTimeArray[0] : actdata.TotalTimeMS; EventSystem.Instance.Publish(PlayAnimatorEvent.Static.Clone( Id, AnimatorEventType.Skill, actdata.ActionName, duration, action.ActionSpeed, 0, actdata.IsCycAction, actdata.ActionAudioName) ); } else { float speed = 1.0f; bool isFrist = true; for (int i = curActionIndex; i < skillTemplate.ActionQueue.Count; i++) { UnitActionData item = skillTemplate.ActionQueue[i]; if (item.ActionName.IsNullOrWhitespace()) { Log.Debug($"ActionName is null @skill({skillTemplate.TemplateID}), actionIndex:{curActionIndex}"); return; } if (action.LaunchEvent != null) { speed = action.LaunchEvent.action_speed; if (action.LaunchEvent.action_speed_add != null && i < action.LaunchEvent.action_speed_add.Length) { speed += action.LaunchEvent.action_speed_add[i]; } } EventSystem.Instance.Publish(PlayAnimatorEvent.Static.Clone( Id, AnimatorEventType.Skill, item.ActionName, action.ActionTimeArray[i], speed, GroupId(), item.IsCycAction, isFrist ? item.ActionAudioName : "")); if(!item.ActionAudioName.IsNullOrWhitespace()) { if (isFrist) { isFrist = false; } else { Log.Error("not implements multiAction audio"); } } } } } protected virtual void OnMaxMPChanged(ZoneUnit unit, int oldMaxMP, int newMaxMP) { throw new NotImplementedException(); } protected virtual void OnMPChanged(ZoneUnit unit, int oldMP, int newMP) { throw new NotImplementedException(); } protected virtual void OnMaxHPChanged(ZoneUnit unit, int oldMaxHP, int newMaxHP) { OnHPChanged(); } protected virtual void OnHPChanged(ZoneUnit unit, int oldHP, int newHP) { OnHPChanged(); } private void OnHPChanged() { var prop = ZUnit.Info.Properties as XmdsUnitProperties; if (prop != null) { if(prop.GameStatusType == XmdsUnitProperties.StatusType.SpecialElite) { var hp = ZUnit.HP; var pg = (float)ZUnit.HP * 100 / ZUnit.MaxHP; EventSystem.Instance.Publish(HPRefresh.Static.Clone(HPRefresh.Index.Tower, pg, hp)); //Log.Debug($"tower({ZUnit.ObjectID}@{ZUnit.Info.Name}) hp: {ZUnit.HP}/{ZUnit.MaxHP}"); } else if(prop.GameStatusType == XmdsUnitProperties.StatusType.SpecialBoss) { var hp = ZUnit.HP; var pg = (float)ZUnit.HP * 100 / ZUnit.MaxHP; EventSystem.Instance.Publish(HPRefresh.Static.Clone(HPRefresh.Index.Boss, pg, hp)); //Log.Debug($"Boss({ZUnit.ObjectID}) hp: {ZUnit.HP}/{ZUnit.MaxHP}"); } } //Log.Debug($"hp({ZUnit.ObjectID}) change: {ZUnit.HP}"); } protected virtual void OnSkillActionChanged(ZoneUnit unit, ZoneUnit.SkillState skill, byte index) { //技能状态 } protected virtual void OnActionChanged(ZoneUnit unit, UnitActionStatus status, object evt) { //Log.Debug($"ActionChange({Id}): {status}, zobject status:{ZUnit.CurrentState}"); if(!actionChangeHandler.Notify(status, evt)) { Log.Error($"unhandle action changed: {status}"); } } protected virtual void OnActionSubStatusChanged(ZoneUnit unit, byte status, object evt) { } private void registerActionHandler() { actionChangeHandler.AddListener(UnitActionStatus.Idle, (_) => { EventSystem.Instance.Publish(PlayAnimatorEvent.Static.Clone(Id, AnimatorEventType.Idle)); }); var move = actionChangeHandler.AddListener(UnitActionStatus.Move, (o) => { EventSystem.Instance.Publish(PlayAnimatorEvent.Static.Clone(Id, AnimatorEventType.Run)); }); actionChangeHandler.AddListener(UnitActionStatus.Chaos, move); actionChangeHandler.AddListener(UnitActionStatus.ServerSyncMove, move); actionChangeHandler.AddListener(UnitActionStatus.Escape, move); var stun = actionChangeHandler.AddListener(UnitActionStatus.Stun, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.HitMove, stun); actionChangeHandler.AddListener(UnitActionStatus.Dead, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.Damage, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.Pick, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.Spawn, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.ChargeAtkMove, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.ChargeAtkIdle, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.DaZuo, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.DaZuoRecoveryAttr, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.ChuanGongA, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.ChuanGongB, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.BuffLockStateAction, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.HomeBack, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.ClearYaoQi, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.PetLock, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.BreakShield, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.Transport, (o) => { }); actionChangeHandler.AddListener(UnitActionStatus.Skill, (o) => { }); } }