--- /home/te/games/tdm/def/misc.def.org	2014-04-25 21:06:08.000000000 +0200
+++ /home/te/games/tdm/def/misc.def	2014-09-22 11:42:24.000000000 +0200
@@ -137,6 +137,8 @@
 	"editor_float ambient_light_fade_time"	"Time in seconds to fade the ambient light to the new color."
 	"editor_float fade_time"				"Time in seconds to fade the ambient music/sound to the new sound."
 	"editor_vector ambient_light_dynamic_cap"	"Cap the dynamic part of the ambient light at these values.  Default is 0.1 0.1 0.1, but other settings can be useful - for instance 0.2 0.05 0.05 in a reddish cave, etc."
+	"editor_vector ambient_light_dynamic"	"The factor to multiply light sources in the current PVS to compute the dynamic part of the ambient light.  Default is 0.1 0.1 0.1, but other settings can be useful - for instance 0.2 0.05 0.05 in a reddish cave, etc. See also 'ambient_light_dynamic_cap'."
+	"editor_bool no_ambient_light_fade"	"If set to 1, the main ambient light will not be modified. Can be overriden in each location with 'no_ambient_light_fade' '0' and defaults to 0."
 
 	"editor_float ambient_light_falloff"		"Selects the falloff adjustment for the lights in the current area based on their distance.  Possible values: 0 = no falloff with distance, 0.5 = sqrt(distance), 1 = linear falloff, 2 = squared falloff.  1 looks best.  This setting can be overriden for each location on the 'info_location' entity.  See also 'ambient_light_dist_scale'."
 	"editor_float ambient_light_dist_scale"		"An adjustment factor for the distance-based falloffs (if 'ambient_light_falloff' is > 0).  Values around 1.0 look best.  Can be overriden for each location on the 'info_location' entity."
@@ -146,6 +148,7 @@
 
 	"editor_setkeyValue ambient_light_falloff"	"0"
 	"editor_setkeyValue ambient_light_dist_scale"	"1.0"
+	"editor_setkeyValue no_ambient_light_fade"	"0"
 
 	"ambient_light_dynamic_cap"	"0.1 0.1 0.1"
 	"editor_setkeyValue ambient_light_dynamic_cap"	"0.1 0.1 0.1"
@@ -203,13 +206,16 @@
 	"editor_var call_once_on_exit"			"Name of global script function to be called exactly once when the player exits this zone."
 	"editor_var call_once_on_entry"			"Name of global script function to be called exactly once when the player enters this zone."
 
-	"editor_var ambient_light_dynamic"		"Factor to multiply the sum of all light sources in this location by before adding them to the 'ambient_light'.  Set to '0 0 0' to disable dynamic ambient light for this location.  Defaults to '0.01 0.01 0.01'."
+	"editor_vector ambient_light_dynamic"		"Factor to multiply the sum of all light sources in this location by before adding them to the 'ambient_light'.  Set to '0 0 0' to disable dynamic ambient light for this location.  Defaults to '0.01 0.01 0.01'."
 
 	"editor_float ambient_light_falloff"		"Selects the falloff adjustment for the lights in the current area based on their distance.  Possible values: -1 = use setting from your atdm:location_settings entity, 0 = no falloff with distance, 0.5 = sqrt(distance), 1 = linear falloff, 2 = squared falloff.  1 looks best.  See also 'ambient_light_dist_scale'."
 	"editor_float ambient_light_dist_scale"		"An adjustment factor for the distance-based falloffs (if 'ambient_light_falloff' is > 0).  Values around 1.0 look best.  A value of -1 uses the value from your atdm:location_settings entity."
 
 	"editor_vector ambient_light_dynamic_cap"	"Cap the dynamic part of the ambient light at these values.  Default is 0.1 0.1 0.1, but other settings can be useful, for instance 0.2 0.05 0.05 in a reddish cave, etc."
 
