private bool isValidSide(Vector3 vector) { if (!_motor.IsFree(vector, 0.5f, 0.1f)) { return(false); } if (AIUtil.IsObstructed(transform.position + Vector3.up * 2, _target + Vector3.up * 2, 1000)) { return(false); } return(true); }
private bool isValidCover(Cover cover, Vector3 position, int direction, bool checkPath, bool avoidPivot = true) { if (cover == _unreachableCover) { return(false); } if (_isKeepingCloseTo && Vector3.Distance(position, _keepCloseTo.Position) > _keepCloseTo.Distance) { return(false); } if (!_hasPivot) { if (!AIUtil.IsCoverPositionFree(cover, position, 1, _actor)) { return(false); } return(true); } if (!_hasCachedEnemies) { _cachedEnemyCount = 0; _hasCachedEnemies = true; var totalActorCount = AIUtil.FindActors(position, MinDefenselessDistance, _actor); if (totalActorCount > 0) { var enemyCount = 0; for (int i = 0; i < totalActorCount; i++) { if (AIUtil.Actors[i].Side != _actor.Side) { enemyCount++; } } if (enemyCount > 0) { if (_cachedEnemies == null || _cachedEnemies.Length < enemyCount) { _cachedEnemies = new Actor[enemyCount]; } var index = 0; for (int i = 0; i < totalActorCount; i++) { if (AIUtil.Actors[i].Side != _actor.Side) { _cachedEnemies[index++] = AIUtil.Actors[i]; } } _cachedEnemyCount = index; } } } for (int i = 0; i < _cachedEnemyCount; i++) { var enemy = _cachedEnemies[i]; if (enemy.Side != _actor.Side) { var enemyPosition = enemy.transform.position; var distance = Vector3.Distance(position, enemyPosition); if (distance < AvoidDistance) { return(false); } if (!AIUtil.IsGoodAngle(MaxTallCoverThreatAngle, MaxLowCoverThreatAngle, cover, position, enemyPosition, cover.IsTall)) { return(false); } } } if (_isPivotThreat) { var distance = Vector3.Distance(position, _pivotPosition); if (_hasMaxPivotDistance && distance > _maxPivotDistance) { return(false); } var aimPosition = position; if (AIUtil.IsObstructed(aimPosition + (_actor.StandingTopPosition - transform.position), _pivotPosition + Vector3.up * 2)) { return(false); } } else { var distance = Vector3.Distance(position, _pivotPosition); if (_hasMaxPivotDistance && distance > _maxPivotDistance) { return(false); } if (!AIUtil.IsGoodAngle(MaxDefenseAngle, MaxDefenseAngle, cover, _pivotPosition, position, cover.IsTall)) { return(false); } } if (!AIUtil.IsCoverPositionFree(cover, position, 1, _actor)) { return(false); } if (checkPath) { if (NavMesh.CalculatePath(transform.position, position, 1, _path)) { if (avoidPivot) { var count = _path.GetCornersNonAlloc(_corners); for (int i = 0; i < count; i++) { var a = i == 0 ? transform.position : _corners[i - 1]; var b = _corners[i]; var closest = Util.FindClosestToPath(a, b, _pivotPosition); if (Vector3.Distance(closest, _pivotPosition) < AvoidDistance) { return(false); } } } } else { return(false); } } return(true); }
private void Update() { if (!_actor.IsAlive) { return; } var wantsToAlwaysAim = AlwaysAim && _motor.Cover == null; if (wantsToAlwaysAim) { Equip(_motor); } if (_motor.Gun == null) { return; } if (_isReloading) { _isReloading = !_motor.IsGunReady; } else if (_motor.Gun != null && _motor.Gun.IsClipEmpty) { _isReloading = true; _motor.InputReload(); } var isObstructed = false; if (_isFiring && _isAimingAtAPosition) { var origin = transform.position; if (_motor.Cover != null && _motor.Cover.IsTall) { if (_motor.CoverDirection > 0 && _motor.IsNearRightCorner) { origin = _motor.Cover.RightCorner(transform.position.y, _motor.CoverSettings.CornerOffset.x); } else if (_motor.CoverDirection < 0 && _motor.IsNearLeftCorner) { origin = _motor.Cover.LeftCorner(transform.position.y, _motor.CoverSettings.CornerOffset.x); } } var start = origin + Vector3.up * 2; var distance = Vector3.Distance(start, _aim); if (distance > 1.5f) { isObstructed = AIUtil.IsObstructed(start, _aim, distance - 1.5f); } } if (_motor.Cover == null && (_isAiming || wantsToAlwaysAim) && !_isReloading) { _motor.InputAim(); } if (_isFiring && !_isReloading && !isObstructed) { var cycleDuration = _motor.Cover != null ? CoverBursts.CycleDuration : Bursts.CycleDuration; if (_fireCycle >= cycleDuration) { if (_isFiringABurst) { _gunBurstsWereCalculatedFor = _motor.Gun; _burstBulletCount = _bulletCountAtStart - _motor.Gun.Clip; } _isFiringABurst = false; _fireCycle -= cycleDuration; if (_gunBurstsWereCalculatedFor == _motor.Gun && _motor.Gun.Clip < _burstBulletCount) { _isReloading = true; _motor.InputReload(); } } if (_motor.Cover != null) { if (_fireCycle >= CoverBursts.Wait) { _motor.InputAim(); if (_fireCycle >= CoverBursts.Wait + CoverBursts.IntroDuration && _fireCycle < CoverBursts.CycleDuration - CoverBursts.OutroDuration) { if (!_isFiringABurst) { _bulletCountAtStart = _motor.Gun.Clip; _isFiringABurst = true; } if (_motor.IsGunReady) { _motor.InputFireOnCondition(_actor.Side); } } } } else { _motor.InputAim(); if (_fireCycle >= Bursts.Wait) { if (!_isFiringABurst) { _bulletCountAtStart = _motor.Gun.Clip; _isFiringABurst = true; } if (_motor.IsGunReady) { _motor.InputFireOnCondition(_actor.Side); } } } _fireCycle += Time.deltaTime; } else { _fireCycle = 0; _isFiringABurst = false; } }
private bool isValidCover(Cover cover, Vector3 position, int direction, bool checkPath) { if (!_hasThreat) { return(true); } if (Vector3.Distance(position, _threatPosition) < AvoidDistance) { return(false); } if (!AIUtil.IsGoodAngle(MaxTallCoverAngle, MaxLowCoverAngle, cover, position, _threatPosition, cover.IsTall)) { return(false); } if (!AIUtil.IsCoverPositionFree(cover, position, 1, _actor)) { return(false); } var aimPosition = position; if (cover.IsTall) { var angle = Util.AngleOfVector(_threatPosition - position); if (direction > 0) { if (!cover.IsFrontField(angle, _motor.CoverSettings.Angles.TallRightCornerFront)) { return(false); } if (!cover.IsRight(angle, _motor.CoverSettings.Angles.RightCorner, false)) { return(false); } aimPosition = cover.RightCorner(cover.Bottom, _motor.CoverSettings.CornerOffset.x); } else if (direction < 0) { if (!cover.IsFrontField(angle, _motor.CoverSettings.Angles.TallLeftCornerFront)) { return(false); } if (!cover.IsLeft(angle, _motor.CoverSettings.Angles.LeftCorner, false)) { return(false); } aimPosition = cover.LeftCorner(cover.Bottom, _motor.CoverSettings.CornerOffset.x); } } if (AIUtil.IsObstructed(aimPosition + (_actor.StandingTopPosition - transform.position), _threatPosition + Vector3.up * 2, 100)) { return(false); } if (checkPath) { if (Vector3.Distance(transform.position, _threatPosition) > AvoidDistance) { if (NavMesh.CalculatePath(transform.position, position, 1, _path)) { for (int i = 0; i < _path.GetCornersNonAlloc(_corners); i++) { var a = i == 0 ? transform.position : _corners[i - 1]; var b = _corners[i]; var closest = Util.FindClosestToPath(a, b, _threatPosition); if (Vector3.Distance(closest, _threatPosition) < AvoidDistance) { return(false); } } } else { return(false); } } } return(true); }