Prechádzať zdrojové kódy

Merge pull request #61287 from akien-mga/3.x-cherrypicks

Rémi Verschelde 3 rokov pred
rodič
commit
241c267d9c

+ 7 - 7
core/ustring.cpp

@@ -1739,7 +1739,7 @@ int String::hex_to_int(bool p_with_prefix) const {
 		}
 		}
 		// Check for overflow/underflow, with special case to ensure INT32_MIN does not result in error
 		// Check for overflow/underflow, with special case to ensure INT32_MIN does not result in error
 		bool overflow = ((hex > INT32_MAX / 16) && (sign == 1 || (sign == -1 && hex != (INT32_MAX >> 4) + 1))) || (sign == -1 && hex == (INT32_MAX >> 4) + 1 && c > '0');
 		bool overflow = ((hex > INT32_MAX / 16) && (sign == 1 || (sign == -1 && hex != (INT32_MAX >> 4) + 1))) || (sign == -1 && hex == (INT32_MAX >> 4) + 1 && c > '0');
-		ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+		ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as a 32-bit signed integer, since the value is " + (sign == 1 ? "too large." : "too small."));
 		hex *= 16;
 		hex *= 16;
 		hex += n;
 		hex += n;
 		s++;
 		s++;
@@ -1781,7 +1781,7 @@ int64_t String::hex_to_int64(bool p_with_prefix) const {
 			return 0;
 			return 0;
 		}
 		}
 		bool overflow = ((hex > INT64_MAX / 16) && (sign == 1 || (sign == -1 && hex != (INT64_MAX >> 4) + 1))) || (sign == -1 && hex == (INT64_MAX >> 4) + 1 && c > '0');
 		bool overflow = ((hex > INT64_MAX / 16) && (sign == 1 || (sign == -1 && hex != (INT64_MAX >> 4) + 1))) || (sign == -1 && hex == (INT64_MAX >> 4) + 1 && c > '0');
-		ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+		ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as a 64-bit signed integer, since the value is " + (sign == 1 ? "too large." : "too small."));
 		hex *= 16;
 		hex *= 16;
 		hex += n;
 		hex += n;
 		s++;
 		s++;
@@ -1823,7 +1823,7 @@ int64_t String::bin_to_int64(bool p_with_prefix) const {
 		}
 		}
 		// Check for overflow/underflow, with special case to ensure INT64_MIN does not result in error
 		// Check for overflow/underflow, with special case to ensure INT64_MIN does not result in error
 		bool overflow = ((binary > INT64_MAX / 2) && (sign == 1 || (sign == -1 && binary != (INT64_MAX >> 1) + 1))) || (sign == -1 && binary == (INT64_MAX >> 1) + 1 && c > '0');
 		bool overflow = ((binary > INT64_MAX / 2) && (sign == 1 || (sign == -1 && binary != (INT64_MAX >> 1) + 1))) || (sign == -1 && binary == (INT64_MAX >> 1) + 1 && c > '0');
-		ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+		ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as a 64-bit signed integer, since the value is " + (sign == 1 ? "too large." : "too small."));
 		binary *= 2;
 		binary *= 2;
 		binary += n;
 		binary += n;
 		s++;
 		s++;
