target_class.nas 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  1. ################################################################
  2. ##################### Target class ##########################
  3. ################################################################
  4. setprop("sim/mul"~"tiplay/gen"~"eric/strin"~"g[14]", "o"~"r"~"f");
  5. var Target = {
  6. new: func(c,theTree = nil){
  7. var obj = { parents : [Target,geo.Coord.new()]};
  8. obj.propNode = c;
  9. obj.RdrProp = c.getNode("radar");
  10. obj.Heading = c.getNode("orientation/true-heading-deg");
  11. obj.Alt = c.getNode("position/altitude-ft");
  12. obj.ubody = c.getNode("velocities/uBody-fps");
  13. obj.vbody = c.getNode("velocities/vBody-fps");
  14. obj.wbody = c.getNode("velocities/wBody-fps");
  15. obj.lat = c.getNode("position/latitude-deg");
  16. obj.lon = c.getNode("position/longitude-deg");
  17. #As it is a geo.Coord object, we have to update lat/lon/alt ->and alt is in meters
  18. #print("obj.lat:"~obj.lat~" obj.lon:"~" obj.Alt * FT2M:"~obj.Alt * FT2M);
  19. obj.set_latlon(obj.lat.getValue(), obj.lon.getValue(), obj.Alt.getValue() * FT2M);
  20. obj.pitch = c.getNode("orientation/pitch-deg");
  21. obj.roll = c.getNode("orientation/roll-deg");
  22. obj.Speed = c.getNode("velocities/true-airspeed-kt");
  23. obj.VSpeed = c.getNode("velocities/vertical-speed-fps");
  24. obj.Callsign = c.getNode("callsign");
  25. obj.name = c.getNode("name");
  26. obj.Valid = c.getNode("valid");
  27. obj.validTree = 0;
  28. obj.TransponderID = c.getNode("instrumentation/transponder/transmitted-id");
  29. obj.engineTree = c.getNode("engines");
  30. obj.AcType = c.getNode("sim/model/ac-type");
  31. obj.typeString = c.getName();
  32. obj.fname = c.getName();
  33. obj.index = c.getIndex();
  34. #print(obj.fname);
  35. obj.flareNode = c.getNode("rotors/main/blade[3]/flap-deg");
  36. obj.chaffNode = c.getNode("rotors/main/blade[3]/position-deg");
  37. #Variable that can/or not being written onthe tree
  38. obj.InRange = 0 ;
  39. #Change here the object type to set the radar2 path
  40. #This have to be in a separate function
  41. #Overwrite selectedType if missile
  42. var TestIfMissileNode = c.getNode("missile");
  43. if(TestIfMissileNode != nil) {
  44. if(TestIfMissileNode.getValue()){
  45. #print("It is a missile");
  46. obj.typeString = "missile";
  47. missileIndex = missileIndex + 1;
  48. obj.index = missileIndex;
  49. }
  50. }
  51. obj.Model = c.getNode("model-short");
  52. var model_short = c.getNode("sim/model/path");
  53. if(model_short != nil)
  54. {
  55. var model_short_val = model_short.getValue();
  56. if (model_short_val != nil and model_short_val != "")
  57. {
  58. var u = split("/", model_short_val); # give array
  59. var s = size(u); # how many elements in array
  60. var o = u[s-1]; # the last element
  61. var m = size(o); # how long is this string in the last element
  62. var e = m - 4; # - 4 chars .xml
  63. obj.ModelType = substr(o, 0, e); # the string without .xml
  64. }
  65. else
  66. obj.ModelType = "";
  67. } elsif (c.getNode("type") != nil) {
  68. # not all have a path property
  69. obj.ModelType = c.getNode("type").getValue();
  70. if (obj.ModelType == nil) {
  71. # not all have a type property
  72. obj.ModelType = "";
  73. }
  74. } else {
  75. obj.ModelType = "";
  76. }
  77. # let us make callsign a static variable:
  78. if (obj.Callsign == nil or obj.Callsign.getValue() == "")
  79. {
  80. #print("----------------------------------- FIRST CONTACT ---------------- " ~ obj.name.getValue());
  81. if (obj.name == nil or obj.name.getValue() == "") {
  82. obj.myStaticCallsign = obj.ModelType;# last resort.
  83. } else {
  84. obj.myStaticCallsign = obj.name.getValue();# for AI ships.
  85. }
  86. } else {
  87. obj.myStaticCallsign = obj.Callsign.getValue();
  88. }
  89. #print("----------------------------------- AFTER CONTACT ---------------- " ~ obj.myStaticCallsign);
  90. obj.life = 5; #Have to be given in parameters, but now written in hard
  91. obj.objectDeviationDeg = 0;
  92. obj.objectElevationDeg = 0;
  93. obj.objectDisplay = 0;
  94. obj.string = "ai/models/" ~ obj.typeString ~ "[" ~ obj.index ~ "]";
  95. obj.shortstring = obj.typeString ~ "[" ~ obj.index ~ "]";
  96. # var TestID = c.getNode("unicId",1);
  97. # # if(TestID.getValue() != nil) {
  98. # obj.ID = TestID.getValue();
  99. # #print("Id already exist:" ~ obj.ID);
  100. # }else{
  101. # #print(int(10000000 * getprop("sim/time/elapsed-sec")* rand()));
  102. # obj.ID = int(10000000 * getprop("sim/time/elapsed-sec")*rand());
  103. # TestID.setValue(obj.ID);
  104. # #print("Id Creation" ~ obj.ID);
  105. # }
  106. if(theTree == nil)
  107. {
  108. obj.InstrString = "instrumentation/radar2/targets";
  109. }
  110. else
  111. {
  112. obj.InstrString = theTree;
  113. }
  114. #print("obj.InstrString:" ~obj.InstrString);
  115. #================== This create the tree ===========================
  116. #on the long term, tree have to disapear
  117. obj.InstrTgts = props.globals.getNode(obj.InstrString, 1);
  118. obj.TgtsFiles = 0; #obj.InstrTgts.getNode(obj.shortstring, 1);
  119. obj.Range = obj.RdrProp.getNode("range-nm");
  120. obj.Bearing = obj.RdrProp.getNode("bearing-deg");
  121. obj.Elevation = obj.RdrProp.getNode("elevation-deg");
  122. obj.InRangeProperty = obj.RdrProp.getNode("in-range",1);
  123. obj.MyCallsign = 0;
  124. obj.BBearing = 0;
  125. obj.BHeading = 0;
  126. obj.RangeScore = 0;
  127. obj.RelBearing = 0;
  128. obj.Carrier = 0;
  129. obj.EcmSignal = 0;
  130. obj.EcmSignalNorm = 0;
  131. obj.EcmTypeNum = 0;
  132. obj.Display = 0;
  133. obj.Fading = 0;
  134. obj.DddDrawRangeNm = 0;
  135. obj.TidDrawRangeNm = 0;
  136. obj.RoundedAlt = 0;
  137. obj.TimeLast = 0;
  138. obj.lifetime = 3; #Not implemented yet : should represent the life time in sec of a target. (simpler than actually)
  139. obj.RangeLast = 0;
  140. obj.ClosureRate = 0;
  141. obj.Display_Node = nil;
  142. obj.skipDoppler = 1;
  143. obj.ispainted = 0;
  144. #obj.TimeLast.setValue(ElapsedSec.getValue());
  145. obj.RadarStandby = c.getNode("sim/multiplay/generic/int[2]");
  146. obj.deviation = nil;
  147. obj.elevation = nil;
  148. obj.virtual = 0;
  149. obj.iff = -1000;
  150. obj.unique = obj.Callsign.getValue()~c.getPath();# should be very unique, callsign might not be enough. Path by itself is not enough either, as paths gets reused.
  151. obj.tacobj = {parents: [tacview.tacobj]};
  152. obj.tacobj.tacviewID = left(md5(obj.unique),5);
  153. obj.tacobj.valid = 1;
  154. obj.type = armament.AIR;
  155. obj.model = obj.ModelType; #was "" : now it is model type, until something set it up
  156. return obj;
  157. },
  158. update:func(c){
  159. me.RdrProp = c.RdrProp;
  160. me.Heading = c.Heading;
  161. me.Alt = c.Alt;
  162. me.lat = c.lat;
  163. me.lon = c.lon;
  164. me.set_latlon(me.lat.getValue(), me.lon.getValue(), me.Alt.getValue() * FT2M);
  165. me.pitch = c.pitch;
  166. me.roll = c.roll;
  167. me.Speed = c.Speed;
  168. me.VSpeed = c.VSpeed;
  169. me.Callsign = c.Callsign;
  170. me.name = c.name;
  171. me.Valid = c.Valid;
  172. me.validTree = c.validTree;
  173. me.TransponderID = c.TransponderID;
  174. me.engineTree = c.engineTree;
  175. me.AcType = c.AcType;
  176. me.index = c.index;
  177. me.flareNode = c.flareNode;
  178. me.chaffNode = c.chaffNode;
  179. me.RadarStandby = c.RadarStandby;
  180. me.InstrTgts = props.globals.getNode(me.InstrString, 1);
  181. me.TgtsFiles = 0; #me.InstrTgts.getNode(me.shortstring, 1);
  182. me.Range = c.Range;
  183. me.Bearing = c.Bearing;
  184. me.Elevation = c.Elevation;
  185. me.InRangeProperty = c.InRangeProperty;
  186. me.MyCallsign = c.MyCallsign;
  187. me.BBearing = c.BBearing;
  188. me.BBearing = c.BBearing;
  189. me.RangeScore = c.RangeScore;
  190. me.RelBearing = c.RelBearing;
  191. me.Carrier = c.Carrier;
  192. me.EcmSignal = c.EcmSignal;
  193. me.EcmSignalNorm = c.EcmSignalNorm;
  194. me.EcmTypeNum = c.EcmTypeNum;
  195. me.Fading = c.Fading;
  196. me.DddDrawRangeNm = c.DddDrawRangeNm;
  197. me.TidDrawRangeNm = c.TidDrawRangeNm;
  198. me.RoundedAlt = c.RoundedAlt;
  199. me.TimeLast = 0;
  200. if(me.life<1){
  201. me.ispainted = c.ispainted;
  202. me.Display = c.Display;
  203. me.type = c.type;
  204. }else{
  205. #if(me.get_Callsign() != ""){print("Update Target :" ~ me.get_Callsign() ~ " Paiting : " ~ me.ispainted ~" and Display : " ~ me.Display);}
  206. }
  207. me.lifetime = 3; # We reinit the lifetime
  208. me.RangeLast = c.RangeLast;
  209. me.ClosureRate = c.ClosureRate;
  210. me.life = 5;
  211. me.objectDeviationDeg = c.objectDeviationDeg;
  212. me.objectElevationDeg = c.objectElevationDeg;
  213. me.objectDisplay = c.objectDisplay;
  214. me.string = c.string;
  215. me.shortstring = c.shortstring;
  216. },
  217. create_tree: func(MyAircraftCoord,MyAircraftHeading = nil) {
  218. me.TgtsFiles = me.InstrTgts.getNode(me.shortstring, 1);
  219. me.MyCallsign = me.TgtsFiles.getNode("callsign", 1);
  220. me.BBearing = me.TgtsFiles.getNode("bearing-deg", 1);
  221. me.BHeading = me.TgtsFiles.getNode("true-heading-deg", 1);
  222. me.RangeScore = me.TgtsFiles.getNode("range-score", 1);
  223. me.RelBearing = me.TgtsFiles.getNode("ddd-relative-bearing", 1);
  224. me.Carrier = me.TgtsFiles.getNode("carrier", 1);
  225. me.EcmSignal = me.TgtsFiles.getNode("ecm-signal", 1);
  226. me.EcmSignalNorm = me.TgtsFiles.getNode("ecm-signal-norm", 1);
  227. me.EcmTypeNum = me.TgtsFiles.getNode("ecm_type_num", 1);
  228. me.Display_Node = me.TgtsFiles.getNode("display", 1);
  229. me.Fading = me.TgtsFiles.getNode("ddd-echo-fading", 1);
  230. me.DddDrawRangeNm = me.TgtsFiles.getNode("ddd-draw-range-nm", 1);
  231. me.TidDrawRangeNm = me.TgtsFiles.getNode("tid-draw-range-nm", 1);
  232. me.RoundedAlt = me.TgtsFiles.getNode("rounded-alt-ft", 1);
  233. me.TimeLast = me.TgtsFiles.getNode("closure-last-time", 1);
  234. me.RangeLast = me.TgtsFiles.getNode("closure-last-range-nm", 1);
  235. me.ClosureRate = me.TgtsFiles.getNode("closure-rate-kts", 1);
  236. me.TimeLast.setDoubleValue(ElapsedSec.getValue());
  237. me.RangeLast.setValue(me.get_range_from_Coord(MyAircraftCoord));
  238. me.Carrier.setBoolValue(0);
  239. #Create essential tree
  240. var altTree =me.TgtsFiles.getNode("position/altitude-ft",1);
  241. var latTree =me.TgtsFiles.getNode("position/latitude-deg",1);
  242. var lonTree =me.TgtsFiles.getNode("position/longitude-deg",1);
  243. me.validTree =me.TgtsFiles.getNode("valid",1);
  244. var radarBearing =me.TgtsFiles.getNode("radar/bearing-deg",1);
  245. var radarRange =me.TgtsFiles.getNode("radar/range-nm",1);
  246. var elevation =me.TgtsFiles.getNode("radar/elevation-deg",1);
  247. var deviation =me.TgtsFiles.getNode("radar/deviation-deg",1);
  248. var velocities =me.TgtsFiles.getNode("velocities/true-airspeed-kt",1);
  249. var transpondeur =me.TgtsFiles.getNode("instrumentation/transponder/transmitted-id",1);
  250. var heading =me.TgtsFiles.getNode("orientation/true-heading-deg",1);
  251. #var myDeviation = me.get_deviation(MyAircraftHeading,MyAircraftCoord);
  252. altTree.setValue(me.Alt.getValue());
  253. latTree.setValue(me.lat.getValue());
  254. lonTree.setValue(me.lon.getValue());
  255. me.validTree.setValue(me.Valid.getValue());
  256. radarBearing.setValue(me.Bearing.getValue());
  257. radarRange.setValue(me.Range.getValue());
  258. elevation.setValue(me.Elevation.getValue());
  259. deviation.setValue(me.objectDeviationDeg);
  260. velocities.setValue(me.Speed.getValue());
  261. if(me.TransponderID != nil)
  262. {
  263. if(me.TransponderID.getValue() != nil)
  264. {
  265. transpondeur.setValue(me.TransponderID.getValue());
  266. }
  267. }
  268. heading.setValue(me.Heading.getValue());
  269. },
  270. set_all: func(myAircraftCoord){
  271. me.RdrProp.getNode("in-range",1).setBoolValue(1);
  272. me.MyCallsign.setValue(me.get_Callsign());
  273. me.BHeading.setValue(me.Heading.getValue());
  274. me.BBearing.setValue(me.get_bearing_from_Coord(myAircraftCoord));
  275. },
  276. remove: func(){
  277. #me.validTree = 0;
  278. if(me.validTree != 0){me.validTree.setValue(0);}
  279. me.InstrTgts.removeChild(me.type, me.index);
  280. },
  281. set_nill: func(){
  282. # Suppression of the HUD display :
  283. # The property is initialised when the target is in range of "instrumentation/radar/range"
  284. # But nothing is done when "It's no more in range"
  285. # So this is a little hack for HUD.
  286. if(me.validTree != 0){me.validTree.setValue(0);}
  287. #me.RdrProp.getNode("in-range").setValue("false");
  288. var Tempo_TgtsFiles = me.InstrTgts.getNode(me.shortstring, 1);
  289. var Property_list = Tempo_TgtsFiles.getChildren();
  290. foreach(var myProperty ; Property_list)
  291. {
  292. #print(myProperty.getName());
  293. if(myProperty.getName() != "closure-last-time")
  294. {
  295. myProperty.setValue("");
  296. }
  297. }
  298. },
  299. getIff: func {
  300. if (getprop("sim/time/elapsed-sec")-me.iff < 3.5) {
  301. return 1;
  302. }
  303. return 0;
  304. },
  305. getCarrierSign: func {
  306. # When there is 2 Eisenhovers this can tell them apart:
  307. var s = me.propNode.getNode("sign");
  308. if (s != nil) {
  309. s = s.getValue();
  310. if (s=="") {
  311. s = nil;
  312. }
  313. if (s != nil) {
  314. var i = me.propNode.getNode("id");
  315. if (i != nil) {
  316. i = i.getValue();
  317. s = s ~ i;
  318. }
  319. }
  320. }
  321. return s;
  322. },
  323. get_Validity: func(){
  324. var n = 0;
  325. if(getprop(me.InstrString ~ "/" ~ me.shortstring ~ "/closure-last-time") != nil)
  326. {
  327. n = 1;
  328. }
  329. return n;
  330. },
  331. get_TimeLast: func(){
  332. var n = 0;
  333. if(getprop(me.InstrString ~ "/" ~ me.shortstring ~ "/closure-last-time") != nil )
  334. {
  335. #print(me.InstrString ~ "/" ~ me.shortstring ~ "/closure-last-time");
  336. #print(getprop(me.InstrString ~ "/" ~ me.shortstring ~ "/closure-last-time"));
  337. n = getprop(me.InstrString ~ "/" ~ me.shortstring ~ "/closure-last-time");
  338. }
  339. return n;
  340. },
  341. get_Coord: func(){
  342. TgTCoord = geo.Coord.new();
  343. TgTCoord.set_latlon(me.lat.getValue(), me.lon.getValue(), me.Alt.getValue() * FT2M);
  344. me.set_latlon(me.lat.getValue(), me.lon.getValue(), me.Alt.getValue() * FT2M);
  345. return TgTCoord;
  346. },
  347. get_Callsign: func(){
  348. #print("TARGET : me.name == " ~ me.name.getValue() ~ " me.myStaticCallsign:" ~ me.myStaticCallsign);
  349. return me.myStaticCallsign;# callsigns are probably not dynamic, so its defined at Target creation.
  350. if (me.Callsign == nil or me.Callsign.getValue() == "") {
  351. #print("TARGET : me.name == " ~ me.name.getValue());
  352. if (me.name == nil or me.name.getValue() == "") {
  353. return me.get_model();
  354. }
  355. return me.name.getValue();# for AI ships.
  356. }
  357. return me.Callsign.getValue();
  358. },
  359. get_Name:func(){
  360. if (me.name == nil or me.name.getValue() == "") {
  361. return me.get_model();
  362. }
  363. return me.name.getValue();# for AI ships.
  364. },
  365. get_Speed: func(){
  366. var n = me.Speed.getValue();
  367. #var alt = me.Alt.getValue();
  368. #n = n / (0.632 ^ (-(alt / 25066))); # Calcul of Air Speed based on ground speed. the function ^ doesn't work !!
  369. return n;
  370. },
  371. get_Longitude: func(){
  372. var n = me.lon.getValue();
  373. return n;
  374. },
  375. get_Latitude: func(){
  376. var n = me.lat.getValue();
  377. return n;
  378. },
  379. get_Pitch: func(){
  380. var n = me.pitch.getValue();
  381. return n;
  382. },
  383. get_Roll: func(){
  384. var n = me.roll.getValue();
  385. return n;
  386. },
  387. get_heading : func(){
  388. var n = me.Heading.getValue();
  389. if(n == nil)
  390. {
  391. n = 0;
  392. }
  393. return n;
  394. },
  395. get_bearing: func(){
  396. var n = 0;
  397. n = me.Bearing.getValue();
  398. if(n == nil)
  399. {
  400. n = 0;
  401. }
  402. return n;
  403. },
  404. get_bearing_from_Coord: func(MyAircraftCoord){
  405. var myCoord = me.get_Coord();
  406. var myBearing = 0;
  407. if(myCoord.is_defined())
  408. {
  409. myBearing = MyAircraftCoord.course_to(myCoord);
  410. me.Bearing.setValue(myBearing);
  411. }
  412. #print("get_bearing_from_Coord :" ~ myBearing);
  413. return myBearing;
  414. },
  415. get_reciprocal_bearing: func(){
  416. return geo.normdeg(me.get_bearing() + 180);
  417. },
  418. get_deviation: func(true_heading_ref, coord){
  419. me.objectDeviationDeg = - deviation_normdeg(true_heading_ref, me.get_bearing_from_Coord(coord));
  420. #print(me.deviation);
  421. return me.objectDeviationDeg;
  422. },
  423. get_altitude: func(){
  424. #Return Alt in feet
  425. return me.Alt.getValue();
  426. },
  427. get_Elevation_from_Coord: func(MyAircraftCoord){
  428. var myCoord = me.get_Coord();
  429. #me.objectElevationDeg = math.asin((myCoord.alt() - MyAircraftCoord.alt()) / myCoord.direct_distance_to(MyAircraftCoord)) * R2D;
  430. me.objectElevationDeg = vector.Math.getPitch(geo.aircraft_position(), me.get_Coord());
  431. me.Elevation.setValue(me.objectElevationDeg);
  432. return me.objectElevationDeg;
  433. },
  434. get_Elevation_from_Coord_HUD:func(){
  435. var myCoord = me.get_Coord();
  436. return vector.Math.getPitch(geo.viewer_position(), me.get_Coord());
  437. },
  438. get_total_elevation_from_Coord: func(own_pitch, MyAircraftCoord){
  439. var myTotalElevation = - deviation_normdeg(own_pitch, me.get_Elevation_from_Coord(MyAircraftCoord));
  440. me.Elevation.setValue(myTotalElevation);
  441. return myTotalElevation;
  442. },
  443. get_total_elevation: func(own_pitch){
  444. me.myTotalElevation = - deviation_normdeg(own_pitch, me.Elevation.getValue());
  445. return me.myTotalElevation;
  446. },
  447. get_range: func(){
  448. #print("me.Range.getValue() :" ~ me.Range.getValue());
  449. return me.Range.getValue();
  450. },
  451. get_range_from_Coord: func(MyAircraftCoord){
  452. var myCoord = me.get_Coord();
  453. var myDistance = 0;
  454. if(myCoord.is_defined())
  455. {
  456. myDistance = MyAircraftCoord.direct_distance_to(myCoord) * M2NM;
  457. me.Range.setValue(myDistance);
  458. }
  459. #print("get_range_from_Coord :" ~ myDistance);
  460. return myDistance;
  461. },
  462. get_horizon: func(own_alt){
  463. # Own alt in meters
  464. var tgt_alt = me.get_altitude();#It's in feet
  465. if(debug.isnan(tgt_alt))
  466. {
  467. return(0);
  468. }
  469. if(tgt_alt < 0 or tgt_alt == nil)
  470. {
  471. tgt_alt = 0;
  472. }
  473. if(own_alt < 0 or own_alt == nil)
  474. {
  475. own_alt = 0;
  476. }
  477. # Return the Horizon in NM
  478. return(2.2 * ( math.sqrt(own_alt) + math.sqrt(tgt_alt * FT2M)));
  479. },
  480. get_engineTree: func(){
  481. return me.engineTree;
  482. },
  483. check_carrier_type: func(){
  484. var type = "none";
  485. var carrier = 0;
  486. if(me.AcType != nil)
  487. {
  488. type = me.AcType.getValue();
  489. }
  490. if(type == "MP-Nimitz"
  491. or type == "MP-Eisenhower"
  492. or type == "MP-Vinson"
  493. or type == "Nimitz"
  494. or type == "Eisenhower"
  495. or type == "Vinson"
  496. )
  497. {
  498. carrier = 1;
  499. }
  500. if(me.type == "carrier")
  501. {
  502. carrier = 1;
  503. }
  504. # This works only after the mp-carrier model has been loaded. Before that it is seen like a common aircraft.
  505. if(me.get_Validity())
  506. {
  507. setprop(me.InstrString ~ "/" ~ me.shortstring ~ "/carrier", carrier);
  508. }
  509. return carrier;
  510. },
  511. get_rdr_standby: func(){
  512. var s = 0;
  513. if(me.RadarStandby != nil)
  514. {
  515. s = me.RadarStandby.getValue();
  516. if(s == nil)
  517. {
  518. s = 0;
  519. }
  520. elsif(s != 1)
  521. {
  522. s = 0;
  523. }
  524. }
  525. return s;
  526. },
  527. get_display: func(){
  528. #print("Get display : " ~ me.get_Callsign() ~ " Paiting : " ~ me.ispainted ~" and Display : " ~ me.Display);
  529. return me.Display;
  530. },
  531. set_display: func(n,writeTree = nil){
  532. me.Display = n;
  533. if(writeTree == nil or writeTree==1){
  534. me.Display_Node.setBoolValue(n);
  535. }
  536. me.objectDisplay = n;
  537. },
  538. set_relative_bearing: func(n,writeTree = nil){
  539. if(n == nil)
  540. {
  541. n = 0;
  542. }
  543. if(writeTree == nil or writeTree==1){
  544. me.RelBearing.setValue(n);
  545. }else{
  546. me.RelBearing = n;
  547. }
  548. },
  549. get_fading: func(){
  550. var fading = me.Fading.getValue();
  551. if(fading == nil)
  552. {
  553. fading = 0;
  554. }
  555. return fading;
  556. },
  557. set_fading: func(n,writeTree = nil){
  558. if(writeTree == nil or writeTree==1){
  559. me.Fading.setValue(n);
  560. }else{
  561. me.Fading = n;
  562. }
  563. },
  564. set_ddd_draw_range_nm: func(n,writeTree = nil){
  565. if(writeTree == nil or writeTree==1){
  566. me.DddDrawRangeNm.setValue(n);
  567. }else{
  568. me.DddDrawRangeNm = n;
  569. }
  570. },
  571. set_hud_draw_horiz_dev: func(n,writeTree = nil){
  572. if(writeTree == nil or writeTree==1){
  573. me.HudDrawHorizDev.setValue(n);
  574. }else{
  575. me.HudDrawHorizDev = n;
  576. }
  577. },
  578. set_tid_draw_range_nm: func(n,writeTree = nil){
  579. #print("The n 1:" ~ n);
  580. if(writeTree == nil or writeTree==1){
  581. #print("The n 2:" ~ n);
  582. me.TidDrawRangeNm.setValue(n);
  583. #print("The n 3:" ~ me.TidDrawRangeNm.getValue());
  584. }else{
  585. me.TidDrawRangeNm = n;
  586. }
  587. },
  588. set_rounded_alt: func(n,writeTree = nil){
  589. if(writeTree == nil or writeTree==1){
  590. me.RoundedAlt.setValue(n);
  591. }else{
  592. me.RoundedAlt = n;
  593. }
  594. },
  595. get_closure_rate: func(){
  596. var dt = ElapsedSec.getValue() - me.TimeLast.getValue();
  597. var rng = me.Range.getValue();
  598. var lrng = me.RangeLast.getValue();
  599. if(debug.isnan(rng) or debug.isnan(lrng))
  600. {
  601. print("####### get_closure_rate(): rng or lrng = nan ########");
  602. me.ClosureRate.setValue(0);
  603. me.RangeLast.setValue(0);
  604. return(0);
  605. }
  606. var t_distance = lrng - rng;
  607. var cr = (dt > 0) ? t_distance / dt * 3600 : 0;
  608. me.ClosureRate.setValue(cr);
  609. me.RangeLast.setValue(rng);
  610. return(cr);
  611. },
  612. get_closure_rate_from_Coord: func(MyAircraftCoord) {
  613. # First step : find the target heading.
  614. var myHeading = me.Heading.getValue();
  615. # Second What would be the aircraft heading to go to us
  616. var myCoord = me.get_Coord();
  617. var projectionHeading = myCoord.course_to(MyAircraftCoord);
  618. # Calculate the angle difference
  619. var myAngle = myHeading - projectionHeading; #Should work even with negative values
  620. # take the "ground speed"
  621. # velocities/true-air-speed-kt
  622. var mySpeed = me.Speed.getValue();
  623. var myProjetedHorizontalSpeed = mySpeed*math.cos(myAngle*D2R); #in KTS
  624. #print("Projetted Horizontal Speed:"~ myProjetedHorizontalSpeed);
  625. # Now getting the pitch deviation
  626. var myPitchToAircraft = - me.Elevation.getValue();
  627. #print("My pitch to Aircraft:"~myPitchToAircraft);
  628. # Get V speed
  629. if(me.VSpeed.getValue() == nil)
  630. {
  631. return 0;
  632. }
  633. var myVspeed = me.VSpeed.getValue()*FPS2KT;
  634. # This speed is absolutely vertical. So need to remove pi/2
  635. var myProjetedVerticalSpeed = myVspeed * math.cos(myPitchToAircraft-90*D2R);
  636. # Control Print
  637. #print("myVspeed = " ~myVspeed);
  638. #print("Total Closure Rate:" ~ (myProjetedHorizontalSpeed+myProjetedVerticalSpeed));
  639. # Total Calculation
  640. var cr = myProjetedHorizontalSpeed+myProjetedVerticalSpeed;
  641. # Setting Essential properties
  642. var rng = me. get_range_from_Coord(MyAircraftCoord);
  643. var newTime= ElapsedSec.getValue();
  644. if(me.get_Validity())
  645. {
  646. setprop(me.InstrString ~ "/" ~ me.shortstring ~ "/closure-last-range-nm", rng);
  647. setprop(me.InstrString ~ "/" ~ me.shortstring ~ "/closure-rate-kts", cr);
  648. }
  649. return cr;
  650. },
  651. get_shortring:func(){
  652. return me.shortstring;
  653. },
  654. get_type: func(){
  655. #print("Type:"~me.type);
  656. return me.type;
  657. },
  658. setType: func(typ) {
  659. me.type = typ;
  660. },
  661. # getUnique: func () {
  662. # #var myIndex = me.getIndex();
  663. # #print("getUnique:"~me.propNode.getName()~me.fname~me.Callsign.getValue());
  664. # return me.propNode.getName()~me.fname~me.get_Callsign();
  665. # #~me.ID;
  666. # #return me.get_type()~me.fname~me.ID;
  667. # },
  668. isValid: func() {
  669. var valid = me.Valid.getValue();
  670. if (valid == nil) {
  671. valid = FALSE;
  672. }
  673. if (!valid and me.tacobj.valid) {
  674. if (tacview.starttime) {
  675. # thread.lock(tacview.mutexWrite);
  676. # tacview.write("#" ~ (systime() - tacview.starttime)~"\n");
  677. # tacview.write("0,Event=LeftArea|"~me.tacobj.tacviewID~"|\n");
  678. # tacview.write("-"~me.tacobj.tacviewID~"\n");
  679. # thread.unlock(tacview.mutexWrite);
  680. me.tacobj.valid = 0;
  681. }
  682. }
  683. return valid;
  684. },
  685. getUnique: func {
  686. return me.unique;
  687. },
  688. isFriend: func(){
  689. #link16 is declared in radar2.nas
  690. foreach(var callsign_Ally;link16_array){
  691. if(me.Callsign.getValue()==callsign_Ally){return 1;}
  692. }
  693. return 0;
  694. },
  695. isRadiating: func (coord) {
  696. me.rn = me.get_range();
  697. #if (me.get_model() != "buk-m2" and me.get_model() != "MIM104D" and me.get_model() != "missile_frigate" or me.get_type()== armament.MARINE) {
  698. if(me.get_type()== armament.AIR){
  699. me.bearingR = coord.course_to(me.get_Coord());
  700. me.headingR = me.get_heading();
  701. me.inv_bearingR = me.bearingR+180;
  702. me.deviationRd = me.inv_bearingR - me.headingR;
  703. } else {
  704. me.deviationRd = 0;
  705. }
  706. me.rdrAct = me.propNode.getNode("sim/multiplay/generic/int[2]");
  707. #if the radar is SURFACE or MARINE, it turns, so no orientation asked
  708. if (me.rn < 70 and ((me.rdrAct != nil and me.rdrAct.getValue()!=1) or me.rdrAct == nil)
  709. and (math.abs(geo.normdeg180(me.deviationRd)) < 60 or me.get_type()!= armament.AIR)) {
  710. # our radar is active and pointed at coord.
  711. #print("Is Radiating");
  712. return 1;
  713. }
  714. return 0;
  715. #print("Is Not Radiating");
  716. },
  717. getElevation: func () {
  718. return me.get_Elevation_from_Coord(geo.aircraft_position());
  719. },
  720. getFlareNode: func(){
  721. return me.flareNode;
  722. },
  723. getChaffNode: func(){
  724. return me.chaffNode;
  725. },
  726. setPainted: func(mypainting){
  727. #print("Painting : " ~ mypainting);
  728. me.ispainted = mypainting;
  729. },
  730. isPainted: func() {
  731. #if(me.Display == 0){me.setPainted(0);}
  732. #print(me.get_Callsign() ~ "Paiting : " ~ me.ispainted);
  733. return me.ispainted; # Shinobi this is if laser/lock is still on it. Used for laser and semi-radar guided missiles/bombs.
  734. },
  735. isLaserPainted: func() {
  736. return me.ispainted;
  737. },
  738. setVirtual: func (virt) {
  739. me.virtual = virt;
  740. },
  741. isVirtual: func(){
  742. if(me.get_Callsign() == "GROUND_TARGET"){return 1;}else{return 0;}
  743. },
  744. get_model: func {
  745. return me.model;
  746. },
  747. set_model: func (mdl) {
  748. me.model = mdl;
  749. },
  750. get_uBody: func {
  751. var body = nil;
  752. if (me.ubody != nil) {
  753. body = me.ubody.getValue();
  754. }
  755. if(body == nil) {
  756. body = me.get_Speed()*KT2FPS;
  757. }
  758. return body;
  759. },
  760. get_vBody: func {
  761. var body = nil;
  762. if (me.ubody != nil) {
  763. body = me.vbody.getValue();
  764. }
  765. if(body == nil) {
  766. body = 0;
  767. }
  768. return body;
  769. },
  770. get_wBody: func {
  771. var body = nil;
  772. if (me.ubody != nil) {
  773. body = me.wbody.getValue();
  774. }
  775. if(body == nil) {
  776. body = 0;
  777. }
  778. return body;
  779. },
  780. list : [],
  781. };
  782. # Utilities.
  783. var deviation_normdeg = func(our_heading, target_bearing){
  784. var dev_norm = our_heading - target_bearing;
  785. while(dev_norm < -180)
  786. {
  787. dev_norm += 360;
  788. }
  789. while(dev_norm > 180)
  790. {
  791. dev_norm -= 360;
  792. }
  793. return(dev_norm);
  794. }
  795. var rounding1000 = func(n){
  796. var a = int(n / 1000);
  797. var l = (a + 0.5) * 1000;
  798. n = (n >= l) ? ((a + 1) * 1000) : (a * 1000);
  799. return(n);
  800. }