using System; using System.Collections.Generic; using MoleMole.Config; using UnityEngine; namespace MoleMole { public class LevelActor : BaseAbilityActor { public enum Mode { Single = 0, Multi = 1, MultiRemote = 2, NetworkedMP = 3 } public enum LevelState { LevelLoaded = 0, LevelStarted = 1, LevelRunning = 2, LevelEnded = 3, LevelTransiting = 4 } public enum LevelMinSwapTimerState { Idle = 0, Running = 1 } public enum ComboTimerState { Running = 0, Pause = 1 } public enum AvatarSwapState { Idle = 0, WaitingForEvent = 1, Started = 2 } private const float LEVEL_MIN_SWAP_TIME = 0.5f; private const float LEVEL_COMBO_WINDOW_TIME = 2.8f; private const int MAX_FRAME_INDEX = 20; public MonoLevelEntity levelEntity; public Mode levelMode; public Action comboTimeUPCallback; private float _levelMinSwapTimer; public LevelMinSwapTimerState _swapTimerState; public SafeInt32 levelCombo = 0; private SafeFloat _levelComboTimer = 0f; private ComboTimerState _comboTimerState; public float upLevelNatureBonusFactor = 1f; public float downLevelNatureBonusFactor = 1f; private bool _countAnimEventComboOnceInOneFrame = true; private int _frameIndex; private HashSet> _frameHitSet; public Action onLevelComboChanged; public LevelAntiCheatPlugin antiCheatPlugin; private LevelDamageStasticsPlugin _damagePlugin; private LevelMissionStatisticsPlugin _levelMissionStatisticsPlugin; private LevelAIPlugin _levelMonsterAIPlugin; private LevelDefendModePlugin _levelDefendModePlugin; public BaseLevelBuff[] levelBuffs; public LevelBuffWitchTime witchTimeLevelBuff; public LevelBuffStopWorld stopWorldLevelBuff; private uint _swapOutID; private uint _swapInID; private AvatarSwapState _avatarSwapState; private float _timeSlowTimer; private Action _timeSlowDoneCallback; public LevelState levelState { get; private set; } public void SuddenLevelStart() { levelState = LevelState.LevelStarted; Singleton.Instance.PushSoundBankScale(new string[1] { "BK_InLevel_Common" }); } public void SuddenLevelEnd() { levelState = LevelState.LevelEnded; Singleton.Instance.ClearManualPrepareBank(); } public override void OnRemoval() { base.OnRemoval(); onLevelComboChanged = null; } public override void Init(BaseMonoEntity entity) { levelEntity = (MonoLevelEntity)entity; commonConfig = levelEntity.commonConfig; base.Init(entity); runtimeID = 562036737u; levelState = LevelState.LevelLoaded; _damagePlugin = new LevelDamageStasticsPlugin(this); if (Singleton.Instance.collectAntiCheatData) { antiCheatPlugin = new LevelAntiCheatPlugin(_damagePlugin); AddPlugin(antiCheatPlugin); } _frameHitSet = new HashSet>(); _frameIndex = 0; LevelChallengeHelperPlugin plugin = new LevelChallengeHelperPlugin(this); AddPlugin(plugin); int levelId = Singleton.Instance.LevelId; if (levelId != 0) { int count = Singleton.Instance.GetUnFinishedTutorialIDList(levelId).Count; if (count > 0) { LevelTutorialHelperPlugin plugin2 = new LevelTutorialHelperPlugin(this); AddPlugin(plugin2); } } _levelMissionStatisticsPlugin = new LevelMissionStatisticsPlugin(this); AddPlugin(_levelMissionStatisticsPlugin); _levelMonsterAIPlugin = new LevelAIPlugin(this); AddPlugin(_levelMonsterAIPlugin); InitAdditionalLevelActorPlugins(); Singleton.Instance.RegisterEventListener(runtimeID); Singleton.Instance.RegisterEventListener(runtimeID); Singleton.Instance.RegisterEventListener(runtimeID); Singleton.Instance.RegisterEventListener(runtimeID); Singleton.Instance.RegisterEventListener(runtimeID); Singleton.Instance.RegisterEventListener(runtimeID); AvatarManager instance = Singleton.Instance; instance.onLocalAvatarChanged = (Action)Delegate.Combine(instance.onLocalAvatarChanged, new Action(OnLocalAvatarChanged)); } public void SetLevelDefendModePluginStart(int targetValue) { if (_levelDefendModePlugin != null && HasPlugin()) { _levelDefendModePlugin.Reset(targetValue); } else { _levelDefendModePlugin = new LevelDefendModePlugin(this, targetValue); AddPlugin(_levelDefendModePlugin); } _levelDefendModePlugin.SetActive(true); } public void SetLevelDefendModePluginStart() { if (_levelDefendModePlugin != null && HasPlugin()) { _levelDefendModePlugin.Reset(); } else { _levelDefendModePlugin = new LevelDefendModePlugin(this); AddPlugin(_levelDefendModePlugin); } _levelDefendModePlugin.SetActive(true); } public void SetLevelDefendModePluginReset(int targetValue) { if (_levelDefendModePlugin != null && HasPlugin()) { _levelDefendModePlugin.Reset(targetValue); } } public void SetLevelDefendModePluginStop() { if (_levelDefendModePlugin != null && HasPlugin()) { _levelDefendModePlugin.Stop(); RemovePlugin(_levelDefendModePlugin); _levelDefendModePlugin = null; } } public int GetLevelDefendModeMonsterEnterAmount() { if (_levelDefendModePlugin != null && HasPlugin()) { return _levelDefendModePlugin.MonsterEnterAmount; } return 0; } public int GetLevelDefendModeMonsterKillAmount() { if (_levelDefendModePlugin != null && HasPlugin()) { return _levelDefendModePlugin.MonsterKillAmount; } return 0; } public void AddTriggerFieldInDefendMode(TriggerFieldActor triggerFieldActor) { if (_levelDefendModePlugin != null && HasPlugin()) { _levelDefendModePlugin.AddTriggerFieldActor(triggerFieldActor); } } public void ControlLevelDamageStastics(DamageStastcisControlType type) { if (HasPlugin()) { _damagePlugin.ControlDamageStastics(type); } } public void SetupLevelDamageStastics() { AddPlugin(_damagePlugin); } public void RemoveLevelDamageStastics() { RemovePlugin(_damagePlugin); } public void StartLevelBuff(BaseLevelBuff buff, float duration, bool allowRefresh, bool enteringTimeSlow, LevelBuffSide side, uint ownerRuntimeID, bool notStartEffect) { if (buff.isActive) { if (buff == witchTimeLevelBuff) { witchTimeLevelBuff.Refresh(duration, side, ownerID, enteringTimeSlow, allowRefresh, notStartEffect); } else if (buff != stopWorldLevelBuff) { } } else if (buff == witchTimeLevelBuff) { witchTimeLevelBuff.Setup(enteringTimeSlow, duration, side, notStartEffect); AddPlugin(buff); } else if (buff == stopWorldLevelBuff) { stopWorldLevelBuff.Setup(enteringTimeSlow, duration, ownerRuntimeID); AddPlugin(stopWorldLevelBuff); } buff.isActive = true; Singleton.Instance.FireEvent(new EvtLevelBuffState(buff.levelBuffType, LevelBuffState.Start, side, ownerRuntimeID)); } public bool IsLevelBuffActive(LevelBuffType levelBuffType) { bool result = false; for (int i = 0; i < levelBuffs.Length; i++) { if (levelBuffs[i].levelBuffType == levelBuffType) { result = levelBuffs[i].isActive; break; } } return result; } public virtual void StopLevelBuff(BaseLevelBuff buff) { RemovePlugin(buff); buff.isActive = false; Singleton.Instance.FireEvent(new EvtLevelBuffState(buff.levelBuffType, LevelBuffState.Stop, buff.levelBuffSide, runtimeID)); } public override bool OnEventWithPlugins(BaseEvent evt) { if (evt is EvtLevelState) { return OnLevelState((EvtLevelState)evt); } if (evt is EvtAvatarCreated) { return OnCreateAvatar((EvtAvatarCreated)evt); } if (evt is EvtMonsterCreated) { return OnCreateMonster((EvtMonsterCreated)evt); } if (evt is EvtStageCreated) { return OnCreateStage((EvtStageCreated)evt); } if (evt is EvtStageReady) { return OnStageReady((EvtStageReady)evt); } if (evt is EvtStageTriggerCreated) { return OnStageTriggerCreated((EvtStageTriggerCreated)evt); } if (evt is EvtDynamicObjectCreated) { return OnDynamicObjectCreated((EvtDynamicObjectCreated)evt); } if (evt is EvtHittingOther) { return OnHittingOther((EvtHittingOther)evt); } return false; } public override bool OnEventResolves(BaseEvent evt) { if (evt is EvtHittingOther) { return OnHittingOtherResolve((EvtHittingOther)evt); } return false; } public override bool ListenEvent(BaseEvent evt) { bool flag = base.ListenEvent(evt); if (evt is EvtKilled) { flag |= ListenKill((EvtKilled)evt); } else if (evt is EvtBeingHit) { flag |= ListenBeingHit((EvtBeingHit)evt); } else if (evt is EvtAttackStart) { flag |= ListenAttackStart((EvtAttackStart)evt); } else if (evt is EvtAttackLanded) { flag |= ListenAttackLanded((EvtAttackLanded)evt); } else { if (evt is EvtReviveAvatar) { return ListenReviveAvatar((EvtReviveAvatar)evt); } if (evt is EvtAvatarSwapOutStart) { return ListenSwapOutAvatarStart((EvtAvatarSwapOutStart)evt); } } return flag; } public bool OnCreateAvatar(EvtAvatarCreated evt) { BaseMonoAvatar baseMonoAvatar = (BaseMonoAvatar)Singleton.Instance.GetEntity(evt.avatarID); if (!Singleton.Instance.IsPlayerAvatar(baseMonoAvatar)) { if (Singleton.Instance.IsHelperAvatar(evt.avatarID)) { baseMonoAvatar.gameObject.SetActive(false); } return false; } if (Singleton.Instance.IsLocalAvatar(evt.avatarID)) { if (false) { baseMonoAvatar.PlayState("Story"); } else { baseMonoAvatar.TriggerAppear(); baseMonoAvatar.RefreshController(); } } else if (levelMode == Mode.Single) { baseMonoAvatar.gameObject.SetActive(false); } else { baseMonoAvatar.TriggerAppear(); baseMonoAvatar.RefreshController(); } Singleton.Instance.FireNotify(new Notify(NotifyTypes.OnAvatarCreate, evt.avatarID)); return true; } public bool OnCreateMonster(EvtMonsterCreated evt) { Singleton.Instance.GetInLevelUICanvas().hintArrowManager.AddHintArrow(evt.monsterID); return true; } private bool OnStageTriggerCreated(EvtStageTriggerCreated evt) { Singleton.Instance.GetInLevelUICanvas().hintArrowManager.AddHintArrow(evt.triggerRuntimeID); return true; } private bool OnDynamicObjectCreated(EvtDynamicObjectCreated evt) { if (evt.dynamicType == BaseMonoDynamicObject.DynamicType.Barrier && levelMode != Mode.MultiRemote) { DragAllAvatarsNearLocalAvatar(); } return true; } private void OnLocalAvatarChanged(BaseMonoAvatar from, BaseMonoAvatar to) { Singleton.Instance.SetListenerFollowing(to.transform, new Vector3(0f, 2f, 0f)); Singleton.Instance.GetMainCamera().SetupFollowAvatar(to.GetRuntimeID()); Singleton.Instance.GetInLevelUICanvas().OnUpdateLocalAvatar(to.GetRuntimeID(), from.GetRuntimeID()); Singleton.Instance.GetInLevelUICanvas().OnUpdateLocalAvatarAbilityDisplay(to.GetRuntimeID(), from.GetRuntimeID()); to.RefreshController(); } private void DragAllAvatarsNearLocalAvatar() { BaseMonoAvatar localAvatar = Singleton.Instance.GetLocalAvatar(); BaseMonoAvatar helperAvatar = Singleton.Instance.GetHelperAvatar(); List allPlayerAvatars = Singleton.Instance.GetAllPlayerAvatars(); List list = new List(); if (helperAvatar != null) { list.Add(helperAvatar); } foreach (BaseMonoAvatar item in allPlayerAvatars) { if (item != localAvatar) { list.Add(item); } } foreach (BaseMonoAvatar item2 in list) { if (Physics.Linecast(localAvatar.transform.position, item2.transform.position, 1 << InLevelData.OBSTACLE_COLLIDER_LAYER)) { item2.transform.position = localAvatar.transform.position; } } } private bool ListenSwapOutAvatarStart(EvtAvatarSwapOutStart evt) { if (levelMode == Mode.Single && evt.targetID == _swapOutID && _avatarSwapState == AvatarSwapState.WaitingForEvent) { SwapLocalAvatar(_swapOutID, _swapInID); } return true; } public bool ListenReviveAvatar(EvtReviveAvatar evt) { AvatarActor avatarActor = (AvatarActor)Singleton.Instance.GetActor(evt.avatarID); Vector3 revivePosition; if (evt.isRevivePosAssigned) { revivePosition = evt.revivePosition; } else { BaseMonoAvatar localAvatar = Singleton.Instance.GetLocalAvatar(); revivePosition = ((!(localAvatar != null) || !localAvatar.IsActive()) ? evt.revivePosition : localAvatar.XZPosition); } avatarActor.Revive(revivePosition); Singleton.Instance.GetMainCamera().SetFailPostFX(false); abilityPlugin.AddOrGetAbilityAndTriggerOnTarget(AbilityData.GetAbilityConfig("Level_AvatarReviveInvincible"), avatarActor.runtimeID, 2f); return true; } private string GetFootStepNameFromStageTypeName(string stageTypeName) { string result = "Tile"; if (stageTypeName.IndexOf("Spaceship") != -1) { result = "Metal"; } else if (stageTypeName.IndexOf("ME") != -1) { result = "Concrete"; } else if (stageTypeName.IndexOf("NZ_Town") != -1) { result = "Grass"; } return result; } public bool OnCreateStage(EvtStageCreated evt) { bool sendStageReady; HandleAvatarCreationForStageCreation(evt, out sendStageReady); if (evt.isBorn) { Singleton.Instance.PushSoundBankScale(new string[1] { "BK_InLevel_Common" }); } string footStepNameFromStageTypeName = GetFootStepNameFromStageTypeName(Singleton.Instance.GetStageTypeName()); if (footStepNameFromStageTypeName != null) { List allAvatars = Singleton.Instance.GetAllAvatars(); int i = 0; for (int count = allAvatars.Count; i < count; i++) { Singleton.Instance.SetSwitch("Terrain_Type", footStepNameFromStageTypeName, allAvatars[i].gameObject); } } Singleton.Instance.LoadNavMeshRelatedLevel(Singleton.Instance.GetStageTypeName()); if (sendStageReady) { Singleton.Instance.FireEvent(new EvtStageReady { isBorn = evt.isBorn }); } return true; } protected virtual void HandleAvatarCreationForStageCreation(EvtStageCreated evt, out bool sendStageReady) { List list = new List(); foreach (string avatarSpawnName in evt.avatarSpawnNameList) { int namedSpawnPointIx = Singleton.Instance.GetStageEnv().GetNamedSpawnPointIx(avatarSpawnName); list.Add(Singleton.Instance.GetStageEnv().spawnPoints[namedSpawnPointIx]); } if (evt.isBorn) { Singleton.Instance.CreateTeamAvatars(); Singleton.Instance.InitAvatarsPos(list); Singleton.Instance.InitMonstersPos(evt.offset); } else { Singleton.Instance.InitAvatarsPos(list); Singleton.Instance.InitMonstersPos(evt.offset); } sendStageReady = true; } private bool OnStageReady(EvtStageReady evt) { if (levelState == LevelState.LevelStarted) { levelState = LevelState.LevelRunning; } if (evt.isBorn) { Singleton.Instance.ApplyActiveStageEffectSettingAndStartCheckingForChange(); } Singleton.Instance.FireEvent(new EvtLevelState(EvtLevelState.State.PostStageReady)); return true; } public bool OnLevelState(EvtLevelState evt) { if (evt.state == EvtLevelState.State.Start) { if (levelState == LevelState.LevelLoaded) { levelState = LevelState.LevelStarted; } Singleton.Instance.LevelDesignStart(); } else if (evt.state == EvtLevelState.State.EndWin || evt.state == EvtLevelState.State.EndLose) { levelState = LevelState.LevelEnded; Singleton.Instance.LevelDesignEndWithResult(evt.levelEndReason, evt.cgId); Singleton.Instance.ClearManualPrepareBank(); } else if (evt.state == EvtLevelState.State.EnterTransition) { levelState = LevelState.LevelTransiting; } else if (evt.state == EvtLevelState.State.ExitTransition) { levelState = LevelState.LevelRunning; } else if (evt.state == EvtLevelState.State.PostStageReady) { Singleton.Instance.FireNotify(new Notify(NotifyTypes.PostStageReady)); } return true; } private bool ListenKill(EvtKilled evt) { ushort num = Singleton.Instance.ParseCategory(evt.targetID); if (num == 3) { if (!Singleton.Instance.IsPlayerAvatar(evt.targetID)) { return false; } BaseMonoAvatar baseMonoAvatar = Singleton.Instance.GetAllPlayerAvatars().Find((BaseMonoAvatar avatar) => avatar.IsAlive()); if (baseMonoAvatar == null) { Singleton.Instance.RemoveEventListener(runtimeID); } } Singleton.Instance.RemoveDetourElement(evt.targetID); return true; } public bool ListenBeingHit(EvtBeingHit evt) { ushort num = Singleton.Instance.ParseCategory(evt.targetID); if (num == 4 || num == 3 || num == 7) { if (evt.attackData.hitLevel == AttackResult.ActorHitLevel.Mute) { return true; } Singleton.Instance.FireNotify(new Notify(NotifyTypes.ShowDamegeText, evt)); } return true; } public void TriggerSwapLocalAvatar(uint swapOutID, uint swapInID, bool force) { if ((!force && _swapTimerState == LevelMinSwapTimerState.Running) || _avatarSwapState == AvatarSwapState.Started) { return; } if (levelMode == Mode.Single) { AvatarActor actor = Singleton.Instance.GetActor(swapOutID); if (actor.AllowOtherSwitchIn) { actor.avatar.TriggerSwitchOut(BaseMonoAvatar.AvatarSwapOutType.Delayed); SwapLocalAvatar(swapOutID, swapInID); return; } _swapOutID = swapOutID; _swapInID = swapInID; _avatarSwapState = AvatarSwapState.WaitingForEvent; actor.avatar.TriggerSwitchOut(force ? BaseMonoAvatar.AvatarSwapOutType.Force : BaseMonoAvatar.AvatarSwapOutType.Normal); } else if (levelMode == Mode.Multi || levelMode == Mode.MultiRemote) { SwapLocalAvatar(swapOutID, swapInID); } } public void SwapLocalAvatar(uint swapOutID, uint swapInID) { _avatarSwapState = AvatarSwapState.Started; BaseMonoAvatar avatarByRuntimeID = Singleton.Instance.GetAvatarByRuntimeID(swapOutID); BaseMonoAvatar avatarByRuntimeID2 = Singleton.Instance.GetAvatarByRuntimeID(swapInID); if (levelMode == Mode.Single) { SingleModeSwapTo(avatarByRuntimeID.XZPosition, avatarByRuntimeID.FaceDirection, avatarByRuntimeID2); } else if (levelMode == Mode.Multi || levelMode == Mode.MultiRemote) { MultiModeSwap(avatarByRuntimeID, avatarByRuntimeID2); } } public void SingleModeSwapTo(Vector3 xzPosition, Vector3 forward, BaseMonoAvatar swapInAvatar) { _swapTimerState = LevelMinSwapTimerState.Running; _levelMinSwapTimer = 0.5f; if (swapInAvatar.switchState == BaseMonoAvatar.AvatarSwitchState.OffStage) { swapInAvatar.transform.position = xzPosition; swapInAvatar.SteerFaceDirectionTo(forward); swapInAvatar.gameObject.SetActive(true); swapInAvatar.TriggerSwitchIn(); } else if (swapInAvatar.switchState == BaseMonoAvatar.AvatarSwitchState.SwitchingOut) { swapInAvatar.TriggerSwitchIn(); } else if (swapInAvatar.IsSwitchOutTriggerSet()) { swapInAvatar.ResetTriggerSwitchOut(); } Singleton.Instance.TriggerEntityEffectPattern("Avatar_SwitchRole", swapInAvatar.XZPosition, swapInAvatar.FaceDirection, Vector3.one, levelEntity); if (!Singleton.Instance.IsLocalAvatar(swapInAvatar.GetRuntimeID())) { Singleton.Instance.SetLocalAvatar(swapInAvatar.GetRuntimeID()); } } private void MultiModeSwap(BaseMonoAvatar swapOutAvatar, BaseMonoAvatar swapInAvatar) { _swapTimerState = LevelMinSwapTimerState.Running; _levelMinSwapTimer = 0.5f; Singleton.Instance.SetLocalAvatar(swapInAvatar.GetRuntimeID()); Singleton.Instance.GetMainCamera().SuddenSwitchFollowAvatar(swapInAvatar.GetRuntimeID(), true); if (swapOutAvatar.switchState == BaseMonoAvatar.AvatarSwitchState.OnStage) { swapOutAvatar.RefreshController(); swapOutAvatar.OrderMove = false; } } private bool ListenAttackStart(EvtAttackStart evt) { return false; } private bool ListenAttackLanded(EvtAttackLanded evt) { KeyValuePair item = new KeyValuePair(_frameIndex, evt.animEventID); if (_countAnimEventComboOnceInOneFrame && _frameHitSet.Contains(item)) { return true; } if (evt.attackResult.isAnimEventAttack && evt.attackResult.isInComboCount && !evt.attackResult.rejected && Singleton.Instance.ParseCategory(evt.targetID) == 3 && Singleton.Instance.IsLocalAvatar(evt.targetID)) { _frameHitSet.Add(item); ResetComboTimer(); DelegateUtils.UpdateField(ref levelCombo, (int)levelCombo + 1, onLevelComboChanged); if ((int)Singleton.Instance.maxComboNum < (int)levelCombo) { Singleton.Instance.maxComboNum = levelCombo; } } return true; } public void TimeSlow(float duration) { TimeSlow(duration, 0.05f, null); } public void ResetCombo() { ResetComboTimer(); DelegateUtils.UpdateField(ref levelCombo, 0, onLevelComboChanged); } public void TimeSlow(float duration, float slowRatio, Action doneCallback) { if (_timeSlowTimer > 0f && _timeSlowDoneCallback != null) { _timeSlowDoneCallback(); _timeSlowDoneCallback = null; } _timeSlowTimer = duration; _timeSlowDoneCallback = doneCallback; Time.timeScale = slowRatio; Time.fixedDeltaTime = 0.02f * Time.timeScale; Singleton.Instance.Post("Avatar_TimeSlow_Start"); } public void SetLevelComboTimerState(ComboTimerState state) { _comboTimerState = state; } public override void Core() { _frameIndex++; if (_frameIndex > 20) { _frameHitSet.Clear(); _frameIndex = 0; } base.Core(); if (_timeSlowTimer > 0f) { _timeSlowTimer -= Time.unscaledDeltaTime; if (_timeSlowTimer <= 0f) { Time.timeScale = 1f; Time.fixedDeltaTime = 0.02f * Time.timeScale; Singleton.Instance.Post("Avatar_TimeSlow_End"); if (_timeSlowDoneCallback != null) { _timeSlowDoneCallback(); _timeSlowDoneCallback = null; } } } if (_swapTimerState == LevelMinSwapTimerState.Running) { _levelMinSwapTimer -= levelEntity.TimeScale * Time.deltaTime; if (_levelMinSwapTimer < 0f) { _swapTimerState = LevelMinSwapTimerState.Idle; _levelMinSwapTimer = 0f; } } if (_avatarSwapState == AvatarSwapState.Started) { _avatarSwapState = AvatarSwapState.Idle; } if (!((float)_levelComboTimer > 0f)) { return; } BaseMonoAvatar localAvatar = Singleton.Instance.GetLocalAvatar(); if (localAvatar != null) { string currentSkillID = localAvatar.CurrentSkillID; if (!string.IsNullOrEmpty(currentSkillID) && localAvatar.config.Skills.ContainsKey(currentSkillID)) { float comboTimerPauseNormalizedTimeStart = localAvatar.config.Skills[currentSkillID].ComboTimerPauseNormalizedTimeStart; float comboTimerPauseNormalizedTimeStop = localAvatar.config.Skills[currentSkillID].ComboTimerPauseNormalizedTimeStop; float currentNormalizedTime = localAvatar.GetCurrentNormalizedTime(); if (comboTimerPauseNormalizedTimeStart < comboTimerPauseNormalizedTimeStop) { if (currentNormalizedTime > comboTimerPauseNormalizedTimeStart && currentNormalizedTime < comboTimerPauseNormalizedTimeStop) { _comboTimerState = ComboTimerState.Pause; } else if (currentNormalizedTime > comboTimerPauseNormalizedTimeStop) { _comboTimerState = ComboTimerState.Running; } } } } if (_comboTimerState == ComboTimerState.Running) { _levelComboTimer = (float)_levelComboTimer - levelEntity.TimeScale * Time.deltaTime; } if ((float)_levelComboTimer < 0f) { if (comboTimeUPCallback != null) { comboTimeUPCallback(); } else { DelegateUtils.UpdateField(ref levelCombo, 0, onLevelComboChanged); } } } public void SetAvatarBeAttackMaxNum(int maxNum) { _levelMonsterAIPlugin.SetAvatarBeAttackMaxNum(maxNum); } public void UntargetEntity(BaseMonoEntity target) { List allAvatars = Singleton.Instance.GetAllAvatars(); for (int i = 0; i < allAvatars.Count; i++) { BaseMonoAvatar baseMonoAvatar = allAvatars[i]; BaseMonoEntity baseMonoEntity = baseMonoAvatar.AttackTarget; if (baseMonoEntity is MonoBodyPartEntity) { baseMonoEntity = ((MonoBodyPartEntity)baseMonoEntity).owner; } if (baseMonoAvatar != null && baseMonoAvatar.IsActive() && baseMonoEntity == target) { baseMonoAvatar.SetAttackTarget(null); } } List allMonsters = Singleton.Instance.GetAllMonsters(); for (int j = 0; j < allMonsters.Count; j++) { BaseMonoMonster baseMonoMonster = allMonsters[j]; if (baseMonoMonster != null && baseMonoMonster.IsActive() && baseMonoMonster.AttackTarget == target) { baseMonoMonster.SetAttackTarget(null); } } } public void ResetComboTimer() { _levelComboTimer = (2.8f + GetProperty("Actor_ComboTimerDelta")) * GetProperty("Actor_ComboTimerRatio"); } public override void HealHP(float amount) { } public override void HealSP(float amount) { } protected override void OnAbilityStateAdd(AbilityState state, bool muteDisplayEffect) { } protected override void OnAbilityStateRemove(AbilityState state) { } public override void ForceKill(uint killerID, KillEffect killEffect) { } public void ReviveAvatarByID(uint runtimeID, Vector3 revivePosition) { HideDeadBody(); BaseMonoAvatar avatarByRuntimeID = Singleton.Instance.GetAvatarByRuntimeID(runtimeID); Singleton.Instance.FireEvent(new EvtReviveAvatar(avatarByRuntimeID.GetRuntimeID(), true, revivePosition)); } private void HideDeadBody() { foreach (BaseMonoAvatar allPlayerAvatar in Singleton.Instance.GetAllPlayerAvatars()) { if (!allPlayerAvatar.IsAlive()) { allPlayerAvatar.gameObject.SetActive(false); } } } private bool OnHittingOther(EvtHittingOther evt) { return true; } private bool OnHittingOtherResolve(EvtHittingOther evt) { evt.Resolve(); Singleton.Instance.FireEvent(new EvtBeingHit(evt.toID, runtimeID, evt.animEventID, evt.attackData)); return true; } protected virtual void InitAdditionalLevelActorPlugins() { witchTimeLevelBuff = new LevelBuffWitchTime(this); stopWorldLevelBuff = new LevelBuffStopWorld(this); levelBuffs = new BaseLevelBuff[2]; levelBuffs[0] = witchTimeLevelBuff; levelBuffs[1] = stopWorldLevelBuff; AddPlugin(new LevelAbilityHelperPlugin(this)); } } }