Files
Hasebe/Assets/Code/OfficeGame/BattleMode/Actions/Attacks/BattleActionPlayerAttackMMA.cs
T
2026-11-06 19:40:08 +03:00

108 lines
4.2 KiB
C#

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<BattleActionParameters> 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<EntityProperties>().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);
}
}
}