public bool PrepareForTakeOff(string vehicleName, out Airstrip airstrip) { List <Airstrip> availableStrips = new List <Airstrip>(); foreach (Airstrip airStrip in airStrips) { if (airStrip.CanTakeOff(vehicleName)) { availableStrips.Add(airStrip); } } if (availableStrips.Count == 0) { airstrip = null; return(false); } int index = UnityEngine.Random.Range(0, availableStrips.Count); bool hasTookOff = availableStrips[index].PrepareForTakeOff(vehicleName); if (hasTookOff) { airstrip = availableStrips[index]; } else { airstrip = null; } return(hasTookOff); }
public void SwitchDirectionsTest() { Airstrip test = new Airstrip("test", 1, 1, true, 1); test.SwitchDirections(); Assert.AreEqual(test.TakeOffDirection, 181); }
public void CancelTakeOff(Airstrip airStrip) { if (airStrip.vehicleAttached == null || airStrip.vehicleIsDeploying == false) { return; } airStrip.CancelTakeOff(); }
public void AirstripTest() { Airstrip test = new Airstrip("test", 1, 1, true, 1); Assert.AreEqual(test.Name, "test"); Assert.AreEqual(test.CoordinateX, 1); Assert.AreEqual(test.CoordinateY, 1); Assert.AreEqual(test.IsFree, true); Assert.AreEqual(test.TakeOffDirection, 1); }
public override void OnFixedUpdate() { base.OnFixedUpdate(); if (isDead) { return; } if (fuel == 0) { return; } if (isRTB) { Vehicle target = null; if (takeOffFrom == null || takeOffFrom.isDead || takeOffFrom.airstripCtrl.airStrips.Any((Airstrip airStrip) => airStrip.enabled && airStrip.canLandAir) == false) { Dictionary <Vehicle, float> distances = new Dictionary <Vehicle, float>(); // We need to find another vessel to land. foreach (Vehicle v in SceneManager.instance.vehicles) { if (v == null) { continue; } if (v.isDead) { continue; } if (v.side != side) { continue; } if (v.airstripCtrl == null) { continue; } if (v.airstripCtrl.airStrips.Count == 0) { continue; } if (v.airstripCtrl.airStrips.Any((Airstrip airStrip) => airStrip.enabled && airStrip.canLandAir) == false) { continue; } distances.Add(v, Vector3.Distance(position, v.position)); } if (distances.Count > 0) { float minDistance = distances.Values.Min(); Vehicle nearestVehicle = distances.First((KeyValuePair <Vehicle, float> kv) => kv.Value == minDistance).Key; target = nearestVehicle; } else { // Cannot return to base. isRTB = false; return; } } else { target = takeOffFrom; } if (isAligned == false) { //Debug.Log("Align..."); // Fly away to make sufficient space. float distance = Vector3.Distance(position, target.position - Vector3.Normalize(target.velocity) * alignDistance); if (distance > approachDistance) { //Debug.Log("Aligning..."); Vector3 approachTarget = target.position - Vector3.Normalize(target.velocity) * alignDistance; float expectedCourse = Mathf.Rad2Deg * Mathf.Atan2(approachTarget.x - position.x, approachTarget.z - position.z); locomotor.orderedCourse = expectedCourse; if (locomotor.orderedCourse > 360f) { locomotor.orderedCourse -= 360f; } if (locomotor.orderedCourse < 0f) { locomotor.orderedCourse += 360f; } locomotor.orderedPitch = Mathf.Clamp(0.2f * ((20f + approachDistance * 0.06f) - position.y) / speed, -30f, 30f); locomotor.orderedSpeed = maxSpeed * 0.6f; } else { isAligned = true; } } else { float distance = Vector3.Distance(position, target.position); Vector3 approachTarget; if (distance > landDistance) { //Debug.Log("Approaching..."); approachTarget = target.position - Vector3.Normalize(target.velocity) * distance * 0.75f; approachTarget.y = 20f + distance * 0.06f; } else { //Debug.Log("Trying to land..."); if (target.airstripCtrl.airStrips.Any((Airstrip airStrip) => airStrip.enabled && airStrip.vehicleAttached == this)) { // We've already been assigned to an airstrip. Airstrip assignedAirStrip = target.airstripCtrl.airStrips.Find((Airstrip a) => a.enabled && a.vehicleAttached == this); approachTarget = assignedAirStrip.landStartPoint.position; if (assignedAirStrip.Land(this) == true) { // A success landing! The movement control is handed-over to the vehicle. isRTB = false; isAligned = false; return; } } else { // We have no airStrip assigned yet. Airstrip availableAirstrip = target.airstripCtrl.Land(this); if (availableAirstrip != null) { //Debug.Log("Airstrip available!"); availableAirstrip.vehicleAttached = this; approachTarget = availableAirstrip.landStartPoint.position; if (availableAirstrip.Land(this) == true) { // A success landing! The movement control is handed-over to the vehicle. isRTB = false; isAligned = false; return; } } else { //Debug.Log("Go around!"); // No airstrip is available now. Go around! isAligned = false; return; } } } float expectedCourse = Mathf.Rad2Deg * Mathf.Atan2(approachTarget.x - position.x, approachTarget.z - position.z); locomotor.orderedCourse = expectedCourse; if (locomotor.orderedCourse > 360f) { locomotor.orderedCourse -= 360f; } if (locomotor.orderedCourse < 0f) { locomotor.orderedCourse += 360f; } float expectedPitch = Mathf.Rad2Deg * Mathf.Atan2(approachTarget.y - position.y, Mathf.Sqrt(Mathf.Pow(approachTarget.z - position.z, 2) + Mathf.Pow(approachTarget.x - position.x, 2))); locomotor.orderedPitch = expectedPitch; locomotor.orderedSpeed = Mathf.Clamp(distance * landSpeedFactor + landSpeedConstant, minSpeed, maxSpeed * 0.4f) + target.speed; } } else { if (useAltCommand) { locomotor.orderedPitch = Mathf.Clamp(kP * (newOrderedAlt - position.y) / speed, -40f, 40f); } if (position.y < 10f || (velocity.y < 0 && position.y / velocity.y < 20f)) { locomotor.orderedPitch = Mathf.Max(Mathf.Clamp((10f - position.y) / speed, -5f, 20f), locomotor.orderedPitch); } if (mainTrack != null && (mainTrack.target == null || (mainTrack.target != null && mainTrack.target.isDead == true))) { mainTrack = null; } } }
void OnGUI() { int i = 0; Track trackToBeEngaged = null; if (selectedVehicle != null && selectedLauncherVehicle != "") { GUI.Label(new Rect(10f, 10f, 50f, 20f), "Targets:"); } else { GUI.Label(new Rect(10f, 10f, 50f, 20f), "Units:"); } viewAir = GUI.Toggle(new Rect(60f, 10f, 50f, 20f), viewAir, "Air", "button"); viewSurf = GUI.Toggle(new Rect(120f, 10f, 50f, 20f), viewSurf, "Surf", "button"); viewSub = GUI.Toggle(new Rect(180f, 10f, 50f, 20f), viewSub, "Sub", "button"); viewWeapon = GUI.Toggle(new Rect(240f, 10f, 50f, 20f), viewWeapon, "Weap", "button"); viewNonWeapon = GUI.Toggle(new Rect(300f, 10f, 50f, 20f), viewNonWeapon, "NoWeap", "button"); viewSide0 = GUI.Toggle(new Rect(360f, 10f, 50f, 20f), viewSide0, "Side0", "button"); viewSide1 = GUI.Toggle(new Rect(420f, 10f, 50f, 20f), viewSide1, "Side1", "button"); viewSideNeutral = GUI.Toggle(new Rect(480f, 10f, 50f, 20f), viewSideNeutral, "Neutral", "button"); showPlumbLine = GUI.Toggle(new Rect(540f, 10f, 50f, 20f), showPlumbLine, "PL"); showIntentionLine = GUI.Toggle(new Rect(600f, 10f, 50f, 20f), showIntentionLine, "IL"); showName = GUI.Toggle(new Rect(660f, 10f, 50f, 20f), showName, "Name"); if (showName) { foreach (Vehicle vehicle in SceneManager.instance.vehicles) { if (Vehicle.sVehicleCanBeTracked[vehicle.typeName]) { Vector3 screenPoint = vehicleCamera.WorldToScreenPoint(vehicle.transform.position); if (screenPoint.z > 0) { if (vehicle.side == 0) { GUI.contentColor = Color.blue; } else if (vehicle.side == 1) { GUI.contentColor = Color.red; } else if (vehicle.side == -1) { GUI.contentColor = Color.white; } GUI.Label(new Rect(screenPoint.x, Screen.height - screenPoint.y, 200f, 30f), vehicle.typeName); } } } } GUI.contentColor = Color.white; GUILayout.BeginArea(new Rect(10f, 40f, 280f, Screen.height - 50f)); scrollPosition = GUILayout.BeginScrollView(scrollPosition); foreach (Vehicle vehicle in SceneManager.instance.vehicles) { if (Vehicle.sVehicleTypes[vehicle.typeName] == Vehicle.VehicleType.Air && viewAir == false) { continue; } if (Vehicle.sVehicleTypes[vehicle.typeName] == Vehicle.VehicleType.Surf && viewSurf == false) { continue; } if (Vehicle.sVehicleTypes[vehicle.typeName] == Vehicle.VehicleType.Sub && viewSub == false) { continue; } if (vehicle.GetComponent <WarheadModule>() != null && viewWeapon == false) { continue; } if (vehicle.GetComponent <WarheadModule>() == null && viewNonWeapon == false) { continue; } if (selectedLauncherVehicle == "") { if (vehicle.side == 0 && viewSide0 == false) { continue; } if (vehicle.side == 1 && viewSide1 == false) { continue; } if (vehicle.side == -1 && viewSideNeutral == false) { continue; } } if (Vehicle.sVehicleCanBeTracked[vehicle.typeName]) { if (selectedVehicle != null && selectedLauncherVehicle != "") { if (vehicle.isDead) { continue; } if (vehicle.side == -1 || vehicle.side == selectedVehicle.side) { continue; } if (selectedVehicle.sensorCtrl == null || selectedVehicle.sensorCtrl.tracksDetected.Exists((Track trk) => trk.target == vehicle) == false) { continue; } Track track = selectedVehicle.sensorCtrl.tracksDetected.Find((Track trk) => trk.target == vehicle); if (selectedVehicle.launcherCtrl.CanEngageWith(track, selectedLauncherVehicle, false) == false) { continue; } bool engage = GUILayout.Button(vehicle.typeName, GUILayout.Height(15f)); if (engage) { trackToBeEngaged = track; } i++; } else { bool selected = selectedVehicle == vehicle; bool nowSelected = (GUILayout.Toggle(selectedVehicle == vehicle, vehicle.typeName + (vehicle.isDead ? "(Dead)" : ""), "button", GUILayout.Height(15f))); if (selected && nowSelected == false) { //vehicleCamera.transform.parent = null; selectedVehicle = null; vehicleCamera.GetComponent <MouseOrbit>().target = null; } else if (selected == false && nowSelected) { selectedVehicle = vehicle; vehicleCamera.transform.parent = vehicle.transform; vehicleCamera.transform.localPosition = new Vector3(500f, 500f, 500f); vehicleCamera.transform.LookAt(vehicle.transform); vehicleCamera.transform.parent = null; vehicleCamera.GetComponent <MouseOrbit>().target = vehicle.transform; //vehicleCamera.GetComponent<MouseOrbit>().UpdateState(); } ++i; } } } GUILayout.EndScrollView(); GUILayout.EndArea(); if (trackToBeEngaged != null) { selectedVehicle.launcherCtrl.Launch(selectedLauncherVehicle, trackToBeEngaged); if (selectedVehicle.launcherCtrl.CanEngageWith(trackToBeEngaged, selectedLauncherVehicle, false, true) == false) { selectedLauncherVehicle = ""; } } if ( selectedVehicle == null || selectedVehicle.launcherCtrl == null || selectedVehicle.launcherCtrl.launchers.Any ( (Launcher launcher) => launcher.enabled && launcher.vehicleNames.Contains(selectedLauncherVehicle) && launcher.vehicleCounts[launcher.vehicleNames.IndexOf(selectedLauncherVehicle)] > 0 ) == false ) { // No launcher available for the selected weapon. (perhaps due to damage) selectedLauncherVehicle = ""; } if (selectedVehicle != null) { GUILayout.BeginArea(new Rect(Screen.width - 310f, 10f, 300f, 1500f)); { GUILayout.BeginVertical(); { GUILayout.Label("Unit: " + selectedVehicle.typeName + " (" + selectedVehicle.armorModule.armorPoint.ToString("F0") + "/" + selectedVehicle.armorModule.maxArmorPoint.ToString("F0") + ")" + " Side: " + selectedVehicle.side.ToString()); if (selectedVehicle.GetComponent <GuidanceModule>() != null) { GuidanceModule guidanceModule = selectedVehicle.GetComponent <GuidanceModule>(); GUILayout.Label("Guidance: " + guidanceModule.GetType().Name); if (guidanceModule.targetTrack != null) { GUILayout.Label(guidanceModule.targetTrack.vehicleTypeName + "(" + guidanceModule.targetTrack.age.ToString("F0") + "): " + Vector3.Distance(selectedVehicle.position, guidanceModule.targetTrack.predictedPosition).ToString("F0")); } else if (guidanceModule.guidanceParameter is Vector3) { GUILayout.Label(((Vector3)guidanceModule.guidanceParameter).ToString() + ": " + Vector3.Distance((Vector3)guidanceModule.guidanceParameter, selectedVehicle.position).ToString("F0")); } } selectedVehicle.OnVehicleControllerGUI(); if (selectedVehicle.launcherCtrl != null && selectedVehicle.launcherCtrl.launchers.Count > 0) { GUILayout.Label("Weapon: "); List <string> launcherVehicles = new List <string>(); List <int> launcherVehicleCount = new List <int>(); foreach (Launcher launcher in selectedVehicle.launcherCtrl.launchers) { if (launcher.enabled == false) { continue; } for (int j = 0; j < launcher.vehicleNames.Count; ++j) { if (launcherVehicles.Contains(launcher.vehicleNames[j])) { launcherVehicleCount[launcherVehicles.IndexOf(launcher.vehicleNames[j])] += launcher.vehicleCounts[j]; } else { launcherVehicles.Add(launcher.vehicleNames[j]); launcherVehicleCount.Add(launcher.vehicleCounts[j]); } } } if (launcherVehicles.Count > 0) { for (int j = 0; j < launcherVehicles.Count; ++j) { bool wasSelected = selectedLauncherVehicle == launcherVehicles[j]; if (launcherVehicleCount[j] == 0) { if (wasSelected) { selectedLauncherVehicle = ""; } continue; } if (GUILayout.Toggle(wasSelected, launcherVehicles[j] + " x" + launcherVehicleCount[j].ToString(), "button", GUILayout.Height(15f))) { selectedLauncherVehicle = launcherVehicles[j]; } else { if (wasSelected) { selectedLauncherVehicle = ""; } } } } else { selectedLauncherVehicle = ""; } } if (selectedVehicle.airstripCtrl != null && selectedVehicle.airstripCtrl.airStrips.Count > 0 && (selectedVehicle.airstripCtrl.vehicleCounts.Any((int v) => v > 0) || selectedVehicle.airstripCtrl.airStrips.Any((Airstrip airStrip) => airStrip.vehicleAttached != null && (airStrip.vehicleIsDeploying || airStrip.vehicleIsLaunching)) ) ) { GUILayout.Label("Flight Deck:"); for (int n = 0; n < selectedVehicle.airstripCtrl.vehicles.Count; ++n) { if (selectedVehicle.airstripCtrl.vehicleCounts[n] == 0) { continue; } bool launch = GUILayout.Button(selectedVehicle.airstripCtrl.vehicles[n] + " x" + selectedVehicle.airstripCtrl.vehicleCounts[n].ToString(), "button", GUILayout.Height(15f)); if (launch) { Airstrip airStrip; selectedVehicle.airstripCtrl.PrepareForTakeOff(selectedVehicle.airstripCtrl.vehicles[n], out airStrip); } } for (int n = 0; n < selectedVehicle.airstripCtrl.airStrips.Count; ++n) { Airstrip a = selectedVehicle.airstripCtrl.airStrips[n]; if (a.vehicleAttached == null) { continue; } string stripState = ""; if (a.vehicleIsDeploying && a.vehicleIsUndeploying == false) { stripState = "Preparing"; } else if (a.vehicleIsDeploying && a.vehicleIsUndeploying) { stripState = "Canceling"; } else if (a.vehicleIsLaunching) { stripState = "Launching"; } else { stripState = "Landing"; } if (a.vehicleIsDeploying && a.vehicleProgress == 100f) { if (Vehicle.sVehicleIsDeployOnly.ContainsKey(a.vehicleAttached.typeName) && Vehicle.sVehicleIsDeployOnly[a.vehicleAttached.typeName] == true) { bool retract = GUILayout.Button("Retract " + a.vehicleAttached.typeName, "button", GUILayout.Height(15f)); if (retract) { selectedVehicle.airstripCtrl.CancelTakeOff(a); } } else { GUILayout.BeginHorizontal(); { bool launch = GUILayout.Button(a.vehicleAttached.typeName + " (Ready to Launch)", "button", GUILayout.Height(15f)); if (launch) { selectedVehicle.airstripCtrl.TakeOff(a); } bool cancelLaunch = GUILayout.Button("Cancel", "button", GUILayout.Height(15f), GUILayout.Width(70f)); if (cancelLaunch) { selectedVehicle.airstripCtrl.CancelTakeOff(a); } } GUILayout.EndHorizontal(); } } else { GUILayout.Label(a.vehicleAttached.typeName + " (" + stripState + "...)", "button", GUILayout.Height(15f)); } } } if (selectedVehicle.takeOffFrom != null && selectedVehicle.enabled && selectedVehicle is Aircraft) { bool rtb = GUILayout.Toggle((selectedVehicle as Aircraft).isRTB, "Return to Base", "button", GUILayout.Height(15f)); if (rtb && (selectedVehicle as Aircraft).isRTB == false) { selectedVehicle.ReturnToBase(); } else if (rtb == false) { if ((selectedVehicle as Aircraft).isRTB == true) { bool landSiteFound = false; foreach (Vehicle v in SceneManager.instance.vehicles) { if (v.airstripCtrl != null) { foreach (Airstrip a in v.airstripCtrl.airStrips) { if (a.vehicleAttached == selectedVehicle) { a.vehicleAttached = null; a.vehicleIsLanding = a.vehicleIsUndeploying = false; landSiteFound = true; break; } } } if (landSiteFound) { break; } } (selectedVehicle as Aircraft).isRTB = false; (selectedVehicle as Aircraft).isAligned = false; } } } if (selectedVehicle.sensorCtrl != null && selectedVehicle.sensorCtrl.sensors.Count > 0) { GUILayout.Label("Sensor:"); foreach (Sensor sensor in selectedVehicle.sensorCtrl.sensors) { bool toggle = GUILayout.Toggle(sensor.isToggled && sensor.enabled, sensor.sensorName + (sensor.enabled ? "" : " (Damaged)"), "button", GUILayout.Height(15f)); if (sensor.isToggleable && sensor.enabled) { selectedVehicle.sensorCtrl.Toggle(sensor.sensorName, toggle); } } } GUILayout.Label("Tactics:"); selectedVehicle.autoDealWithAirThreats = GUILayout.Toggle(selectedVehicle.autoDealWithAirThreats, "Auto Deal With Air Threats"); selectedVehicle.autoDealWithSubThreats = GUILayout.Toggle(selectedVehicle.autoDealWithSubThreats, "Auto Deal With Sub Threats"); selectedVehicle.autoEngageAirTracks = GUILayout.Toggle(selectedVehicle.autoEngageAirTracks, "Auto Engage Air Tracks"); selectedVehicle.autoEngageSurfTracks = GUILayout.Toggle(selectedVehicle.autoEngageSurfTracks, "Auto Engage Surf Tracks"); selectedVehicle.autoEngageSubTracks = GUILayout.Toggle(selectedVehicle.autoEngageSubTracks, "Auto Engage Sub Tracks"); if (selectedVehicle.GetVehicleInfo() != null) { foreach (string line in selectedVehicle.GetVehicleInfo()) { GUILayout.Label(line); } } if (selectedVehicle.sensorCtrl != null && selectedVehicle.sensorCtrl.sensors.Count > 0) { GUILayout.Label("Tracks:"); foreach (Track track in selectedVehicle.sensorCtrl.tracksDetected) { GUILayout.Label(track.vehicleTypeName + "(" + track.age.ToString("F0") + "): " + track.identification.ToString() + ", " + Vector3.Distance(track.predictedPosition, selectedVehicle.position).ToString("F0")); } } } } GUILayout.EndVertical(); GUILayout.EndArea(); GUILayout.BeginArea(new Rect(Screen.width / 2f - 100f, Screen.height - 50f, 200f, 40f)); GUILayout.BeginVertical(); { GUILayout.BeginHorizontal(); { if (GUILayout.RepeatButton("Zoom-", GUILayout.Height(30f))) { vehicleCamera.GetComponent <MouseOrbit>().distance += 20f; } if (GUILayout.RepeatButton("Zoom+", GUILayout.Height(30f))) { vehicleCamera.GetComponent <MouseOrbit>().distance -= 20f; } vehicleCamera.GetComponent <MouseOrbit>().useTailMode = GUILayout.Toggle(vehicleCamera.GetComponent <MouseOrbit>().useTailMode, "Tail", "button", GUILayout.Height(30f)); } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); GUILayout.EndArea(); } }
private IEnumerator TakeOffVehicleTactic(Track track) { Vehicle interceptor = null; Airstrip interceptorTookOffFrom = null; while (track.target != null && track.isLost == false) { bool isThreat = (Vehicle.sVehicleCanEngage[track.vehicleTypeName][(int)Vehicle.VehicleType.Surf] == true || Vehicle.sVehicleCanEngage[track.vehicleTypeName][(int)Vehicle.VehicleType.Sub] == true); if ((isThreat && Vehicle.sVehicleTypes[track.vehicleTypeName] == VehicleType.Air && autoDealWithAirThreats == false) || (isThreat && Vehicle.sVehicleTypes[track.vehicleTypeName] == VehicleType.Sub && autoDealWithSubThreats == false) || (isThreat == false && Vehicle.sVehicleTypes[track.vehicleTypeName] == VehicleType.Air && autoEngageAirTracks == false) || (isThreat == false && Vehicle.sVehicleTypes[track.vehicleTypeName] == VehicleType.Surf && autoEngageSurfTracks == false) || (isThreat == false && Vehicle.sVehicleTypes[track.vehicleTypeName] == VehicleType.Sub && autoEngageSubTracks == false)) { yield return(new WaitForSeconds(1.0f)); continue; } if (UnityEngine.Random.Range(0f, 100f) < 50f) { if (interceptorTookOffFrom != null && interceptorTookOffFrom.vehicleAttached == interceptor) { // We've got the interceptor on the deck awaiting take-off. interceptorTookOffFrom.TakeOff(); if (interceptorTookOffFrom.vehicleIsLaunching) { interceptorTookOffFrom = null; } } } if (UnityEngine.Random.Range(0f, 100f) < 40f) { if (interceptor == null || interceptor.isDead || (interceptor is Aircraft && (interceptor as Aircraft).isRTB)) { string chosenInterceptor = airstripCtrl.FindBestVehicleFor(track); if (chosenInterceptor != "") { Airstrip airStrip; if (airstripCtrl.PrepareForTakeOff(chosenInterceptor, out airStrip)) { interceptor = airStrip.vehicleAttached; interceptorTookOffFrom = airStrip; yield return(new WaitForSeconds(UnityEngine.Random.Range(0.4f, 0.5f))); } } else { yield return(new WaitForSeconds(5f)); } } } yield return(new WaitForSeconds(1f)); } // The track is dead/lost. We should recover our interceptor back to the hangar if it has not taken-off yet. if (interceptor != null && interceptorTookOffFrom != null) { while (true) { if (interceptorTookOffFrom.vehicleIsDeploying && interceptorTookOffFrom.vehicleIsUndeploying == false && interceptorTookOffFrom.vehicleProgress == 100f) { interceptorTookOffFrom.CancelTakeOff(); break; } yield return(new WaitForSeconds(1f)); } } }
public void TakeOff(Airstrip airStrip) { airStrip.TakeOff(); }