123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553 |
- var RadarTool = {
-
- ##############################################################################################
- # This function will explore the proprty tree and create new contact in the raw_selection.
- ##############################################################################################
-
- get_elevation : func(lat,lon){
- #first looking if the tile is loaded
- me.local_ground_alt = geo.elevation(lat, lon);
-
- #if geo is nil, the tile is not loaded. There is no fucking way to get the ground elevation (except what I'm about to do)
- if(me.local_ground_alt == nil){
- #finding the closest navaid and take its altitude
- me.navaid_vector = findNavaidsWithinRange(lat,lon,100);
- me.local_ground_alt = me.navaid_vector[0].elevation;
- }
- return me.local_ground_alt;
- },
-
-
- scan_update_tgt_list_func:func(){
- if(scan_update_tgt_list){
- me.temp_raw_list = me.Mp.getChildren();
- foreach(var c ; me.temp_raw_list)
- {
- # FIXME: At that time a multiplayer node may have been deleted while still
- # existing as a displayable target in the radar targets nodes.
- # FIXED, with janitor. 5H1N0B1
- var type = me.type_selector(c);
- if(c.getNode("valid") == nil or c.getNode("valid").getValue() != 1)
- {
- continue;
- }
-
- # the 2 following line are needed : If not, it would detects our own missiles...
- # this will come soon
- # var HaveRadarNode = c.getNode("radar");
- #print(me.check_selected_type(c));
- #if(type == "multiplayer"
- # or (type == "tanker" and HaveRadarNode != nil)
- # or (type == "aircraft" and me.showAI == 1)
- # or type == "carrier"
- # or type == "ship"
- # or (type == "missile" and HaveRadarNode != nil))
- #
- var Tree_Name = c.getName();
- #print("folderName:" ~ c.getName());
- #print("type:" ~ type);
-
- if(me.check_selected_type(c))
- {
- # creation of the tempo object Target
- var u = Target.new(c,me.myTree.getPath());
-
- folderName = c.getName();
- #print("test : " ~ c.pathNode.getValue());
- #print("folderName:" ~ folderName);
- # important Shinobi:
- # expand this so multiplayer that is on sea or ground is also set correct.
- # also consider if doppler do not see them that they are either SURFACE or MARINE, depending on if they have alt = ~ 0
- # notice that GROUND_TARGET is set inside Target.new().
- u.setType(armament.AIR);
-
- #print("Update Type of " ~ u.get_Callsign());
- #printf("Elevation of the tile :%f00" , me.get_elevation(u.get_Latitude(), u.get_Longitude()));
- #print("Target Altitude:" ~u.get_altitude()*FT2M);
-
- #var ground_alt = geo.elevation(u.get_Latitude(), u.get_Longitude());
- me.type_ground_alt = me.get_elevation(u.get_Latitude(), u.get_Longitude());#= ground_alt==nil?0:ground_alt;
-
- # We are testing if it is near the ground
- if(me.type_ground_alt!=nil){
- if(abs(me.type_ground_alt - u.get_altitude()*FT2M) < 20 or u.get_altitude()*FT2M < 50) { # in meters
- #print("It is close to the ground");
- me.info = geodinfo(u.get_Latitude(), u.get_Longitude());
- if (me.info != nil and me.info[1] != nil) {
- #print("The ground underneath the aircraft is ", me.info[1].solid == 1 ? "solid." : "water.");
- #debug.dump(me.info);
- if(me.info[1].solid == 1){
- #print("SURFACE");
- u.setType(armament.SURFACE);
- u.skipDoppler = 0;
- }else{
- #print("MARINE");
- u.setType(armament.MARINE);
- u.skipDoppler = 1;
- }
- #if we can't get the geoinfo it is because the terrain didn't load. So doing a default altitude check to choose
- }elsif(u.get_altitude()*FT2M < 50){
- #print("MARINE");
- u.setType(armament.MARINE);
- u.skipDoppler = 1;
- }else{
- #print("SURFACE");
- u.setType(armament.SURFACE);
- u.skipDoppler = 0;
- }
- }
- }else{
- print("Tiles not loaded for target load moar" ~ u.get_Callsign() ~ " at " ~ u.get_range() ~"nm");
- }
-
-
- if(u.get_type() == armament.AIR){
- # now we test the model name to guess what type it is:
- me.pathNode = c.getNode("sim/model/path");
- if (me.pathNode != nil) {
- me.path = me.pathNode.getValue();
- me.model = split(".", split("/", me.path)[-1])[0];
- u.set_model(me.model);#used for RCS
- }
- u.skipDoppler = 0;
- }
-
- #Testing if ORDNANCE
- if (c.getNode("missile") != nil and c.getNode("missile").getValue()) {
- u.setType(armament.ORDNANCE);
- u.skipDoppler = 0;
- # print("missile:"~ folderName ~":"~ "armament.ORDNANCE");
- }
- if (c.getNode("munition") != nil and c.getNode("munition").getValue()) {
- u.setType(armament.ORDNANCE);
- # u.skipDoppler = 0;
- # print("munition:" ~ folderName ~":"~ "armament.ORDNANCE");
- }
- #Testing Ground Target
- if(u.get_Callsign() == "GROUND_TARGET"){
- u.setType(armament.SURFACE);
- }
- #print(folderName ~ " type:" ~ u.get_type()~ " Skipping Doppler: " ~ u.skipDoppler);
- # if(Tree_Name != "munition"){
- # print("Test Important:");
- me.update_array(u,me.raw_selection);
- me.update_array(u,completeList);
- # }
- }
- }
- }
-
- scan_update_tgt_list = 0;
- },
-
-
- ##############################################################################################
- # Checking if behind terrain or Not
- ##############################################################################################
-
- isNotBehindTerrain: func(SelectedObject){
- if(SelectedObject.get_Callsign()=="GROUND_TARGET"){return 1;}
- isVisible = 0;
-
- # As the script is relatively ressource consuming, then, we do a maximum of test before doing it
- # if(me.get_check())
- # {
- SelectCoord = SelectedObject.get_Coord();
-
- SelectCoord.set_alt(SelectCoord.alt()+1);
- # Because there is no terrain on earth that can be between these 2
- if(me.our_alt < 8900 and SelectCoord.alt() < 8900)
- {
- if (pickingMethod == 1) {
- var myPos = geo.aircraft_position();
- var xyz = {"x":myPos.x(), "y":myPos.y(), "z":myPos.z()};
- var dir = {"x":SelectCoord.x()-myPos.x(), "y":SelectCoord.y()-myPos.y(), "z":SelectCoord.z()-myPos.z()};
- # Check for terrain between own aircraft and other:
- v = get_cart_ground_intersection(xyz, dir);
- if (v == nil) {
- return 1;
- #printf("No terrain, planes has clear view of each other");
- } else {
- var terrain = geo.Coord.new();
- terrain.set_latlon(v.lat, v.lon, v.elevation);
- var maxDist = myPos.direct_distance_to(SelectCoord);
- var terrainDist = myPos.direct_distance_to(terrain);
- if (terrainDist < maxDist-1) {
- #print("terrain found between the planes");
- return 0;
- } else {
- #print("The planes has clear view of each other");
- return 1;
- }
- }
- } else {
-
-
- # Temporary variable
- # A (our plane) coord in meters
- a = me.MyCoord.x();
- b = me.MyCoord.y();
- c = me.MyCoord.z();
- # B (target) coord in meters
- d = SelectCoord.x();
- e = SelectCoord.y();
- f = SelectCoord.z();
- x = 0;
- y = 0;
- z = 0;
- RecalculatedL = 0;
- difa = d - a;
- difb = e - b;
- difc = f - c;
- # direct Distance in meters
- myDistance = SelectCoord.direct_distance_to(me.MyCoord);
- Aprime = geo.Coord.new();
-
- # Here is to limit FPS drop on very long distance
- L = 500;
- if(myDistance > 50000)
- {
- L = myDistance / 15;
- }
- step = L;
- maxLoops = int(myDistance / L);
-
- isVisible = 1;
- # This loop will make travel a point between us and the target and check if there is terrain
- for(var i = 0 ; i < maxLoops ; i += 1)
- {
- L = i * step;
- K = (L * L) / (1 + (-1 / difa) * (-1 / difa) * (difb * difb + difc * difc));
- DELTA = (-2 * a) * (-2 * a) - 4 * (a * a - K);
-
- if(DELTA >= 0)
- {
- # So 2 solutions or 0 (1 if DELTA = 0 but that 's just 2 solution in 1)
- x1 = (-(-2 * a) + math.sqrt(DELTA)) / 2;
- x2 = (-(-2 * a) - math.sqrt(DELTA)) / 2;
- # So 2 y points here
- y1 = b + (x1 - a) * (difb) / (difa);
- y2 = b + (x2 - a) * (difb) / (difa);
- # So 2 z points here
- z1 = c + (x1 - a) * (difc) / (difa);
- z2 = c + (x2 - a) * (difc) / (difa);
- # Creation Of 2 points
- Aprime1 = geo.Coord.new();
- Aprime1.set_xyz(x1, y1, z1);
-
- Aprime2 = geo.Coord.new();
- Aprime2.set_xyz(x2, y2, z2);
-
- # Here is where we choose the good
- if(math.round((myDistance - L), 2) == math.round(Aprime1.direct_distance_to(SelectCoord), 2))
- {
- Aprime.set_xyz(x1, y1, z1);
- }
- else
- {
- Aprime.set_xyz(x2, y2, z2);
- }
- AprimeLat = Aprime.lat();
- Aprimelon = Aprime.lon();
- AprimeTerrainAlt = geo.elevation(AprimeLat, Aprimelon);
- if(AprimeTerrainAlt == nil)
- {
- AprimeTerrainAlt = 0;
- }
-
- if(AprimeTerrainAlt > Aprime.alt())
- {
- isVisible = 0;
- }
- }
- }
- }
- }
- else
- {
- isVisible = 1;
- }
- # }
- return isVisible;
- },
- ##############################################################################################
- # Checking if the target is beyond horizon
- ##############################################################################################
- NotBeyondHorizon: func(SelectedObject){
- me.MyCoord = geo.aircraft_position();
- me.our_alt = me.MyCoord.alt();
-
-
- if(SelectedObject.get_Callsign()=="GROUND_TARGET"){return 1;}
- # if distance is beyond the earth curve
- var horizon = SelectedObject.get_horizon(me.our_alt);
- var u_rng = me.targetRange(SelectedObject);
- #print("u_rng : " ~ u_rng ~ ", Horizon : " ~ horizon);
- var InHorizon = (u_rng < horizon);
- return InHorizon;
- },
- doppler: func(SelectedObject){
-
- #if it is a radiating stuff, skip doppler
- #print("In the doppler");
- if(pylons.fcs.getSelectedWeapon() != nil){
- #print("pylons.fcs.getSelectedWeapon() != nil");
- if(pylons.fcs.getSelectedWeapon().type != "30mm Cannon"){
- #print("pylons.fcs.getSelectedWeapon().guidance:" ~pylons.fcs.getSelectedWeapon().guidance);
- if(pylons.fcs.getSelectedWeapon().guidance =="radiation"){
- #print( "Using anti radiation missile. Is target radiating :" ~ SelectedObject.isRadiating(me.MyCoord));
- if(SelectedObject.isRadiating(me.MyCoord)){
- return 1;
- }
- }
- }
- }
-
- # Test to check if the target can hide bellow us
- # Or Hide using anti doppler movements
-
- var InDoppler = 0;
- var groundNotbehind = me.isGroundNotBehind(SelectedObject);
- if(groundNotbehind)
- {
- InDoppler = 1;
- }
- if(me.HaveDoppler and (abs(SelectedObject.get_closure_rate_from_Coord(me.MyCoord)) > me.DopplerSpeedLimit))
- {
- InDoppler = 1;
- }
- if(SelectedObject.get_Callsign() == "GROUND_TARGET" or SelectedObject.check_carrier_type())
- {
- InDoppler = 1;
- }
- return InDoppler;
- },
- ##############################################################################################
- # Checking if ground isn't behind : this is done for non doppler radar that should be blind
- # or also a way to blind a doppler radar
- ##############################################################################################
-
- isGroundNotBehind: func(SelectedObject){
-
- var myPitch = SelectedObject.get_Elevation_from_Coord(me.MyCoord);
- var GroundNotBehind = 1; # sky is behind the target (this don't work on a valley)
- if(myPitch < 0 and me.NotBeyondHorizon(SelectedObject))
- {
- # the aircraft is bellow us, the ground could be bellow
- # Based on earth curve. Do not work with mountains
- # The script will calculate what is the ground distance for the line (us-target) to reach the ground,
- # If the earth was flat. Then the script will compare this distance to the horizon distance
- # If our distance is greater than horizon, then sky behind
- # If not, we cannot see the target unless we have a doppler radar
- var distHorizon = me.MyCoord.alt() / math.tan(abs(myPitch * D2R)) * M2NM;
- var horizon = SelectedObject.get_horizon( me.our_alt);
- var TempBool = (distHorizon > horizon);
- GroundNotBehind = (distHorizon > horizon);
- }
- return GroundNotBehind;
- },
- ##############################################################################################
- # Checking azimuth
- ##############################################################################################
- inAzimuth: func(SelectedObject,ExceptGroundTarget = 1){
-
- if(SelectedObject.get_Callsign()=="GROUND_TARGET" and ExceptGroundTarget){return 1;}
- # Check if it's in Azimuth.
- # first we check our heading+ center az deviation + the sweep if the radar is mechanical
- tempAz = me.az_fld;
- var inMyAzimuth = 0;
-
- var myHeading = math.mod(me.fieldazCenter + me.OurHdg, 360);
- if(me.haveSweep)
- {
- myHeading = math.mod(myHeading + me.SwpMarker * (0.0844 / me.swp_diplay_width) * tempAz / 4, 360);
- mydeviation = SelectedObject.get_deviation(myHeading, me.MyCoord);
- #print("Heading:"~ myHeading ~" My deviation:"~ mydeviation);
- inMyAzimuth = (abs(mydeviation) < (tempAz / 4));
- }
- else
- {
- mydeviation = SelectedObject.get_deviation(myHeading, me.MyCoord);
- inMyAzimuth = (abs(mydeviation)<(tempAz/2));
- }
- return inMyAzimuth;
- },
-
- ##############################################################################################
- # Don't know what this. With canvas this should be deleted
- ##############################################################################################
- #The goal of this function is to make the xml radar screen work. It is useless with Canvas
- calculateScreen: func(SelectedObject){
- # swp_diplay_width = Global
- # az_fld = Global
- # ppi_diplay_radius = Global
-
- SelectedObject.check_carrier_type();
- mydeviation = SelectedObject.get_deviation(me.OurHdg, me.MyCoord);
- #print("My Radar deviation %f", mydeviation);
- var u_rng = me.targetRange(SelectedObject);
-
- # compute mp position in our B-scan like display. (Bearing/horizontal + Range/Vertical).
- SelectedObject.set_relative_bearing(me.swp_diplay_width / me.az_fld * mydeviation,me.UseATree);
- var factor_range_radar = me.rng_diplay_width / me.rangeTab[me.rangeIndex]; # length of the distance range on the B-scan screen.
- SelectedObject.set_ddd_draw_range_nm(factor_range_radar * u_rng,me.UseATree);
- u_fading = 1;
- u_display = 1;
-
- # Compute mp position in our PPI like display.
- factor_range_radar = me.ppi_diplay_radius / me.rangeTab[me.rangeIndex]; # Length of the radius range on the PPI like screen.
- SelectedObject.set_tid_draw_range_nm(factor_range_radar * u_rng,me.UseATree);
-
- # Compute first digit of mp altitude rounded to nearest thousand. (labels).
- SelectedObject.set_rounded_alt(rounding1000(SelectedObject.get_altitude()) / 1000,me.UseATree);
-
- # Compute closure rate in Kts.
- #SelectedObject.get_closure_rate_from_Coord(me.MyCoord) * MPS2KT;
-
- # Check if u = nearest echo.
- if(SelectedObject.get_Callsign() == getprop("/ai/closest/callsign"))
- {
- #print(u.get_Callsign());
- tmp_nearest_u = SelectedObject;
- tmp_nearest_rng = u_rng;
- }
- SelectedObject.set_display(u_display, me.UseATree);
- SelectedObject.set_fading(u_fading, me.UseATree);
- },
- ##############################################################################################
- # Checking the elevation
- ##############################################################################################
- inElevation: func(SelectedObject){
- if(SelectedObject.get_Callsign()=="GROUND_TARGET"){return 1;}
- # Moving the center of this field will be ne next option
- var tempAz = me.vt_az_fld;
- var myElevation = SelectedObject.get_total_elevation_from_Coord(me.OurPitch, me.MyCoord);
- var IsInElevation = (abs(myElevation) < (tempAz / 2));
- return IsInElevation;
- },
- ##############################################################################################
- # Checking the Range
- ##############################################################################################
- InRange: func(SelectedObject){
- if(SelectedObject.get_Callsign()=="GROUND_TARGET"){return 1;}
- # Check if it's in range
- IsInRange = 0;
- var myRange = me.targetRange(SelectedObject);
- if(myRange != 0)
- {
- #print(SelectedObject.get_Callsign() ~": Range (NM) : " ~myRange);
- IsInRange = ( myRange <= me.rangeTab[me.rangeIndex]);
- }
- return IsInRange;
- },
-
- ##############################################################################################
- # Checking the heat (n1 rotation) need improvement (like heat attenuation)
- ##############################################################################################
- heat_sensor: func(SelectedObject){
- myEngineTree = SelectedObject.get_engineTree();
- # If MP or AI has an engine tree, we will check for each engine n1>30 or rpm>1000
- if(myEngineTree != nil)
- {
- var engineList = myEngineTree.getChildren();
- foreach(var currentEngine ; engineList)
- {
- var HaveN1node = currentEngine.getNode("n1");
- var HaveRPMnode = currentEngine.getNode("rpm");
- if(HaveN1node != nil)
- {
- n1value = HaveN1node.getValue();
- if(n1value != nil and n1value > 30)
- {
- #print("N1 detected");
- return 1;
- }
- }
- if(HaveRPMnode != nil)
- {
- RpMvalue = HaveRPMnode.getValue();
- if(RpMvalue != nil and RpMvalue > 1000)
- {
- #print("RPM detected");
- return 1;
- }
- }
- }
- }
- # Here we could add a velocity test : if speed >mach 1, we can imagine that friction provides heat
- },
-
- ##############################################################################################
- #Detection of the link16 : Should allow us to see it as a friend and avoiding shooting it
- ##############################################################################################
- IsFriendlink16: func(SelectedObject){
- cs = SelectedObject.get_Callsign();
- rn = SelectedObject.get_range();
- if (getprop("link16/wingman-1")==cs or getprop("link16/wingman-2")==cs or getprop("link16/wingman-3")==cs or getprop("link16/wingman-4")==cs or getprop("link16/wingman-5")==cs or getprop("link16/wingman-6")==cs or getprop("link16/wingman-7")==cs or getprop("link16/wingman-8")==cs or getprop("link16/wingman-9")==cs or rn > 150) {
- return 1;
- }else{
- return 0;
- }
- },
-
- ##############################################################################################
- #Transponder detection : if transponder still on, the target will be easy to detect
- ##############################################################################################
- HasTransponderOn: func(SelectedObject){
- trAct = SelectedObject.propNode.getNode("instrumentation/transponder/transmitted-id");
- rn = SelectedObject.get_range();
-
- if(SelectedObject.propNode.getName() != "multiplayer" and rn < 55) {
- return 1;#non MP always has transponder on.
- } elsif (trAct != nil and trAct.getValue() != -9999 and rn < 55) {
- return 1; # transponder on
- }else{
- return 0;
- }
- },
-
- targetRange: func(SelectedObject){
- me.MyCoord = geo.aircraft_position();
- # This is a way to shortcurt the issue that some of node have : in-range =0
- # So by giving the second fucntion our coord, we just have to calculate it
- var myRange = 0;
- # myRange = SelectedObject.get_range();
- # if(myRange == 0)
- # {
- myRange = SelectedObject.get_range_from_Coord(me.MyCoord);
- #print("Pouet");
- # }
- #print("targetRange : " ~ SelectedObject.get_Callsign() ~" longitude : " ~ SelectedObject.get_Longitude() ~ " latitude : " ~ SelectedObject.get_Latitude() ~" result="~myRange);
- return myRange;
- },
-
- targetBearing: func(SelectedObject){
- # This is a way to shortcurt the issue that some of node have : bearing =0
- # So by giving the second fucntion our coord, we just have to calculate it
- var myBearing = 0;
- myBearing = SelectedObject.get_bearing();
- if(myBearing == 0)
- {
- myBearing = SelectedObject.get_bearing_from_Coord(me.MyCoord);
- }
- return myBearing;
- },
- TargetWhichRadarAzimut: func(SelectedObject){
- if(SelectedObject.type == armament.SURFACE or SelectedObject.type == armament.MARINE) {
- return 180;
- }else{
- return 60;
- }
- }
- }
|