BITFALL/Assets/Artists/Scripts/Equip/AIGunController.cs

143 lines
3.5 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using BITFALL.Bullet;
using BITFALL.Entities.Equipment;
using BITKit;
using BITKit.Entities;
using BITKit.StateMachine;
using Unity.Mathematics;
using UnityEngine;
namespace BITFALL.Guns
{
public class AIGunController : AIEquipController
{
[SerializeField] private Transform firePoint;
[SerializeReference,SubclassSelector] private IBulletService bulletService;
[SerializeField] private bool forceFire;
[SerializeField] private Optional<int> customBurstCount;
[SerializeField] private Optional<IntervalUpdate> customFireInterval;
[SerializeField] private Optional<float> overrideRecoil;
private AssetableGun _gun=>assetableItem as AssetableGun;
private readonly IntervalUpdate fireInterval = new();
private readonly LimitTimes fireLimitTimes=new()
{
max = 3
};
public override void Entry()
{
base.Entry();
fireInterval.Interval = _gun.FireMode.FireRate is 0 ? 1 : 1f/_gun.FireMode.FireRate;
UnityEntity.AddListener<BITConstant.Command.AttackCommand>(OnAttack);
fireLimitTimes.max = customBurstCount.IfNotAllow(1);
fireLimitTimes.Reset();
UnityEntity.AddListener<string>(OnCommand);
}
private void OnCommand(string obj)
{
switch (obj)
{
case BITConstant.Player.Fire:
RequestFire();
break;
case BITConstant.Player.Melee:
RequestMelee();
fireInterval.AddDelay(1);
break;
}
}
public override void Exit()
{
base.Exit();
UnityEntity.RemoveListener<BITConstant.Command.AttackCommand>(OnAttack);
UnityEntity.RemoveListener<string>(OnCommand);
}
public override void OnUpdate(float deltaTime)
{
if (forceFire)
{
RequestFire();
}
}
private void RequestFire()
{
if (fireInterval.AllowUpdate)
{
if (customFireInterval.Allow)
{
if (customFireInterval.Value.AllowUpdate)
{
//OnAttack(new BITConstant.Command.AttackCommand());
fireLimitTimes.Reset();
}
else
{
if (fireLimitTimes.Allow)
OnAttack(new BITConstant.Command.AttackCommand());
}
}
else
{
OnAttack(new BITConstant.Command.AttackCommand());
}
}
}
private void OnAttack(BITConstant.Command.AttackCommand obj)
{
for (var i = 0; i < _gun.BuckShot.IfNotAllow(1); i++)
{
InternalFire();
}
UnityEntity.Invoke(Constant.Animation.Play, BITConstant.Player.Fire);
}
private void InternalFire()
{
var random = UnityEngine.Random.insideUnitCircle;
if (_gun.TryGetProperty<ISpread>(out var spread))
{
random *= spread.Spread;
}
if (overrideRecoil.Allow)
{
random *= overrideRecoil.Value;
}
var rotation = firePoint.rotation;
if(targetSensor is not null && targetSensor.Get().TryGetFirstOrDefault(out var target))
{
if (target.TryGetComponent<IEntityMovement>(out var targetMovement))
{
rotation = Quaternion.LookRotation(targetMovement.ViewCenter - firePoint.position);
}
else
{
rotation = Quaternion.LookRotation(target.position - firePoint.position);
}
}
bulletService.Spawn(new SpawnBullet()
{
Forward = rotation * (Vector3.forward + Vector3.up * random.y + Vector3.right * random.x),
InitialDamage =overrideDamage.IfNotAllow( _gun.InitialDamage),
Initiator = Entity.Id,
Position = firePoint.position,
Rotation = rotation,
StartSpeed = _gun.InitialBulletSpeed,
InitialForce = _gun.InitialBulletForce,
});
}
}
}