using System.Collections; using System.Threading.Tasks; using Comfort.Common; using EFT; using EFT.SynchronizableObjects; using UnityEngine; namespace SPT.Custom.Airdrops { public class AirdropPlane : MonoBehaviour { private const string PLANE_PATH = "assets/content/location_objects/lootable/prefab/il76md-90.prefab"; private const float RADIUS_TO_PICK_RANDOM_POINT = 3000f; private AirplaneSynchronizableObject airplaneSync; private float speed; private float distanceToDrop; private float flaresCooldown; private bool flaresDeployed; private bool headingChanged; public static async Task Init(Vector3 airdropPoint, int dropHeight, float planeVolume, float speed) { var instance = (await LoadPlane()).AddComponent(); instance.airplaneSync = instance.GetComponent(); // now has new parameter for AirplaneLogicClass, might be wrong instance.airplaneSync.SetLogic(new AirplaneLogicClass(true)); instance.SetPosition(dropHeight, airdropPoint); instance.SetAudio(planeVolume); instance.speed = speed; instance.gameObject.SetActive(false); return instance; } private static async Task LoadPlane() { var easyAssets = Singleton.Instance.EasyAssets; await easyAssets.Retain(PLANE_PATH, null, null).LoadingJob; var plane = Instantiate(easyAssets.GetAsset(PLANE_PATH)); return plane; } private void SetAudio(float planeVolume) { var airplaneAudio = gameObject.AddComponent(); airplaneAudio.clip = airplaneSync.soundClip.Clip; airplaneAudio.dopplerLevel = 1f; airplaneAudio.outputAudioMixerGroup = Singleton.Instance.VeryStandartMixerGroup; airplaneAudio.loop = true; airplaneAudio.maxDistance = 2000; airplaneAudio.minDistance = 1; airplaneAudio.pitch = 0.5f; airplaneAudio.priority = 128; airplaneAudio.reverbZoneMix = 1; airplaneAudio.rolloffMode = AudioRolloffMode.Custom; airplaneAudio.spatialBlend = 1; airplaneAudio.spread = 60; airplaneAudio.volume = planeVolume; airplaneAudio.Play(); } private void SetPosition(int dropHeight, Vector3 airdropPoint) { var pointOnCircle = Random.insideUnitCircle.normalized * RADIUS_TO_PICK_RANDOM_POINT; transform.position = new Vector3(pointOnCircle.x, dropHeight, pointOnCircle.y); transform.LookAt(new Vector3(airdropPoint.x, dropHeight, airdropPoint.z)); } public void ManualUpdate(float distance) { transform.Translate(Vector3.forward * (Time.deltaTime * speed)); distanceToDrop = distance; UpdateFlaresLogic(); if (distance - 200f > 0f || headingChanged) return; StartCoroutine(ChangeHeading()); headingChanged = true; } private void UpdateFlaresLogic() { if (flaresDeployed) return; if (distanceToDrop > 0f && flaresCooldown <= Time.unscaledTime) { flaresCooldown = Time.unscaledTime + 4f; StartCoroutine(DeployFlares(Random.Range(0.2f, 0.4f))); } if (distanceToDrop > 0f) return; flaresDeployed = true; StartCoroutine(DeployFlares(5f)); } private IEnumerator DeployFlares(float emissionTime) { var projectile = Instantiate(airplaneSync.infraredCountermeasureParticles, transform); projectile.transform.localPosition = new Vector3(0f, -5f, 0f); var flares = projectile.GetComponentsInChildren(); var endTime = Time.unscaledTime + emissionTime; Singleton.Instance.SynchronizableObjectLogicProcessor.AirdropManager.AddProjectile(projectile, endTime + flares[0].main.duration + flares[0].main.startLifetime.Evaluate(1f)); while (endTime > Time.unscaledTime) yield return null; projectile.transform.parent = null; foreach (var particleSystem in flares) particleSystem.Stop(); } private IEnumerator ChangeHeading() { var startingRotation = transform.eulerAngles; var middleRotation = startingRotation + new Vector3(0f, 40f, -200f); var endRotation = middleRotation + new Vector3(0f, 40f, 200f); for (float i = 0; i < 1; i += Time.deltaTime / 25f) { var finalRotation = Vector3.Lerp(middleRotation, endRotation, EasingSmoothSquared(i)); transform.eulerAngles = Vector3.Lerp(startingRotation, finalRotation, EasingSmoothSquared(i)); yield return null; } } private float EasingSmoothSquared(float x) { return x < 0.5 ? x * x * 2 : (1 - (1 - x) * (1 - x) * 2); } } }