+	"editor_bool no_ambient_light_fade"	"If set to 1, the main ambient light will not be modified when inside this location. If set to '-1', use setting from your atdm:location_settings entity."
+	"editor_setkeyValue no_ambient_light_fade"	"-1"
+
 	"ambient_light_falloff"		"-1"		// use atdm:location settings
 	"ambient_light_dist_scale"	"-1"		// use atdm:location settings
 
--- /home/te/games/tdm/script/tdm_location_settings.script.org	2013-12-06 18:23:58.000000000 +0100
+++ /home/te/games/tdm/script/tdm_location_settings.script	2014-09-22 12:43:07.000000000 +0200
@@ -60,6 +60,7 @@
 	float music_volume;
 
 	/* Tels: Additional members for the ambient light changing: */
+	boolean m_al_no_fade;	
 	float   m_al_fade_time;	
 	float   m_al_fade_time_default;
 
@@ -129,7 +130,13 @@
 	music_volume = (sys.strToFloat( sys.getcvar("tdm_music_volume") ) + 40) / 40;
 
 	/* Tels: Init the ambient light part: */
-
+	m_al_no_fade = false;
+	if (getBoolKey( "no_ambient_light_fade" ))
+	{
+		m_al_no_fade = true;
+		sys.println ("Global no_ambient_light_fade = true, will not fade the main ambient light.");
+		// but continue, because the current location might want to fade the light again
+	}
 	// the default time
 	m_al_fade_time_default = getFloatKey( "ambient_light_fade_time" );
 	// set a default
@@ -232,7 +239,7 @@
 // player entered new location, so update ambient base color and fade time/delay
 void speaker_zone_ambient::updateAmbientLight( entity locEnt )
 {
-	// sys.print( "Setting ambient in location " + locEnt.getName() );
+	// sys.println( "Setting ambient in location " + locEnt.getName() );
 	//sys.print( "Setting old base to '" + m_al_base + "'\n");
 
 	// store the current base and add the old dynamic so we don't experience a sudden drop/raise (bug #2326)
@@ -241,11 +248,10 @@
 	// fade to the new location's color
 	m_al_base_target = locEnt.getVectorKey("ambient_light");
 
-	// tels: can this be done simpler? == "0,0,0" doesn't work, tho
-	if (m_al_base_target_x == 0 && m_al_base_target_y == 0 && m_al_base_target_z == 0)
+	if (m_al_base_target == '0 0 0')
 	{
 		// no value found, use the default
-		// sys.print( "No new target, using default color '" + m_al_default_color + "'\n");
+		// sys.println( "No new target, using default color '" + m_al_default_color + "'");
 		m_al_base_target = m_al_default_color;
 	}
 
@@ -270,6 +276,46 @@
 	}
     // time that has elapsed going from base_old to base_target
 	m_al_fade_start = sys.getTime();
+
+	// See if we need to start or stop fading in this location
+	boolean no_fade = false;
+	string fade_key = locEnt.getKey("no_ambient_light_fade");
+	if (fade_key == "" || fade_key == "-" || fade_key == "-1")
+	{
+		// not defined, use the global setting
+		if (getBoolKey("no_ambient_light_fade"))
+		{
+			no_fade = true;
+		}
+	}
+	else
+	{
+		if (fade_key != "0")
+		{
+			no_fade = true;
+		}
+	}
+
+	// setting changed in this location?
+	if (no_fade && !m_al_no_fade)
+	{
+		sys.println ("speaker_zone_ambient: no_ambient_light_fade = true, stop fading ambient light.");
+		m_al_no_fade = true;
+		// If we stop fading the ambient light, at least set the ambient for the new zone, so we
+		// are not stuck with the old values. After this initial set here, the ambient light will be
+		// left alone and can be controlled by scripts:
+		m_al_fade_start = 0; 	// avoid a ambient_fade_time > 0 preventing this setting here
+		fadeAmbientLight();
+	}
+	else
+	{
+		if (!no_fade && m_al_no_fade)
+		{
+			sys.println ("speaker_zone_ambient: no_ambient_light_fade = false, start fading ambient light again.");
+			m_al_no_fade = false;
+		}
+	}
+
 }
 
 // compute the current base ambient light based on: old color, target color, elapsed time
