using System; using System.Collections.Generic; using MoleMole.Config; using UniRx; using UnityEngine; namespace MoleMole { public class AbilityBrokenEnemyDraggedByHitBoxMixin : BaseAbilityMixin { private BrokenEnemyDraggedByHitBoxMixin config; private Dictionary, int> _addedVelocityActorsAndIndexDic = new Dictionary, int>(); private List>> _draggedEnemyList = new List>>(); private List>> _touchedEnemyList = new List>>(); private float _pullVelocity; public AbilityBrokenEnemyDraggedByHitBoxMixin(ActorAbility instancedAbility, ActorModifier instancedModifier, ConfigAbilityMixin config) : base(instancedAbility, instancedModifier, config) { this.config = (BrokenEnemyDraggedByHitBoxMixin)config; _pullVelocity = instancedAbility.Evaluate(this.config.PullVelocity); } public override void OnAdded() { (entity as IAttacker).onAnimatedHitBoxCreatedCallBack += onAnimatedHitBoxCreated; } public override void OnRemoved() { (entity as IAttacker).onAnimatedHitBoxCreatedCallBack -= onAnimatedHitBoxCreated; foreach (Tuple> draggedEnemy in _draggedEnemyList) { foreach (BaseAbilityActor item in draggedEnemy.Item2) { RemoveAdditiveVelocity(item, draggedEnemy.Item1); } } } public override bool OnPostEvent(BaseEvent evt) { if (evt is EvtAttackLanded) { OnAttackLandedOther((EvtAttackLanded)evt); } return false; } private bool OnAttackLandedOther(EvtAttackLanded evt) { MonoAnimatedHitboxDetect monoAnimatedHitboxDetect = null; bool flag = false; foreach (Tuple> touchedEnemy in _touchedEnemyList) { if (touchedEnemy.Item1 == null || !touchedEnemy.Item2.Contains(evt.attackeeID)) { continue; } monoAnimatedHitboxDetect = touchedEnemy.Item1; flag = true; break; } if (!flag) { return false; } if (evt.attackResult.hitEffect <= AttackResult.AnimatorHitEffect.Light) { return false; } BaseAbilityActor baseAbilityActor = Singleton.Instance.GetActor(evt.attackeeID); if (baseAbilityActor == null) { return false; } HashSet hashSet = null; foreach (Tuple> draggedEnemy in _draggedEnemyList) { if (draggedEnemy.Item1 == monoAnimatedHitboxDetect) { hashSet = draggedEnemy.Item2; if (draggedEnemy.Item2.Contains(baseAbilityActor)) { return false; } } } if (hashSet != null) { hashSet.Add(baseAbilityActor); SetAdditiveVelocity(baseAbilityActor, monoAnimatedHitboxDetect); } return true; } private void onAnimatedHitBoxCreated(MonoAnimatedHitboxDetect hitBox, ConfigEntityAttackPattern attackPattern) { if (!(attackPattern is AnimatedColliderDetect) && !(attackPattern is TargetLockedAnimatedColliderDetect)) { return; } if (attackPattern is AnimatedColliderDetect) { AnimatedColliderDetect animatedColliderDetect = attackPattern as AnimatedColliderDetect; if (!animatedColliderDetect.brokenEnemyDragged) { return; } } else if (attackPattern is TargetLockedAnimatedColliderDetect) { TargetLockedAnimatedColliderDetect targetLockedAnimatedColliderDetect = attackPattern as TargetLockedAnimatedColliderDetect; if (!targetLockedAnimatedColliderDetect.brokenEnemyDragged) { return; } } if (!(hitBox.entryName != config.ColliderEntryName)) { hitBox.enemyEnterCallback = (Action)Delegate.Combine(hitBox.enemyEnterCallback, new Action(HitBoxTriggerEnterCallback)); hitBox.destroyCallback = (Action)Delegate.Combine(hitBox.destroyCallback, new Action(onAnimatedHitBoxDestroy)); _draggedEnemyList.Add(new Tuple>(hitBox, new HashSet())); _touchedEnemyList.Add(new Tuple>(hitBox, new HashSet())); } } private void onAnimatedHitBoxDestroy(MonoAnimatedHitboxDetect hitbox) { List>> list = new List>>(); foreach (Tuple> draggedEnemy in _draggedEnemyList) { if (!(draggedEnemy.Item1 == hitbox)) { continue; } list.Add(draggedEnemy); foreach (BaseAbilityActor item in draggedEnemy.Item2) { RemoveAdditiveVelocity(item, hitbox); } } foreach (Tuple> item2 in list) { _draggedEnemyList.Remove(item2); } List>> list2 = new List>>(); foreach (Tuple> touchedEnemy in _touchedEnemyList) { if (touchedEnemy.Item1 == hitbox) { list2.Add(touchedEnemy); } } foreach (Tuple> item3 in list2) { _touchedEnemyList.Remove(item3); } List> list3 = new List>(); foreach (Tuple key in _addedVelocityActorsAndIndexDic.Keys) { if (key.Item1 == hitbox) { list3.Add(key); } } } private void HitBoxTriggerEnterCallback(MonoAnimatedHitboxDetect hitbox, Collider other) { if (hitbox.entryName != config.ColliderEntryName) { return; } BaseMonoEntity componentInParent = other.GetComponentInParent(); BaseAbilityActor baseAbilityActor = Singleton.Instance.GetActor(componentInParent.GetRuntimeID()); if (baseAbilityActor == null) { return; } ushort num = Singleton.Instance.ParseCategory(componentInParent.GetRuntimeID()); if (num != 3 && num != 4) { return; } HashSet hashSet = new HashSet(Singleton.Instance.GetEnemyActorsOf(baseAbilityActor)); if (!hashSet.Contains(actor)) { return; } bool flag = false; foreach (Tuple> draggedEnemy in _draggedEnemyList) { if (draggedEnemy.Item1 == hitbox) { flag = true; break; } } if (!flag) { return; } HashSet hashSet2 = null; foreach (Tuple> touchedEnemy in _touchedEnemyList) { if (touchedEnemy.Item1 == hitbox) { hashSet2 = touchedEnemy.Item2; if (touchedEnemy.Item2.Contains(baseAbilityActor.runtimeID)) { return; } } } if (hashSet2 != null) { hashSet2.Add(baseAbilityActor.runtimeID); } } public override void Core() { foreach (Tuple> draggedEnemy in _draggedEnemyList) { if (draggedEnemy.Item1 == null) { foreach (BaseAbilityActor item in draggedEnemy.Item2) { RemoveAdditiveVelocity(item, draggedEnemy.Item1); } continue; } foreach (BaseAbilityActor item2 in draggedEnemy.Item2) { SetAdditiveVelocity(item2, draggedEnemy.Item1); } } } private void SetAdditiveVelocity(BaseAbilityActor enemyActor, MonoAnimatedHitboxDetect hitbox) { if (enemyActor != null && (bool)enemyActor.isAlive && !(enemyActor.entity == null)) { Vector3 additiveVelocity = hitbox.collideCenterTransform.position - enemyActor.entity.XZPosition; additiveVelocity.y = 0f; additiveVelocity.Normalize(); DoSetAdditiveVelocity(enemyActor, hitbox, additiveVelocity); } } private void DoSetAdditiveVelocity(BaseAbilityActor targetActor, MonoAnimatedHitboxDetect hitbox, Vector3 additiveVelocity) { if (targetActor != null) { Tuple key = new Tuple(hitbox, targetActor); if (!_addedVelocityActorsAndIndexDic.ContainsKey(key)) { targetActor.entity.SetHasAdditiveVelocity(true); int value = targetActor.entity.AddAdditiveVelocity(additiveVelocity * _pullVelocity); _addedVelocityActorsAndIndexDic.Add(key, value); } else { targetActor.entity.SetHasAdditiveVelocity(true); int index = _addedVelocityActorsAndIndexDic[key]; targetActor.entity.SetAdditiveVelocityOfIndex(additiveVelocity * _pullVelocity, index); } } } private void RemoveAdditiveVelocity(BaseAbilityActor targetActor, MonoAnimatedHitboxDetect hitbox) { if (targetActor != null && (bool)targetActor.isAlive && !(targetActor.entity == null)) { Tuple key = new Tuple(hitbox, targetActor); if (_addedVelocityActorsAndIndexDic.ContainsKey(key)) { int index = _addedVelocityActorsAndIndexDic[key]; targetActor.entity.SetAdditiveVelocityOfIndex(Vector3.zero, index); targetActor.entity.SetHasAdditiveVelocity(false); _addedVelocityActorsAndIndexDic.Remove(key); } } } } }