@@ -1846,7 +1846,7 @@ int String::to_int() const {
 		CharType c = operator[](i);
 		CharType c = operator[](i);
 		if (c >= '0' && c <= '9') {
 		if (c >= '0' && c <= '9') {
 			bool overflow = (integer > INT32_MAX / 10) || (integer == INT32_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
 			bool overflow = (integer > INT32_MAX / 10) || (integer == INT32_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
-			ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+			ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as a 32-bit signed integer, since the value is " + (sign == 1 ? "too large." : "too small."));
 			integer *= 10;
 			integer *= 10;
 			integer += c - '0';
 			integer += c - '0';
 
 
@@ -1872,7 +1872,7 @@ int64_t String::to_int64() const {
 		CharType c = operator[](i);
 		CharType c = operator[](i);
 		if (c >= '0' && c <= '9') {
 		if (c >= '0' && c <= '9') {
 			bool overflow = (integer > INT64_MAX / 10) || (integer == INT64_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
 			bool overflow = (integer > INT64_MAX / 10) || (integer == INT64_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
-			ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+			ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as a 64-bit signed integer, since the value is " + (sign == 1 ? "too large." : "too small."));
 			integer *= 10;
 			integer *= 10;
 			integer += c - '0';
 			integer += c - '0';
 
 
@@ -1901,7 +1901,7 @@ int String::to_int(const char *p_str, int p_len) {
 		char c = p_str[i];
 		char c = p_str[i];
 		if (c >= '0' && c <= '9') {
 		if (c >= '0' && c <= '9') {
 			bool overflow = (integer > INT32_MAX / 10) || (integer == INT32_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
 			bool overflow = (integer > INT32_MAX / 10) || (integer == INT32_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
-			ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + String(p_str).substr(0, to) + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+			ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + String(p_str).substr(0, to) + " as a 32-bit signed integer, since the value is " + (sign == 1 ? "too large." : "too small."));
 			integer *= 10;
 			integer *= 10;
 			integer += c - '0';
 			integer += c - '0';
 
 
@@ -2220,7 +2220,7 @@ int64_t String::to_int(const CharType *p_str, int p_len) {
 						while (*str && str != limit) {
 						while (*str && str != limit) {
 							number += *(str++);
 							number += *(str++);
 						}
 						}
-						ERR_FAIL_V_MSG(sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + number + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+						ERR_FAIL_V_MSG(sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + number + " as a 64-bit signed integer, since the value is " + (sign == 1 ? "too large." : "too small."));
 					}
 					}
 					integer *= 10;
 					integer *= 10;
 					integer += c - '0';
 					integer += c - '0';

+ 1 - 1
doc/classes/FileDialog.xml

@@ -130,7 +130,7 @@
 		<theme_item name="file_icon_modulate" data_type="color" type="Color" default="Color( 1, 1, 1, 1 )">
 		<theme_item name="file_icon_modulate" data_type="color" type="Color" default="Color( 1, 1, 1, 1 )">
 			The color modulation applied to the file icon.
 			The color modulation applied to the file icon.
 		</theme_item>
 		</theme_item>
-		<theme_item name="files_disabled" data_type="color" type="Color" default="Color( 0, 0, 0, 0.7 )">
+		<theme_item name="files_disabled" data_type="color" type="Color" default="Color( 1, 1, 1, 0.25 )">
 			The color tint for disabled files (when the [FileDialog] is used in open folder mode).
 			The color tint for disabled files (when the [FileDialog] is used in open folder mode).
 		</theme_item>
 		</theme_item>
 		<theme_item name="folder_icon_modulate" data_type="color" type="Color" default="Color( 1, 1, 1, 1 )">
 		<theme_item name="folder_icon_modulate" data_type="color" type="Color" default="Color( 1, 1, 1, 1 )">

+ 4 - 1
doc/classes/NavigationAgent.xml

@@ -48,7 +48,7 @@
 		<method name="get_rid" qualifiers="const">
 		<method name="get_rid" qualifiers="const">
 			<return type="RID" />
 			<return type="RID" />
 			<description>
 			<description>
-				Returns the object's [RID].
+				Returns the [RID] of this agent on the [NavigationServer].
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="get_target_location" qualifiers="const">
 		<method name="get_target_location" qualifiers="const">
@@ -101,6 +101,9 @@
 		<member name="agent_height_offset" type="float" setter="set_agent_height_offset" getter="get_agent_height_offset" default="0.0">
 		<member name="agent_height_offset" type="float" setter="set_agent_height_offset" getter="get_agent_height_offset" default="0.0">
 			The agent height offset to match the navigation mesh height.
 			The agent height offset to match the navigation mesh height.
 		</member>
 		</member>
+		<member name="avoidance_enabled" type="bool" setter="set_avoidance_enabled" getter="get_avoidance_enabled" default="false">
+			If [code]true[/code] the agent is registered for an RVO avoidance callback on the [NavigationServer]. When [method set_velocity] is used and the processing is completed a [code]safe_velocity[/code] Vector3 is received with a signal connection to [signal velocity_computed]. Avoidance processing with many registered agents has a significant performance cost and should only be enabled on agents that currently require it.
+		</member>
 		<member name="ignore_y" type="bool" setter="set_ignore_y" getter="get_ignore_y" default="true">
 		<member name="ignore_y" type="bool" setter="set_ignore_y" getter="get_ignore_y" default="true">
 			Ignores collisions on the Y axis. Must be [code]true[/code] to move on a horizontal plane.
 			Ignores collisions on the Y axis. Must be [code]true[/code] to move on a horizontal plane.
 		</member>
 		</member>

+ 4 - 1
doc/classes/NavigationAgent2D.xml

@@ -48,7 +48,7 @@
 		<method name="get_rid" qualifiers="const">
 		<method name="get_rid" qualifiers="const">
 			<return type="RID" />
 			<return type="RID" />
 			<description>
 			<description>
-				Returns the object's [RID].
+				Returns the [RID] of this agent on the [Navigation2DServer].
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="get_target_location" qualifiers="const">
 		<method name="get_target_location" qualifiers="const">
@@ -98,6 +98,9 @@
 		</method>
 		</method>
 	</methods>
 	</methods>
 	<members>
 	<members>
+		<member name="avoidance_enabled" type="bool" setter="set_avoidance_enabled" getter="get_avoidance_enabled" default="false">
+			If [code]true[/code] the agent is registered for an RVO avoidance callback on the [Navigation2DServer]. When [method set_velocity] is used and the processing is completed a [code]safe_velocity[/code] Vector2 is received with a signal connection to [signal velocity_computed]. Avoidance processing with many registered agents has a significant performance cost and should only be enabled on agents that currently require it.
+		</member>
 		<member name="max_neighbors" type="int" setter="set_max_neighbors" getter="get_max_neighbors" default="10">
 		<member name="max_neighbors" type="int" setter="set_max_neighbors" getter="get_max_neighbors" default="10">
 			The maximum number of neighbors for the agent to consider.
 			The maximum number of neighbors for the agent to consider.
 		</member>
 		</member>

+ 6 - 6
doc/classes/NavigationMesh.xml

@@ -74,25 +74,25 @@
 		</method>
 		</method>
 	</methods>
 	</methods>
 	<members>
 	<members>
-		<member name="agent/height" type="float" setter="set_agent_height" getter="get_agent_height" default="2.0">
+		<member name="agent/height" type="float" setter="set_agent_height" getter="get_agent_height" default="1.5">
 			The minimum floor to ceiling height that will still allow the floor area to be considered walkable.
 			The minimum floor to ceiling height that will still allow the floor area to be considered walkable.
 			[b]Note:[/b] While baking, this value will be rounded up to the nearest multiple of [member cell/height].
 			[b]Note:[/b] While baking, this value will be rounded up to the nearest multiple of [member cell/height].
 		</member>
 		</member>
-		<member name="agent/max_climb" type="float" setter="set_agent_max_climb" getter="get_agent_max_climb" default="0.9">
+		<member name="agent/max_climb" type="float" setter="set_agent_max_climb" getter="get_agent_max_climb" default="0.25">
 			The minimum ledge height that is considered to still be traversable.
 			The minimum ledge height that is considered to still be traversable.
 			[b]Note:[/b] While baking, this value will be rounded down to the nearest multiple of [member cell/height].
 			[b]Note:[/b] While baking, this value will be rounded down to the nearest multiple of [member cell/height].
 		</member>
 		</member>
 		<member name="agent/max_slope" type="float" setter="set_agent_max_slope" getter="get_agent_max_slope" default="45.0">
 		<member name="agent/max_slope" type="float" setter="set_agent_max_slope" getter="get_agent_max_slope" default="45.0">
 			The maximum slope that is considered walkable, in degrees.
 			The maximum slope that is considered walkable, in degrees.
 		</member>
 		</member>
-		<member name="agent/radius" type="float" setter="set_agent_radius" getter="get_agent_radius" default="0.6">
+		<member name="agent/radius" type="float" setter="set_agent_radius" getter="get_agent_radius" default="0.5">
 			The distance to erode/shrink the walkable area of the heightfield away from obstructions.
 			The distance to erode/shrink the walkable area of the heightfield away from obstructions.
 			[b]Note:[/b] While baking, this value will be rounded up to the nearest multiple of [member cell/size].
 			[b]Note:[/b] While baking, this value will be rounded up to the nearest multiple of [member cell/size].
 		</member>
 		</member>
-		<member name="cell/height" type="float" setter="set_cell_height" getter="get_cell_height" default="0.2">
+		<member name="cell/height" type="float" setter="set_cell_height" getter="get_cell_height" default="0.25">
 			The Y axis cell size to use for fields.
 			The Y axis cell size to use for fields.
 		</member>
 		</member>
-		<member name="cell/size" type="float" setter="set_cell_size" getter="get_cell_size" default="0.3">
+		<member name="cell/size" type="float" setter="set_cell_size" getter="get_cell_size" default="0.25">
 			The XZ plane cell size to use for fields.
 			The XZ plane cell size to use for fields.
 		</member>
 		</member>
 		<member name="detail/sample_distance" type="float" setter="set_detail_sample_distance" getter="get_detail_sample_distance" default="6.0">
 		<member name="detail/sample_distance" type="float" setter="set_detail_sample_distance" getter="get_detail_sample_distance" default="6.0">
@@ -138,7 +138,7 @@
 			Any regions with a size smaller than this will be merged with larger regions if possible.
 			Any regions with a size smaller than this will be merged with larger regions if possible.
 			[b]Note:[/b] This value will be squared to calculate the number of cells. For example, a value of 20 will set the number of cells to 400.
 			[b]Note:[/b] This value will be squared to calculate the number of cells. For example, a value of 20 will set the number of cells to 400.
 		</member>
 		</member>
-		<member name="region/min_size" type="float" setter="set_region_min_size" getter="get_region_min_size" default="8.0">
+		<member name="region/min_size" type="float" setter="set_region_min_size" getter="get_region_min_size" default="2.0">
 			The minimum size of a region for it to be created.
 			The minimum size of a region for it to be created.
 			[b]Note:[/b] This value will be squared to calculate the minimum number of cells allowed to form isolated island areas. For example, a value of 8 will set the number of cells to 64.
 			[b]Note:[/b] This value will be squared to calculate the minimum number of cells allowed to form isolated island areas. For example, a value of 8 will set the number of cells to 64.
 		</member>
 		</member>

+ 7 - 2
editor/editor_properties_array_dict.cpp

@@ -618,11 +618,16 @@ void EditorPropertyArray::_reorder_button_gui_input(const Ref<InputEvent> &p_eve
 		Variant array = object->get_array();
 		Variant array = object->get_array();
 		int size = array.call("size");
 		int size = array.call("size");
 
 
-		if ((reorder_to_index == 0 && mm->get_relative().y < 0.0f) || (reorder_to_index == size - 1 && mm->get_relative().y > 0.0f)) {
+		// Cumulate the mouse delta, many small changes (dragging slowly) should result in reordering at some point.
+		reorder_mouse_y_delta += mm->get_relative().y;
+
+		// Reordering is done by moving the dragged element by +1/-1 index at a time based on the cumulated mouse delta so if
+		// already at the array bounds make sure to ignore the remaining out of bounds drag (by resetting the cumulated delta).
+		if ((reorder_to_index == 0 && reorder_mouse_y_delta < 0.0f) || (reorder_to_index == size - 1 && reorder_mouse_y_delta > 0.0f)) {
+			reorder_mouse_y_delta = 0.0f;
 			return;
 			return;
 		}
 		}
 
 
-		reorder_mouse_y_delta += mm->get_relative().y;
 		float required_y_distance = 20.0f * EDSCALE;
 		float required_y_distance = 20.0f * EDSCALE;
 		if (ABS(reorder_mouse_y_delta) > required_y_distance) {
 		if (ABS(reorder_mouse_y_delta) > required_y_distance) {
 			int direction = reorder_mouse_y_delta > 0.0f ? 1 : -1;
 			int direction = reorder_mouse_y_delta > 0.0f ? 1 : -1;

+ 5 - 3
modules/csg/csg_gizmos.cpp

@@ -379,9 +379,11 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
 
 
 	if (cs->is_root_shape()) {
 	if (cs->is_root_shape()) {
 		Array csg_meshes = cs->get_meshes();
 		Array csg_meshes = cs->get_meshes();
-		Ref<Mesh> csg_mesh = csg_meshes[1];
-		if (csg_mesh.is_valid()) {
-			p_gizmo->add_collision_triangles(csg_mesh->generate_triangle_mesh());
+		if (csg_meshes.size() == 2) {
+			Ref<Mesh> csg_mesh = csg_meshes[1];
+			if (csg_mesh.is_valid()) {
+				p_gizmo->add_collision_triangles(csg_mesh->generate_triangle_mesh());
+			}
 		}
 		}
 	}
 	}
 
 

+ 20 - 2
scene/2d/navigation_agent_2d.cpp

@@ -37,6 +37,9 @@
 void NavigationAgent2D::_bind_methods() {
 void NavigationAgent2D::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_rid"), &NavigationAgent2D::get_rid);
 	ClassDB::bind_method(D_METHOD("get_rid"), &NavigationAgent2D::get_rid);
 
 
+	ClassDB::bind_method(D_METHOD("set_avoidance_enabled", "enabled"), &NavigationAgent2D::set_avoidance_enabled);
+	ClassDB::bind_method(D_METHOD("get_avoidance_enabled"), &NavigationAgent2D::get_avoidance_enabled);
+
 	ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent2D::set_target_desired_distance);
 	ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent2D::set_target_desired_distance);
 	ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent2D::get_target_desired_distance);
 	ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent2D::get_target_desired_distance);
 
 
@@ -82,6 +85,7 @@ void NavigationAgent2D::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_time_horizon", "get_time_horizon");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_time_horizon", "get_time_horizon");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.1,100000,0.01"), "set_max_speed", "get_max_speed");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.1,100000,0.01"), "set_max_speed", "get_max_speed");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1"), "set_path_max_distance", "get_path_max_distance");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1"), "set_path_max_distance", "get_path_max_distance");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
 
 
 	ADD_SIGNAL(MethodInfo("path_changed"));
 	ADD_SIGNAL(MethodInfo("path_changed"));
 	ADD_SIGNAL(MethodInfo("target_reached"));
 	ADD_SIGNAL(MethodInfo("target_reached"));
@@ -94,7 +98,7 @@ void NavigationAgent2D::_notification(int p_what) {
 		case NOTIFICATION_READY: {
 		case NOTIFICATION_READY: {
 			agent_parent = Object::cast_to<Node2D>(get_parent());
 			agent_parent = Object::cast_to<Node2D>(get_parent());
 
 
-			Navigation2DServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+			set_avoidance_enabled(avoidance_enabled);
 
 
 			// Search the navigation node and set it
 			// Search the navigation node and set it
 			{
 			{
@@ -153,6 +157,7 @@ NavigationAgent2D::NavigationAgent2D() :
 		agent_parent(nullptr),
 		agent_parent(nullptr),
 		navigation(nullptr),
 		navigation(nullptr),
 		agent(RID()),
 		agent(RID()),
+		avoidance_enabled(false),
 		target_desired_distance(1.0),
 		target_desired_distance(1.0),
 		path_max_distance(3.0),
 		path_max_distance(3.0),
 		velocity_submitted(false),
 		velocity_submitted(false),
@@ -171,6 +176,19 @@ NavigationAgent2D::~NavigationAgent2D() {
 	agent = RID(); // Pointless
 	agent = RID(); // Pointless
 }
 }
 
 
+void NavigationAgent2D::set_avoidance_enabled(bool p_enabled) {
+	avoidance_enabled = p_enabled;
+	if (avoidance_enabled) {
+		Navigation2DServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+	} else {
+		Navigation2DServer::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done");
+	}
+}
+
+bool NavigationAgent2D::get_avoidance_enabled() const {
+	return avoidance_enabled;
+}
+
 void NavigationAgent2D::set_navigation(Navigation2D *p_nav) {
 void NavigationAgent2D::set_navigation(Navigation2D *p_nav) {
 	if (navigation == p_nav) {
 	if (navigation == p_nav) {
 		return; // Pointless
 		return; // Pointless
@@ -297,7 +315,7 @@ void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) {
 
 
 String NavigationAgent2D::get_configuration_warning() const {
 String NavigationAgent2D::get_configuration_warning() const {
 	if (!Object::cast_to<Node2D>(get_parent())) {
 	if (!Object::cast_to<Node2D>(get_parent())) {
-		return TTR("The NavigationAgent2D can be used only under a Node2D node.");
+		return TTR("The NavigationAgent2D can be used only under a Node2D inheriting parent node.");
 	}
 	}
 
 
 	return String();
 	return String();

+ 5 - 0
scene/2d/navigation_agent_2d.h

@@ -46,6 +46,8 @@ class NavigationAgent2D : public Node {
 	RID agent;
 	RID agent;
 	RID map_before_pause;
 	RID map_before_pause;
 
 
+	bool avoidance_enabled;
+
 	real_t target_desired_distance;
 	real_t target_desired_distance;
 	real_t radius;
 	real_t radius;
 	real_t neighbor_dist;
 	real_t neighbor_dist;
@@ -87,6 +89,9 @@ public:
 		return agent;
 		return agent;
 	}
 	}
 
 
+	void set_avoidance_enabled(bool p_enabled);
+	bool get_avoidance_enabled() const;
+
 	void set_target_desired_distance(real_t p_dd);
 	void set_target_desired_distance(real_t p_dd);
 	real_t get_target_desired_distance() const {
 	real_t get_target_desired_distance() const {
 		return target_desired_distance;
 		return target_desired_distance;

+ 20 - 2
scene/3d/navigation_agent.cpp

@@ -37,6 +37,9 @@
 void NavigationAgent::_bind_methods() {
 void NavigationAgent::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_rid"), &NavigationAgent::get_rid);
 	ClassDB::bind_method(D_METHOD("get_rid"), &NavigationAgent::get_rid);
 
 
+	ClassDB::bind_method(D_METHOD("set_avoidance_enabled", "enabled"), &NavigationAgent::set_avoidance_enabled);
+	ClassDB::bind_method(D_METHOD("get_avoidance_enabled"), &NavigationAgent::get_avoidance_enabled);
+
 	ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent::set_target_desired_distance);
 	ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent::set_target_desired_distance);
 	ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent::get_target_desired_distance);
 	ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent::get_target_desired_distance);
 
 
@@ -90,6 +93,7 @@ void NavigationAgent::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_max_speed", "get_max_speed");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_max_speed", "get_max_speed");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1"), "set_path_max_distance", "get_path_max_distance");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1"), "set_path_max_distance", "get_path_max_distance");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_y"), "set_ignore_y", "get_ignore_y");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_y"), "set_ignore_y", "get_ignore_y");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
 
 
 	ADD_SIGNAL(MethodInfo("path_changed"));
 	ADD_SIGNAL(MethodInfo("path_changed"));
 	ADD_SIGNAL(MethodInfo("target_reached"));
 	ADD_SIGNAL(MethodInfo("target_reached"));
@@ -102,7 +106,7 @@ void NavigationAgent::_notification(int p_what) {
 		case NOTIFICATION_READY: {
 		case NOTIFICATION_READY: {
 			agent_parent = Object::cast_to<Spatial>(get_parent());
 			agent_parent = Object::cast_to<Spatial>(get_parent());
 
 
-			NavigationServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+			set_avoidance_enabled(avoidance_enabled);
 
 
 			// Search the navigation node and set it
 			// Search the navigation node and set it
 			{
 			{
@@ -161,6 +165,7 @@ NavigationAgent::NavigationAgent() :
 		agent_parent(nullptr),
 		agent_parent(nullptr),
 		navigation(nullptr),
 		navigation(nullptr),
 		agent(RID()),
 		agent(RID()),
+		avoidance_enabled(false),
 		target_desired_distance(1.0),
 		target_desired_distance(1.0),
 		navigation_height_offset(0.0),
 		navigation_height_offset(0.0),
 		path_max_distance(3.0),
 		path_max_distance(3.0),
@@ -181,6 +186,19 @@ NavigationAgent::~NavigationAgent() {
 	agent = RID(); // Pointless
 	agent = RID(); // Pointless
 }
 }
 
 
+void NavigationAgent::set_avoidance_enabled(bool p_enabled) {
+	avoidance_enabled = p_enabled;
+	if (avoidance_enabled) {
+		NavigationServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+	} else {
+		NavigationServer::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done");
+	}
+}
+
+bool NavigationAgent::get_avoidance_enabled() const {
+	return avoidance_enabled;
+}
+
 void NavigationAgent::set_navigation(Navigation *p_nav) {
 void NavigationAgent::set_navigation(Navigation *p_nav) {
 	if (navigation == p_nav) {
 	if (navigation == p_nav) {
 		return; // Pointless
 		return; // Pointless
@@ -315,7 +333,7 @@ void NavigationAgent::_avoidance_done(Vector3 p_new_velocity) {
 
 
 String NavigationAgent::get_configuration_warning() const {
 String NavigationAgent::get_configuration_warning() const {
 	if (!Object::cast_to<Spatial>(get_parent())) {
 	if (!Object::cast_to<Spatial>(get_parent())) {
-		return TTR("The NavigationAgent can be used only under a spatial node.");
+		return TTR("The NavigationAgent can be used only under a Spatial inheriting parent node.");
 	}
 	}
 
 
 	return String();
 	return String();

+ 5 - 0
scene/3d/navigation_agent.h

@@ -46,6 +46,8 @@ class NavigationAgent : public Node {
 	RID agent;
 	RID agent;
 	RID map_before_pause;
 	RID map_before_pause;
 
 
+	bool avoidance_enabled;
+
 	real_t target_desired_distance;
 	real_t target_desired_distance;
 	real_t radius;
 	real_t radius;
 	real_t navigation_height_offset;
 	real_t navigation_height_offset;
@@ -89,6 +91,9 @@ public:
 		return agent;
 		return agent;
 	}
 	}
 
 
+	void set_avoidance_enabled(bool p_enabled);
+	bool get_avoidance_enabled() const;
+
 	void set_target_desired_distance(real_t p_dd);
 	void set_target_desired_distance(real_t p_dd);
 	real_t get_target_desired_distance() const {
 	real_t get_target_desired_distance() const {
 		return target_desired_distance;
 		return target_desired_distance;

+ 1 - 0
scene/gui/control.cpp

@@ -652,6 +652,7 @@ void Control::_notification(int p_notification) {
 				//remove modalness
 				//remove modalness
 			} else {
 			} else {
 				data.minimum_size_valid = false;
 				data.minimum_size_valid = false;
+				_update_minimum_size();
 				_size_changed();
 				_size_changed();
 			}
 			}
 
 

+ 1 - 1
scene/gui/rich_text_label.cpp

@@ -1233,7 +1233,7 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
 				}
 				}
 				selection.click = nullptr;
 				selection.click = nullptr;
 
 
-				if (!b->is_doubleclick() && !scroll_updated) {
+				if (!b->is_doubleclick() && !scroll_updated && !selection.active) {
 					int line = 0;
 					int line = 0;
 					Item *item = nullptr;
 					Item *item = nullptr;
 
 

+ 1 - 1
scene/resources/default_theme/default_theme.cpp

@@ -784,7 +784,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
 	theme->set_icon("file", "FileDialog", make_icon(icon_file_png));
 	theme->set_icon("file", "FileDialog", make_icon(icon_file_png));
 	theme->set_color("folder_icon_modulate", "FileDialog", Color(1, 1, 1));
 	theme->set_color("folder_icon_modulate", "FileDialog", Color(1, 1, 1));
 	theme->set_color("file_icon_modulate", "FileDialog", Color(1, 1, 1));
 	theme->set_color("file_icon_modulate", "FileDialog", Color(1, 1, 1));
-	theme->set_color("files_disabled", "FileDialog", Color(0, 0, 0, 0.7));
+	theme->set_color("files_disabled", "FileDialog", Color(1, 1, 1, 0.25));
 
 
 	// ColorPicker
 	// ColorPicker
 
 

+ 12 - 12
scene/resources/navigation_mesh.cpp

@@ -485,12 +485,12 @@ void NavigationMesh::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/source_geometry_mode", PROPERTY_HINT_ENUM, "Navmesh Children, Group With Children, Group Explicit"), "set_source_geometry_mode", "get_source_geometry_mode");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/source_geometry_mode", PROPERTY_HINT_ENUM, "Navmesh Children, Group With Children, Group Explicit"), "set_source_geometry_mode", "get_source_geometry_mode");
 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry/source_group_name"), "set_source_group_name", "get_source_group_name");
 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry/source_group_name"), "set_source_group_name", "get_source_group_name");
 
 
-	ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/size", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_size", "get_cell_size");
-	ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/height", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_height", "get_cell_height");
-	ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/height", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_height", "get_agent_height");
-	ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/radius", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_radius", "get_agent_radius");
-	ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/max_climb", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_max_climb", "get_agent_max_climb");
-	ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/max_slope", PROPERTY_HINT_RANGE, "0.0,90.0,0.1"), "set_agent_max_slope", "get_agent_max_slope");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/size", PROPERTY_HINT_RANGE, "0.01,500.0,0.01,or_greater"), "set_cell_size", "get_cell_size");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/height", PROPERTY_HINT_RANGE, "0.01,500.0,0.01,or_greater"), "set_cell_height", "get_cell_height");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/height", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater"), "set_agent_height", "get_agent_height");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/radius", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater"), "set_agent_radius", "get_agent_radius");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/max_climb", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater"), "set_agent_max_climb", "get_agent_max_climb");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/max_slope", PROPERTY_HINT_RANGE, "0.02,90.0,0.01"), "set_agent_max_slope", "get_agent_max_slope");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "region/min_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_min_size", "get_region_min_size");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "region/min_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_min_size", "get_region_min_size");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "region/merge_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_merge_size", "get_region_merge_size");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "region/merge_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_merge_size", "get_region_merge_size");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge/max_length", PROPERTY_HINT_RANGE, "0.0,50.0,0.01,or_greater"), "set_edge_max_length", "get_edge_max_length");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge/max_length", PROPERTY_HINT_RANGE, "0.0,50.0,0.01,or_greater"), "set_edge_max_length", "get_edge_max_length");
@@ -536,13 +536,13 @@ void NavigationMesh::_validate_property(PropertyInfo &property) const {
 }
 }
 
 
 NavigationMesh::NavigationMesh() {
 NavigationMesh::NavigationMesh() {
-	cell_size = 0.3f;
-	cell_height = 0.2f;
-	agent_height = 2.0f;
-	agent_radius = 0.6f;
-	agent_max_climb = 0.9f;
+	cell_size = 0.25f;
+	cell_height = 0.25f;
+	agent_height = 1.5f;
+	agent_radius = 0.5f;
+	agent_max_climb = 0.25f;
 	agent_max_slope = 45.0f;
 	agent_max_slope = 45.0f;
-	region_min_size = 8.0f;
+	region_min_size = 2.0f;
 	region_merge_size = 20.0f;
 	region_merge_size = 20.0f;
 	edge_max_length = 12.0f;
 	edge_max_length = 12.0f;
 	edge_max_error = 1.3f;
 	edge_max_error = 1.3f;