@@ -376,68 +422,72 @@
 
 		// sys.println( "Ambient script check, music_volume " + music_volume + " in location " + locEnt.getName() );
 
-		// Tels: query here the ambient_light_dynamic factor:
-		vector dyn = locEnt.getVectorKey("ambient_light_dynamic");
-
-		if (dyn_x != 0 || dyn_y != 0 || dyn_z != 0)
+		// now fade the ambient light until the next update
+		if (!m_al_no_fade)
 		{
-			// save the old dynamic value for a smoother fade (bug #2327)
-			m_al_dynamic_old = m_al_dynamic;
+			// Tels: query here the ambient_light_dynamic factor:
+			vector dyn = locEnt.getVectorKey("ambient_light_dynamic");
 
-			// parameters: falloff, distance_scaling:
-			//  falloff == 0: no falloff with distance
-			//  falloff == 0.5: sqrt(linear) falloff	(dist 100 => 1/10)
-			//  falloff == 1: linear falloff			(dist 100 => 1/100)
-			//  falloff == 2: square falloff			(dist 100 => 1/10000)
-			//  distance scaling: factor to scale the distance, can be used to lower/raise distance factor
-			//   after the linear or square scaling has been used.
-			float falloff;
-		   	falloff	= locEnt.getFloatKey("ambient_light_falloff");		// default is 1
-			if (falloff == -1)
-			{
-				falloff = m_al_falloff_default;
-			}
-			float dynScale;
-			dynScale = locEnt.getFloatKey("ambient_light_dist_scale");
-			if (dynScale == -1)
-			{
-				dynScale = m_al_dist_scale_default;
-			}
-			// adjust the scaling so the mapper can always put 1.0 for every falloff
-			//  good looking: approx: sqrt(linear): 0.01, linear: 0.1, square 1.0
-			if (falloff == 0.5)
+			if (dyn != '0 0 0')
 			{
-				dynScale /= 100;	// 1.0 => 0.01
+				// save the old dynamic value for a smoother fade (bug #2327)
+				m_al_dynamic_old = m_al_dynamic;
+
+				// parameters: falloff, distance_scaling:
+				//  falloff == 0: no falloff with distance
+				//  falloff == 0.5: sqrt(linear) falloff	(dist 100 => 1/10)
+				//  falloff == 1: linear falloff			(dist 100 => 1/100)
+				//  falloff == 2: square falloff			(dist 100 => 1/10000)
+				//  distance scaling: factor to scale the distance, can be used to lower/raise distance factor
+				//   after the linear or square scaling has been used.
+				float falloff;
+			   	falloff	= locEnt.getFloatKey("ambient_light_falloff");		// default is 1
+				if (falloff == -1)
+				{
+					falloff = m_al_falloff_default;
+				}
+				float dynScale;
+				dynScale = locEnt.getFloatKey("ambient_light_dist_scale");
+				if (dynScale == -1)
+				{
+					dynScale = m_al_dist_scale_default;
+				}
+				// adjust the scaling so the mapper can always put 1.0 for every falloff
+				//  good looking: approx: sqrt(linear): 0.01, linear: 0.1, square 1.0
+				if (falloff == 0.5)
+				{
+					dynScale /= 100;	// 1.0 => 0.01
+				}
+				else if (falloff == 1)
+				{
+					dynScale /= 10;		// 1.0 => 0.1
+				}
+				vector light_in_pvs = $player1.getLightInPVS( falloff, dynScale );
+				m_al_dynamic_x = light_in_pvs_x * dyn_x; 
+				m_al_dynamic_y = light_in_pvs_y * dyn_y; 
+				m_al_dynamic_z = light_in_pvs_z * dyn_z;
+
+				// cap the value?
+				vector cap = locEnt.getVectorKey("ambient_light_dynamic_cap");
+				if (cap_x > 0 && m_al_dynamic_x > cap_x ) { m_al_dynamic_x = cap_x; }
+				if (cap_y > 0 && m_al_dynamic_y > cap_y ) { m_al_dynamic_y = cap_y; }
+				if (cap_z > 0 && m_al_dynamic_z > cap_z ) { m_al_dynamic_z = cap_z; }
+
+				//sys.print( " New dynamic ambient light cap is: '" + cap + "'. \n" );
+				// sys.print( " New dynamic ambient light is: '" + m_al_dynamic + "'. \n" );
+				//sys.print( " Old dynamic ambient light: '" + m_al_dynamic_old + "'. \n" );
 			}
-			else if (falloff == 1)
+			else // we entered a zone where the dynamic part is zero? avoid getting *stuck* at the old value
 			{
-				dynScale /= 10;		// 1.0 => 0.1
+				// save the old dynamic value for a smoother fade (bug #2327)
+				m_al_dynamic_old = m_al_dynamic;
+				// fade it to half the value, over time this will result in 0:
+				m_al_dynamic_x = m_al_dynamic_old_x / 2;
+				m_al_dynamic_y = m_al_dynamic_old_y / 2;
+				m_al_dynamic_z = m_al_dynamic_old_z / 2;
+				// sys.print( " dyn = 0 0 0, New dynamic ambient light is: '" + m_al_dynamic + "'. \n" );
 			}
-			vector light_in_pvs = $player1.getLightInPVS( falloff, dynScale );
-			m_al_dynamic_x = light_in_pvs_x * dyn_x; 
-			m_al_dynamic_y = light_in_pvs_y * dyn_y; 
-			m_al_dynamic_z = light_in_pvs_z * dyn_z;
-
-			// cap the value?
-			vector cap = locEnt.getVectorKey("ambient_light_dynamic_cap");
-			if (cap_x > 0 && m_al_dynamic_x > cap_x ) { m_al_dynamic_x = cap_x; }
-			if (cap_y > 0 && m_al_dynamic_y > cap_y ) { m_al_dynamic_y = cap_y; }
-			if (cap_z > 0 && m_al_dynamic_z > cap_z ) { m_al_dynamic_z = cap_z; }
-
-			//sys.print( " New dynamic ambient light cap is: '" + cap + "'. \n" );
-			// sys.print( " New dynamic ambient light is: '" + m_al_dynamic + "'. \n" );
-			//sys.print( " Old dynamic ambient light: '" + m_al_dynamic_old + "'. \n" );
-		}
-		else // we entered a zone where the dynamic part is zero? avoid getting *stuck* at the old value
-		{
-			// save the old dynamic value for a smoother fade (bug #2327)
-			m_al_dynamic_old = m_al_dynamic;
-			// fade it to half the value, over time this will result in 0:
-			m_al_dynamic_x = m_al_dynamic_old_x / 2;
-			m_al_dynamic_y = m_al_dynamic_old_y / 2;
-			m_al_dynamic_z = m_al_dynamic_old_z / 2;
-			// sys.print( " dyn = 0 0 0, New dynamic ambient light is: '" + m_al_dynamic + "'. \n" );
-		}
+		} // end no_ambient_light_fade
 
 		if( locEnt.getName() != m_prevLocation )
 		{
@@ -487,7 +537,7 @@
 				callGlobalFunction( call, m_prevLocationEnt );
 				}
 
-			/* Tels: Update the new ambient base color and fade times/delays */
+			/* Tels: Update the new ambient base color and fade times/delays, as well as m_al_no_fade */
 			updateAmbientLight( locEnt );
 
 			/* Ambient speaker code starts here: */
@@ -665,7 +715,10 @@
 		}
 
 		// now fade the ambient light until the next update
-		fadeAmbientLight();
+		if (!m_al_no_fade)
+	   	{
+			fadeAmbientLight();
+		}
 
 		wait( m_updatePeriod );
 	}
