diff --git a/Aircraft/Instruments-3d/radar2/radar2.nas b/Aircraft/Instruments-3d/radar2/radar2.nas
new file mode 100644
index 000000000..676629148
--- /dev/null
+++ b/Aircraft/Instruments-3d/radar2/radar2.nas
@@ -0,0 +1,250 @@
+##### radar2.nas Multiplayer radar and ECM/RWR system.
+
+# Alexis Bory, 2008.
+ 
+# Cycles through the list of multiplayers and tankers, then triggers 
+# radar or ECM/RWR computations if those features are enabled in our aircraft -set.xml file.
+
+# Needs radardist.nas for some visibilty computations based on radardist radar and RCS database.
+# watch_aimp_models() has to be periodicaly called from one of our aircraft
+# nasal files. Do not forget to init both scripts. 
+
+# Properties:
+
+# instrumentation/radar/enabled (bool) (radar display)
+# instrumentation/ecm/enabled (bool) (RWR display)
+# At least one of these.
+
+# /instrumentation/radar/range : fixed limit to any computation (both radar and ECM/RWR)
+# /instrumentation/radar/radar2-range : our own and current display range.
+# TODO: /instrumentation/radar/symbols-enabled (bool) as we could also display raw spots on the screen.
+# /instrumentation/radar/radar-standby (int), shall be transmited via sim/multiplay/generic/int[2]
+# (until we get a good definition of radar and related properties that could be added to the
+# standard set of MP transmited parameters). With this property set to 1, your radar is not
+# updated anymore but continue to show targets as they where before entering standby and it
+# enter silent mode and do not trigger any alert on other players using a RWR.
+ 
+# /instrumentation/ecm/on-off (bool)
+# alert type 1: at least one weak scan detected. /instrumentation/ecm/alert-type1 (bool)
+# alert type 2: at least one strong scan detected. /instrumentation/ecm/alert-type1 (bool)
+
+# About radar2.nas and wxradar.
+# radar2.nas was intended first to permit building a radar display using a standard .xml animation.
+# Then it was enhanced to provide new multiplayer feature. wxradar was already a good candidate for that
+# and would have a great avantage because those standard .xml animations are really a pity to do,
+# (as many as 3000 xml lines for the f-14 display). Anyway, I'm not enough skilled to write C++ and
+# I also hope that radar2.nas feature will be integrated in wxradar so both can operate together in
+# the same sky.
+
+
+var watch_i      = 0;
+var list_count   = 0;
+var radar_able   = nil;
+var ecm_able = nil;
+var impact_able  = nil;
+var synbols_enabled = nil;
+var my_radarcorr = 0;
+var Mp = props.globals.getNode("ai/models");
+var watch_list = [];
+
+# Our aircraft controls.
+var OurRadarStandby = props.globals.getNode("instrumentation/radar/radar-standby", 1);
+var RangeRadar = props.globals.getNode("instrumentation/radar/range");
+var RangeRadar2 = props.globals.getNode("instrumentation/radar/radar2-range");
+var EcmOn = props.globals.getNode("instrumentation/ecm/on-off", 1);
+
+var OurAlt = props.globals.getNode("position/altitude-ft");
+
+# ECM warnings.
+var EcmAlert1 = props.globals.getNode("instrumentation/ecm/alert-type1", 1);
+var EcmAlert2 = props.globals.getNode("instrumentation/ecm/alert-type2", 1);
+var ecm_alert1      = 0;
+var ecm_alert2      = 0;
+var ecm_alert1_last = 0;
+var ecm_alert2_last = 0;
+
+
+var init = func {
+	var our_ac_name = getprop("sim/aircraft");
+	# Check which feature are enabled for our aircraft to avoid computing useless things.
+	radar_able    = props.globals.getNode("instrumentation/radar/enabled").getValue();
+	ecm_able    = props.globals.getNode("instrumentation/ecm/enabled").getValue();
+	# TODO: synbols_enabled = props.globals.getNode("instrumentation/radar/symbols_enabled");
+	# Get our radar max range.
+	if (radar_able) { 
+		my_radarcorr = radardist.my_maxrange( our_ac_name ); # in kilometers
+	}
+	if ( OurRadarStandby.getValue() == nil ) {
+		OurRadarStandby.setBoolValue(0);
+	}
+}
+
+
+# Main loop.
+var watch_aimp_models = func {
+	# Cycle through an ordered list of multiplayers and tankers.
+	if ( watch_i == 0 ) {
+		list_count = get_list();
+	}
+	var target_type = watch_list[watch_i][0];
+	var target_index = watch_list[watch_i][1];
+	var target_string = "ai/models/" ~ target_type ~ "[" ~ target_index ~ "]";
+	target_process( target_string );
+	if ( watch_i == ( list_count - 1 )) {
+		watch_i = 0;
+	} else {
+		watch_i += 1;
+	}
+}
+
+
+var get_list = func {
+	watch_list = [];
+	var raw_list = Mp.getChildren();
+	foreach( var c; raw_list ) {
+		var type = c.getName();
+		# Carriers are not well handled yet by AIBase.cxx, so we only reconize mp-carriers.
+		if (type == "multiplayer" or type == "tanker") {
+			append(watch_list, [type, c.getIndex()]);
+		}
+	}
+	return size(watch_list);
+}
+
+
+
+
+
+var target_process = func ( target ) {
+	var TNode         = props.globals.getNode(target);
+	var TRadar        = TNode.getNode("radar");
+	var TRadarStandby = TNode.getNode("sim/multiplay/generic/int[2]");
+	# This propery used by ECM over MP should be standardized,
+	# like "ai/models/multiplayer[0]/radar/radar-standby"
+	var THeading      = TNode.getNode("orientation/true-heading-deg");
+	var TInRange      = TRadar.getNode("in-range");
+	var TCarrier      = TRadar.getNode("carrier", 1);
+	var TDisplay      = TRadar.getNode("display", 1);
+	var TEcmSignal    = TRadar.getNode("ecm-signal", 1);
+	# Set variables.
+	var t_carrier     = 0;
+	var t_display     = 0;
+	var t_ecm_signal  = 0;
+	var t_radar_standby = 0;
+
+	if ( TRadarStandby != nil ) {
+		t_radar_standby = TRadarStandby.getValue();
+		if ( t_radar_standby == nil ) {
+			t_radar_standby = 0;
+		} elsif ( t_radar_standby != 1 ) {
+			t_radar_standby = 0;
+		}
+	}	
+	var our_radar_standby = OurRadarStandby.getValue();
+	var t_in_range = TInRange.getValue();
+	if ( t_in_range ) {
+		var TPosition     = TNode.getNode("position");
+		var TRange        = TRadar.getNode("range-nm");
+		var t_range       = TRange.getValue();
+		var TBearing      = TRadar.getNode("bearing-deg");
+		var t_bearing     = TBearing.getValue();
+		var TAlt          = TPosition.getNode("altitude-ft");
+		var t_alt         = TAlt.getValue();
+		var TDrawRangeNm  = TRadar.getNode("draw-range-nm", 1);
+		var TRoundedAlt   = TRadar.getNode("rounded-alt-ft", 1);
+		var t_heading     = THeading.getValue();
+		var range_radar   = RangeRadar.getValue();
+		var range_radar2   = RangeRadar2.getValue();
+		var TPath         = TNode.getNode("sim/model/path");
+		var TACType       = TNode.getNode("sim/model/ac-type");
+		if (( t_bearing == nil ) or ( t_alt == nil ) or ( TPath == nil )) {
+			return;
+		}
+		var t_ac_type = "none";
+		if ( TACType != nil ) { t_ac_type = TACType.getValue() }
+		if ( t_ac_type == "MP-Nimitz" or t_ac_type == "MP-Eisenhower") {
+			t_carrier = 1;
+		}
+		var our_alt = OurAlt.getValue();
+		var horizon = radardist.radar_horizon( our_alt, t_alt );
+		# RADAR stuff.
+		# Check if mp within our radar field (hard coded 74°) and if detectable.
+		if ( radar_able and t_range <= range_radar2 and !our_radar_standby ) {
+			var true_heading = getprop("orientation/heading-deg");
+			var deviation_deg = deviation_normdeg(true_heading, t_bearing);
+			if ( deviation_deg > -37  and  deviation_deg < 37 and radardist.radis(target, my_radarcorr) and t_range < horizon ) {
+				# Compute mp position in our radar display. (Horizontal situation)
+				if ( range_radar2 == 0 ) { range_radar2 = 0.00000001 }
+				var factor_range_radar = 0.15 / range_radar2;
+				var draw_radar = factor_range_radar * t_range;
+				TDrawRangeNm.setValue(draw_radar);
+				# Compute first digit of mp altitude rounded to nearest thousand. (labels).
+				var rounded_alt = rounding1000(t_alt) / 1000;			
+				TRoundedAlt.setValue(rounded_alt);
+				t_display = 1;
+			}
+		}
+		# ECM/RWR stuff.
+		# Test if target has a radar. Computes if we are illuminated.
+		ecm_on = EcmOn.getValue();
+		if ( ecm_able and ecm_on and t_radar_standby == 0 ) {
+			# TODO: overide display when alert.
+			t_path = TPath.getValue();
+			var t_name = radardist.get_aircraft_name(target);
+			var t_maxrange = radardist.my_maxrange(t_name); # in kilometer, 0 is unknown or no radar.
+			if ( t_maxrange > 0  and t_range < horizon ) {
+				# Test if we are in its (arbitrary 120°) angular coverage or if we have a carrier.
+				# Compute the signal strength.
+				var t_reciprocal_bearing = geo.normdeg(t_bearing + 180);
+				var our_deviation_deg = deviation_normdeg(t_heading, t_reciprocal_bearing);
+				if ( our_deviation_deg < 0 ) { our_deviation_deg *= -1 }
+				if ( our_deviation_deg < 60 or t_carrier == 1 ) {
+					t_ecm_signal = ( (((-our_deviation_deg/30)+2.5)*(!t_carrier )) + (-t_range/20) + 2.6 + (t_carrier*1.8));
+				}
+			}
+			# Compute global threat situation. (undiscriminant warning lights)
+			if ( t_ecm_signal > 1 and t_ecm_signal < 3 ) {
+				EcmAlert1.setBoolValue(1);
+				ecm_alert1 = 1;
+			} elsif ( t_ecm_signal >= 3 ) {
+				EcmAlert2.setBoolValue(1);
+				ecm_alert2 = 1;
+			}
+		}
+	}
+	# Outputs:
+	if ( ! our_radar_standby ) {
+		# If stanby: stop updating but do not erase targets positions.
+		TCarrier.setBoolValue(t_carrier);
+		TDisplay.setBoolValue(t_display);
+	}
+	if ( watch_i == 0 ) {
+		if ( ecm_alert1 == 0 and ecm_alert1_last == 0 ) { EcmAlert1.setBoolValue(0) }
+		if ( ecm_alert2 == 0 and ecm_alert1_last == 0 ) { EcmAlert2.setBoolValue(0) }
+		# Avoid alert blinking at each loop.
+		ecm_alert1_last = ecm_alert1;
+		ecm_alert2_last = ecm_alert2;
+		ecm_alert1 = 0;
+		ecm_alert2 = 0;
+	}	
+	TEcmSignal.setValue(t_ecm_signal);
+
+}
+
+
+# Utilities.
+var deviation_normdeg = func(our_heading, target_bearing) {
+			var dev_norm = our_heading - target_bearing;
+			while (dev_norm < -180) dev_norm += 360;
+			while (dev_norm > 180) dev_norm -= 360;
+			return(dev_norm);
+}
+
+var rounding1000 = func(n) {
+	var a = int( n / 1000 );
+	var l = ( a + 0.5 ) * 1000;
+	n = (n >= l) ? ((a + 1) * 1000) : (a * 1000);
+	return( n );
+}
+
+