private Ammo PickBestAmmo( TargetTuple target, Vector3 displacement, float distance) { Ammo result = _ammo[0]; float bestDamage = result.EstimateDamageAgainstTarget( target, displacement, distance); for (int i = 1; i < _ammo.Length; i++) { float damage = _ammo[i].EstimateDamageAgainstTarget( target, displacement, distance); if (damage > bestDamage) { result = _ammo[i]; bestDamage = damage; } } return(result); }
public Cannon( CannonConfig data, AudioSource source, Transform barrelTip, float shotVolume = 1.0f) { _shotReload = data.ShotReload; _salvoLength = data.SalvoLength; _salvoReload = data.SalvoReload; _audioSource = source; _shotVolume = shotVolume; _barrelTip = barrelTip; _random = new System.Random(Environment.TickCount); _shellPrefab = Resources.Load <GameObject>("Shell"); _ammo = new Ammo[data.Ammo.Count]; for (int i = 0; i < data.Ammo.Count; i++) { _ammo[i] = new Ammo(data.Ammo[i], _barrelTip); } }
private Ammo PickBestAmmo( TargetTuple target, Vector3 displacement, float distance) { Ammo result = null; float bestDamage = 0; bool mustUseAp = _apRange > distance && target.Type == TargetType.VEHICLE; for (int i = 0; i < Ammo.Length; i++) { if (Ammo[i].ShellCountRemaining == 0) { continue; } float damage = Ammo[i].EstimateDamageAgainstTarget( target, displacement, distance); // Tanks and autocannons dont shoot other vehicles with HE: if (mustUseAp) { if (Ammo[i].DamageType != DamageType.KE && Ammo[i].DamageType != DamageType.HEAT) { damage = 0; } } if (damage > bestDamage) { result = Ammo[i]; bestDamage = damage; } } return(result); }
private bool FireWeapon( TargetTuple target, Vector3 displacement, float distance, bool isServer) { Ammo ammo = PickBestAmmo(target, displacement, distance); if (ammo == null) { return(false); } ammo.ShellCountRemaining--; // sound _audioSource.PlayOneShot(ammo.ShotSound, _shotVolume); if (ammo.MuzzleFlashEffect != null) { ammo.MuzzleFlashEffect.transform.LookAt(target.Position); ammo.MuzzleFlashEffect.Play(); } GameObject shell = GameObject.Instantiate( _shellPrefab, _barrelTip.position, _barrelTip.transform.rotation); GameObject.Instantiate(ammo.ShellArtPrefab, shell.transform); float roll = _random.NextFloat(0.0, 100.0); bool isHit = roll <= ammo.Accuracy; Vector3 shellDestination = target.Position; if (!isHit) { int deviationMode = (int)roll % 4; float missFactor = _random.NextFloat( Constants.MISS_FACTOR_MIN, Constants.MISS_FACTOR_MAX); float weightX = _random.NextFloat(0, 1); switch (deviationMode) { case 0: shellDestination.x += distance * missFactor * weightX; shellDestination.y += distance * missFactor * (1 - weightX); break; case 1: shellDestination.x -= distance * missFactor * weightX; shellDestination.y += distance * missFactor * (1 - weightX); break; case 2: shellDestination.x += distance * missFactor * weightX; shellDestination.y -= distance * missFactor * (1 - weightX); break; case 3: shellDestination.x -= distance * missFactor * weightX; shellDestination.y -= distance * missFactor * (1 - weightX); break; } } ShellBehaviour shellBehaviour = shell.GetComponent <ShellBehaviour>(); shellBehaviour.Initialize(shellDestination, ammo); if (isServer) { if (target.IsUnit) { if (isHit && !ammo.IsAoe) { target.Enemy.HandleHit( ammo.DamageType, ammo.DamageValue, displacement, distance); } } else { // HE damage is applied by the shellBehavior when it explodes } } return(true); }
/// <summary> /// Call in the weapon class to initialize the shell/bullet. /// </summary> /// <param name="velocity">In meters.</param> public void Initialize(Vector3 target, Ammo ammo) { _targetCoordinates = target; _ammo = ammo; }