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 customBurstCount; [SerializeField] private Optional customFireInterval; [SerializeField] private Optional 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(OnAttack); fireLimitTimes.max = customBurstCount.IfNotAllow(1); fireLimitTimes.Reset(); UnityEntity.AddListener(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(OnAttack); UnityEntity.RemoveListener(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(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(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, }); } } }