using System.Linq; using Code.Game.Entities; using Code.Infrastructure.Particles; using Code.Infrastructure.Utils; using Code.OfficeGame.BattleMode.Actions.Deciders; using Code.OfficeGame.BattleMode.Timeline; using UnityEngine; namespace Code.OfficeGame.BattleMode.Actions.Attacks { public class BattleActionPlayerAttackMMA : BattleAction { private AttackActionConfig _attackData; private IParticleService _particleService; public int EntryStateHash => Animator.StringToHash("WalkBlend"); public BattleActionPlayerAttackMMA(MultipleConfig attackData, IParticleService particleService) { _particleService = particleService; _attackData = (AttackActionConfig) attackData.Configs.SingleOrDefault(x => x.ActionType == ActionType); } public override BattleActionType ActionType => BattleActionType.PlayerAttackMMA; public override void Tick(float tickDelta, EntityProperties entity, BattleActionDecisionResult battleActionDecisionResult, BattleActionData battleActionData) { if (battleActionData is not AttackBattleActionData actionData || battleActionDecisionResult is not RotationBattleActionDeciderResult deciderResult) { battleActionData.Finished = true; return; } if (actionData.CurrentFrame == 0) { actionData.TransitionFrames = _attackData.TransitionFrames; actionData.TotalFrames = _attackData.TotalFrames; entity.SyncRootMotionToMotor(); var entityAnimator = entity.animator; entityAnimator.applyRootMotion = true; var transitionTime = actionData.TransitionFrames * BattleTimeline.TickDelta; entityAnimator.CrossFadeInFixedTime(_attackData.StateHash, transitionTime); } else if (actionData.CurrentFrame <= actionData.TransitionFrames && actionData.TransitionFrames > 0) { float t = (float)actionData.CurrentFrame / actionData.TransitionFrames; Quaternion transientRotation = Quaternion.Lerp( entity.KinematicCharacterMotor.TransientRotation, deciderResult.Rotation, t); entity.KinematicCharacterMotor.SetRotation(transientRotation); } actionData.CurrentFrame++; if (actionData.CurrentFrame >= _attackData.HitboxStartFrame && actionData.CurrentFrame <= _attackData.HitboxEndFrame) { entity.EntityHitBoxes.CheckHitsForCurrentFrame(OnEnemyHit, _attackData.AttackingBodyPart); } if (actionData.CurrentFrame >= actionData.TotalFrames) { var entityAnimator = entity.animator; entity.SyncRootMotionToMotor(); entityAnimator.Play(EntryStateHash, 0, 0f); entityAnimator.Update(0f); battleActionData.Finished = true; } } public override DeciderType DeciderType => DeciderType.Rotation; public override BattleActionData MountAndGetFrames(EntityProperties entity, BattleActionDecisionResult result) { return new AttackBattleActionData() { TotalFrames = _attackData.TotalFrames }; } private void OnEnemyHit(Collider enemyCollider) { var originEntityId = enemyCollider.GetComponentInParent().GetEntityId(); var actionData = new StuggerActionData { TotalFrames = _attackData.StuggerFrames, CurrentFrame = 0 }; var decisionResult = new AsIsBattleActionDeciderResult { ActionType = BattleActionType.Stugger }; battleTimeline.ForceDecideAction(originEntityId, actionData, decisionResult); _particleService.EmitOneShot( new ParticlePartitionIDPair(ParticlePartition.HitParticles, 0), 15, enemyCollider.transform.position, Quaternion.identity); } } }