summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/bullet/SCsub6
-rw-r--r--modules/bullet/bullet_physics_server.cpp2
-rw-r--r--modules/bullet/cone_twist_joint_bullet.cpp2
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.cpp4
-rw-r--r--modules/bullet/hinge_joint_bullet.cpp2
-rw-r--r--modules/bullet/pin_joint_bullet.cpp2
-rw-r--r--modules/csg/csg.cpp2
-rw-r--r--modules/dds/texture_loader_dds.cpp25
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp4
-rw-r--r--modules/gdnative/gdnative/dictionary.cpp9
-rw-r--r--modules/gdnative/gdnative/vector2.cpp8
-rw-r--r--modules/gdnative/gdnative/vector3.cpp8
-rw-r--r--modules/gdnative/gdnative_api.json37
-rw-r--r--modules/gdnative/include/gdnative/dictionary.h2
-rw-r--r--modules/gdnative/include/gdnative/vector2.h2
-rw-r--r--modules/gdnative/include/gdnative/vector3.h2
-rw-r--r--modules/gdnative/include/pluginscript/godot_pluginscript.h2
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.cpp4
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.h2
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.cpp12
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp19
-rw-r--r--modules/gdscript/gdscript.h4
-rw-r--r--modules/gdscript/gdscript_compiler.cpp8
-rw-r--r--modules/gdscript/gdscript_editor.cpp16
-rw-r--r--modules/gdscript/gdscript_functions.cpp16
-rw-r--r--modules/gdscript/gdscript_functions.h1
-rw-r--r--modules/gdscript/gdscript_parser.cpp68
-rw-r--r--modules/gdscript/gdscript_parser.h2
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp27
-rw-r--r--modules/gridmap/grid_map.cpp4
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp7
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h1
-rw-r--r--modules/mono/SCsub5
-rw-r--r--modules/mono/build_scripts/godotsharptools_build.py35
-rw-r--r--modules/mono/build_scripts/mono_configure.py133
-rw-r--r--modules/mono/build_scripts/patches/fix-mono-android-tkill.diff70
-rw-r--r--modules/mono/config.py10
-rw-r--r--modules/mono/csharp_script.cpp28
-rw-r--r--modules/mono/csharp_script.h3
-rw-r--r--modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs4
-rw-r--r--modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs3
-rw-r--r--modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs5
-rw-r--r--modules/mono/editor/bindings_generator.cpp16
-rw-r--r--modules/mono/editor/bindings_generator.h4
-rw-r--r--modules/mono/editor/godotsharp_builds.cpp31
-rw-r--r--modules/mono/editor/godotsharp_builds.h2
-rw-r--r--modules/mono/editor/godotsharp_export.cpp29
-rw-r--r--modules/mono/editor/mono_bottom_panel.cpp5
-rw-r--r--modules/mono/glue/Managed/Files/AABB.cs15
-rw-r--r--modules/mono/glue/Managed/Files/Basis.cs73
-rw-r--r--modules/mono/glue/Managed/Files/Mathf.cs9
-rw-r--r--modules/mono/glue/Managed/Files/Transform2D.cs1
-rw-r--r--modules/mono/glue/Managed/Files/Vector2.cs8
-rw-r--r--modules/mono/glue/Managed/Files/Vector3.cs8
-rw-r--r--modules/mono/glue/base_object_glue.cpp2
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp13
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp14
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp2
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp2
-rw-r--r--modules/mono/mono_gd/gd_mono_property.cpp2
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp26
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h18
-rw-r--r--modules/mono/signal_awaiter_utils.cpp2
-rw-r--r--modules/opus/audio_stream_opus.cpp2
-rw-r--r--modules/recast/navigation_mesh_editor_plugin.cpp8
-rw-r--r--modules/recast/navigation_mesh_generator.cpp166
-rw-r--r--modules/recast/navigation_mesh_generator.h24
-rw-r--r--modules/recast/register_types.cpp17
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp1
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp4
-rw-r--r--modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml75
-rw-r--r--modules/visual_script/visual_script.cpp15
-rw-r--r--modules/visual_script/visual_script.h1
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp20
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.h1
-rw-r--r--modules/visual_script/visual_script_editor.cpp151
-rw-r--r--modules/visual_script/visual_script_editor.h1
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.cpp3
-rw-r--r--modules/webm/video_stream_webm.cpp7
80 files changed, 990 insertions, 396 deletions
diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub
index 16d694c238..2fe7a1b4c0 100644
--- a/modules/bullet/SCsub
+++ b/modules/bullet/SCsub
@@ -186,7 +186,11 @@ if env['builtin_bullet']:
thirdparty_sources = [thirdparty_dir + file for file in bullet2_src]
- env_bullet.Prepend(CPPPATH=[thirdparty_dir])
+ # Treat Bullet headers as system headers to avoid raising warnings. Not supported on MSVC.
+ if not env.msvc:
+ env_bullet.Append(CPPFLAGS=['-isystem', Dir(thirdparty_dir).path])
+ else:
+ env_bullet.Prepend(CPPPATH=[thirdparty_dir])
# if env['target'] == "debug" or env['target'] == "release_debug":
# env_bullet.Append(CPPFLAGS=['-DBT_DEBUG'])
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index be4e0b88e8..038001996d 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -267,7 +267,7 @@ RID BulletPhysicsServer::area_get_space(RID p_area) const {
void BulletPhysicsServer::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) {
AreaBullet *area = area_owner.get(p_area);
- ERR_FAIL_COND(!area)
+ ERR_FAIL_COND(!area);
area->set_spOv_mode(p_mode);
}
diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp
index d9a82d6179..bc7fd52cf6 100644
--- a/modules/bullet/cone_twist_joint_bullet.cpp
+++ b/modules/bullet/cone_twist_joint_bullet.cpp
@@ -84,7 +84,7 @@ void ConeTwistJointBullet::set_param(PhysicsServer::ConeTwistJointParam p_param,
break;
default:
ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED
+ WARN_DEPRECATED;
break;
}
}
diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp
index 8fed933854..0d2c46c579 100644
--- a/modules/bullet/generic_6dof_joint_bullet.cpp
+++ b/modules/bullet/generic_6dof_joint_bullet.cpp
@@ -175,7 +175,7 @@ void Generic6DOFJointBullet::set_param(Vector3::Axis p_axis, PhysicsServer::G6DO
break;
default:
ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED
+ WARN_DEPRECATED;
break;
}
}
@@ -256,7 +256,7 @@ void Generic6DOFJointBullet::set_flag(Vector3::Axis p_axis, PhysicsServer::G6DOF
break;
default:
ERR_EXPLAIN("This flag " + itos(p_flag) + " is deprecated");
- WARN_DEPRECATED
+ WARN_DEPRECATED;
break;
}
}
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp
index 7b99d3d89f..b7e1e1a4c2 100644
--- a/modules/bullet/hinge_joint_bullet.cpp
+++ b/modules/bullet/hinge_joint_bullet.cpp
@@ -118,7 +118,7 @@ void HingeJointBullet::set_param(PhysicsServer::HingeJointParam p_param, real_t
break;
default:
ERR_EXPLAIN("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
- WARN_DEPRECATED
+ WARN_DEPRECATED;
break;
}
}
diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp
index 58b090006a..c9c4d1af7e 100644
--- a/modules/bullet/pin_joint_bullet.cpp
+++ b/modules/bullet/pin_joint_bullet.cpp
@@ -86,7 +86,7 @@ real_t PinJointBullet::get_param(PhysicsServer::PinJointParam p_param) const {
return p2pConstraint->m_setting.m_impulseClamp;
default:
ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED
+ WARN_DEPRECATED;
return 0;
}
}
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index 3a61afa023..aa4d7d7d32 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -45,7 +45,7 @@ void CSGBrush::build_from_faces(const PoolVector<Vector3> &p_vertices, const Poo
int vc = p_vertices.size();
- ERR_FAIL_COND((vc % 3) != 0)
+ ERR_FAIL_COND((vc % 3) != 0);
PoolVector<Vector3>::Read rv = p_vertices.read();
int uvc = p_uvs.size();
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index 059c06c37c..50fdc8ab20 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -31,6 +31,8 @@
#include "texture_loader_dds.h"
#include "core/os/file_access.h"
+#define PF_FOURCC(s) (((s)[3] << 24U) | ((s)[2] << 16U) | ((s)[1] << 8U) | ((s)[0]))
+
enum {
DDS_MAGIC = 0x20534444,
DDSD_CAPS = 0x00000001,
@@ -51,6 +53,7 @@ enum DDSFormat {
DDS_DXT5,
DDS_ATI1,
DDS_ATI2,
+ DDS_A2XY,
DDS_BGRA8,
DDS_BGR8,
DDS_RGBA8, //flipped in dds
@@ -74,9 +77,12 @@ struct DDSFormatInfo {
};
static const DDSFormatInfo dds_format_info[DDS_MAX] = {
- { "DXT1", true, false, 4, 8, Image::FORMAT_DXT1 },
- { "DXT3", true, false, 4, 16, Image::FORMAT_DXT3 },
- { "DXT5", true, false, 4, 16, Image::FORMAT_DXT5 },
+ { "DXT1/BC1", true, false, 4, 8, Image::FORMAT_DXT1 },
+ { "DXT3/BC2", true, false, 4, 16, Image::FORMAT_DXT3 },
+ { "DXT5/BC3", true, false, 4, 16, Image::FORMAT_DXT5 },
+ { "ATI1/BC4", true, false, 4, 8, Image::FORMAT_RGTC_R },
+ { "ATI2/3DC/BC5", true, false, 4, 16, Image::FORMAT_RGTC_RG },
+ { "A2XY/DXN/BC5", true, false, 4, 16, Image::FORMAT_RGTC_RG },
{ "BGRA8", false, false, 1, 4, Image::FORMAT_RGBA8 },
{ "BGR8", false, false, 1, 3, Image::FORMAT_RGB8 },
{ "RGBA8", false, false, 1, 4, Image::FORMAT_RGBA8 },
@@ -158,22 +164,25 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
DDSFormat dds_format;
- if (format_flags & DDPF_FOURCC && format_fourcc == 0x31545844) { //'1TXD'
+ if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("DXT1")) {
dds_format = DDS_DXT1;
- } else if (format_flags & DDPF_FOURCC && format_fourcc == 0x33545844) { //'3TXD'
+ } else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("DXT3")) {
dds_format = DDS_DXT3;
- } else if (format_flags & DDPF_FOURCC && format_fourcc == 0x35545844) { //'5TXD'
+ } else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("DXT5")) {
dds_format = DDS_DXT5;
- } else if (format_flags & DDPF_FOURCC && format_fourcc == 0x31495441) { //'1ITA'
+ } else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("ATI1")) {
dds_format = DDS_ATI1;
- } else if (format_flags & DDPF_FOURCC && format_fourcc == 0x32495441) { //'2ITA'
+ } else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("ATI2")) {
dds_format = DDS_ATI2;
+ } else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("A2XY")) {
+
+ dds_format = DDS_A2XY;
} else if (format_flags & DDPF_RGB && format_flags & DDPF_ALPHAPIXELS && format_rgb_bits == 32 && format_red_mask == 0xff0000 && format_green_mask == 0xff00 && format_blue_mask == 0xff && format_alpha_mask == 0xff000000) {
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index 18dfe08e85..1ff0395ba9 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/networked_multiplayer_enet.cpp
@@ -346,7 +346,7 @@ void NetworkedMultiplayerENet::poll() {
uint32_t *id = (uint32_t *)event.peer->data;
- ERR_CONTINUE(event.packet->dataLength < 8)
+ ERR_CONTINUE(event.packet->dataLength < 8);
uint32_t source = decode_uint32(&event.packet->data[0]);
int target = decode_uint32(&event.packet->data[4]);
@@ -462,7 +462,7 @@ void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
ERR_FAIL_COND(!active);
ERR_FAIL_COND(!is_server());
- ERR_FAIL_COND(!peer_map.has(p_peer))
+ ERR_FAIL_COND(!peer_map.has(p_peer));
if (now) {
enet_peer_disconnect_now(peer_map[p_peer], 0);
diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp
index 2c6c9e2de2..fff3fc3625 100644
--- a/modules/gdnative/gdnative/dictionary.cpp
+++ b/modules/gdnative/gdnative/dictionary.cpp
@@ -55,6 +55,15 @@ void GDAPI godot_dictionary_destroy(godot_dictionary *p_self) {
self->~Dictionary();
}
+godot_dictionary GDAPI godot_dictionary_duplicate(const godot_dictionary *p_self, const godot_bool p_deep) {
+ const Dictionary *self = (const Dictionary *)p_self;
+ godot_dictionary res;
+ Dictionary *val = (Dictionary *)&res;
+ memnew_placement(val, Dictionary);
+ *val = self->duplicate(p_deep);
+ return res;
+}
+
godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_self) {
const Dictionary *self = (const Dictionary *)p_self;
return self->size();
diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp
index 8fa29580d6..a2ac61b35e 100644
--- a/modules/gdnative/gdnative/vector2.cpp
+++ b/modules/gdnative/gdnative/vector2.cpp
@@ -119,6 +119,14 @@ godot_vector2 GDAPI godot_vector2_cubic_interpolate(const godot_vector2 *p_self,
return dest;
}
+godot_vector2 GDAPI godot_vector2_move_toward(const godot_vector2 *p_self, const godot_vector2 *p_to, const godot_real p_delta) {
+ godot_vector2 dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *to = (const Vector2 *)p_to;
+ *((Vector2 *)&dest) = self->move_toward(*to, p_delta);
+ return dest;
+}
+
godot_vector2 GDAPI godot_vector2_rotated(const godot_vector2 *p_self, const godot_real p_phi) {
godot_vector2 dest;
const Vector2 *self = (const Vector2 *)p_self;
diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp
index ef86c6f7e9..894683ab38 100644
--- a/modules/gdnative/gdnative/vector3.cpp
+++ b/modules/gdnative/gdnative/vector3.cpp
@@ -124,6 +124,14 @@ godot_vector3 GDAPI godot_vector3_cubic_interpolate(const godot_vector3 *p_self,
return dest;
}
+godot_vector3 GDAPI godot_vector3_move_toward(const godot_vector3 *p_self, const godot_vector3 *p_to, const godot_real p_delta) {
+ godot_vector3 dest;
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *to = (const Vector3 *)p_to;
+ *((Vector3 *)&dest) = self->move_toward(*to, p_delta);
+ return dest;
+}
+
godot_real GDAPI godot_vector3_dot(const godot_vector3 *p_self, const godot_vector3 *p_b) {
const Vector3 *self = (const Vector3 *)p_self;
const Vector3 *b = (const Vector3 *)p_b;
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 93f4d75330..52c989037e 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -11,7 +11,42 @@
"major": 1,
"minor": 1
},
- "next": null,
+ "next": {
+ "type": "CORE",
+ "version": {
+ "major": 1,
+ "minor": 2
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_dictionary_duplicate",
+ "return_type": "godot_dictionary",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"],
+ ["const godot_bool", "p_deep"]
+ ]
+ },
+ {
+ "name": "godot_vector3_move_toward",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_to"],
+ ["const godot_real", "p_delta"]
+ ]
+ },
+ {
+ "name": "godot_vector2_move_toward",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_to"],
+ ["const godot_real", "p_delta"]
+ ]
+ }
+ ]
+ },
"api": [
{
"name": "godot_color_to_abgr32",
diff --git a/modules/gdnative/include/gdnative/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h
index 14e35b4692..483cd9c4e3 100644
--- a/modules/gdnative/include/gdnative/dictionary.h
+++ b/modules/gdnative/include/gdnative/dictionary.h
@@ -63,6 +63,8 @@ void GDAPI godot_dictionary_new(godot_dictionary *r_dest);
void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src);
void GDAPI godot_dictionary_destroy(godot_dictionary *p_self);
+godot_dictionary GDAPI godot_dictionary_duplicate(const godot_dictionary *p_self, const godot_bool p_deep);
+
godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_self);
godot_bool GDAPI godot_dictionary_empty(const godot_dictionary *p_self);
diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h
index 9e37b8e0c6..7a5ae6afa9 100644
--- a/modules/gdnative/include/gdnative/vector2.h
+++ b/modules/gdnative/include/gdnative/vector2.h
@@ -83,6 +83,8 @@ godot_vector2 GDAPI godot_vector2_linear_interpolate(const godot_vector2 *p_self
godot_vector2 GDAPI godot_vector2_cubic_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_vector2 *p_pre_a, const godot_vector2 *p_post_b, const godot_real p_t);
+godot_vector2 GDAPI godot_vector2_move_toward(const godot_vector2 *p_self, const godot_vector2 *p_to, const godot_real p_delta);
+
godot_vector2 GDAPI godot_vector2_rotated(const godot_vector2 *p_self, const godot_real p_phi);
godot_vector2 GDAPI godot_vector2_tangent(const godot_vector2 *p_self);
diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h
index 61f0c6c62e..70ec6422ac 100644
--- a/modules/gdnative/include/gdnative/vector3.h
+++ b/modules/gdnative/include/gdnative/vector3.h
@@ -90,6 +90,8 @@ godot_vector3 GDAPI godot_vector3_linear_interpolate(const godot_vector3 *p_self
godot_vector3 GDAPI godot_vector3_cubic_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_vector3 *p_pre_a, const godot_vector3 *p_post_b, const godot_real p_t);
+godot_vector3 GDAPI godot_vector3_move_toward(const godot_vector3 *p_self, const godot_vector3 *p_to, const godot_real p_delta);
+
godot_real GDAPI godot_vector3_dot(const godot_vector3 *p_self, const godot_vector3 *p_b);
godot_vector3 GDAPI godot_vector3_cross(const godot_vector3 *p_self, const godot_vector3 *p_b);
diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h
index 968f91ae9f..a9e83d1524 100644
--- a/modules/gdnative/include/pluginscript/godot_pluginscript.h
+++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h
@@ -136,7 +136,7 @@ typedef struct {
godot_bool (*validate)(godot_pluginscript_language_data *p_data, const godot_string *p_script, int *r_line_error, int *r_col_error, godot_string *r_test_error, const godot_string *p_path, godot_pool_string_array *r_functions);
int (*find_function)(godot_pluginscript_language_data *p_data, const godot_string *p_function, const godot_string *p_code); // Can be NULL
godot_string (*make_function)(godot_pluginscript_language_data *p_data, const godot_string *p_class, const godot_string *p_name, const godot_pool_string_array *p_args);
- godot_error (*complete_code)(godot_pluginscript_language_data *p_data, const godot_string *p_code, const godot_string *p_base_path, godot_object *p_owner, godot_array *r_options, godot_bool *r_force, godot_string *r_call_hint);
+ godot_error (*complete_code)(godot_pluginscript_language_data *p_data, const godot_string *p_code, const godot_string *p_path, godot_object *p_owner, godot_array *r_options, godot_bool *r_force, godot_string *r_call_hint);
void (*auto_indent_code)(godot_pluginscript_language_data *p_data, godot_string *p_code, int p_from_line, int p_to_line);
void (*add_global_constant)(godot_pluginscript_language_data *p_data, const godot_string *p_variable, const godot_variant *p_value);
diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp
index c9d92c09ed..7cb47ec623 100644
--- a/modules/gdnative/pluginscript/pluginscript_language.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_language.cpp
@@ -159,13 +159,13 @@ String PluginScriptLanguage::make_function(const String &p_class, const String &
return String();
}
-Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) {
+Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) {
if (_desc.complete_code) {
Array options;
godot_error tmp = _desc.complete_code(
_data,
(godot_string *)&p_code,
- (godot_string *)&p_base_path,
+ (godot_string *)&p_path,
(godot_object *)p_owner,
(godot_array *)&options,
&r_force,
diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h
index 991be0bf12..a11e916975 100644
--- a/modules/gdnative/pluginscript/pluginscript_language.h
+++ b/modules/gdnative/pluginscript/pluginscript_language.h
@@ -81,7 +81,7 @@ public:
virtual bool can_inherit_from_file() { return true; }
virtual int find_function(const String &p_function, const String &p_code) const;
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
- virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint);
+ virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint);
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
virtual void add_global_constant(const StringName &p_variable, const Variant &p_value);
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp
index 8dbbd2e4eb..1d6f9db349 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_script.cpp
@@ -39,12 +39,12 @@
#define ASSERT_SCRIPT_VALID() \
{ \
ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \
- ERR_FAIL_COND(!can_instance()) \
+ ERR_FAIL_COND(!can_instance()); \
}
-#define ASSERT_SCRIPT_VALID_V(ret) \
- { \
- ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \
- ERR_FAIL_COND_V(!can_instance(), ret) \
+#define ASSERT_SCRIPT_VALID_V(ret) \
+ { \
+ ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \
+ ERR_FAIL_COND_V(!can_instance(), ret); \
}
#else
#define ASSERT_SCRIPT_VALID()
@@ -77,7 +77,7 @@ PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int
// There is currently no way to get the constructor function name of the script.
// instance->call("__init__", p_args, p_argcount, r_error);
if (p_argcount > 0) {
- WARN_PRINT("PluginScript doesn't support arguments in the constructor")
+ WARN_PRINT("PluginScript doesn't support arguments in the constructor");
}
return instance;
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 060a9d6c91..62b65fe96b 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -56,6 +56,10 @@ static bool _is_hex_symbol(CharType c) {
return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
}
+static bool _is_bin_symbol(CharType c) {
+ return (c == '0' || c == '1');
+}
+
Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) {
Map<int, TextEdit::HighlighterInfo> color_map;
@@ -76,6 +80,7 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_
bool in_member_variable = false;
bool in_node_path = false;
bool is_hex_notation = false;
+ bool is_bin_notation = false;
bool expect_type = false;
Color keyword_color;
Color color;
@@ -118,14 +123,26 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_
is_hex_notation = false;
}
+ // disallow anything not a 0 or 1
+ if (is_bin_notation && (_is_bin_symbol(str[j]))) {
+ is_number = true;
+ } else if (is_bin_notation) {
+ is_bin_notation = false;
+ is_number = false;
+ } else {
+ is_bin_notation = false;
+ }
+
// check for dot or underscore or 'x' for hex notation in floating point number or 'e' for scientific notation
- if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'e') && !in_word && prev_is_number && !is_number) {
+ if ((str[j] == '.' || str[j] == 'x' || str[j] == 'b' || str[j] == '_' || str[j] == 'e') && !in_word && prev_is_number && !is_number) {
is_number = true;
is_symbol = false;
is_char = false;
if (str[j] == 'x' && str[j - 1] == '0') {
is_hex_notation = true;
+ } else if (str[j] == 'b' && str[j - 1] == '0') {
+ is_bin_notation = true;
}
}
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 716f536e89..40b773d99f 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -458,9 +458,9 @@ public:
virtual bool can_inherit_from_file() { return true; }
virtual int find_function(const String &p_function, const String &p_code) const;
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
- virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint);
+ virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint);
#ifdef TOOLS_ENABLED
- virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_base_path, Object *p_owner, LookupResult &r_result);
+ virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result);
#endif
virtual String _get_indentation() const;
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index f7be0ce37c..189317b163 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1977,12 +1977,12 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
for (int i = 0; i < p_class->subclasses.size(); i++) {
StringName name = p_class->subclasses[i]->name;
-
- GDScript *subclass = p_script->subclasses[name].ptr();
+ Ref<GDScript> &subclass = p_script->subclasses[name];
+ GDScript *subclass_ptr = subclass.ptr();
// Subclass might still be parsing, just skip it
- if (!parsed_classes.has(subclass) && !parsing_classes.has(subclass)) {
- Error err = _parse_class_level(subclass, p_class->subclasses[i], p_keep_state);
+ if (!parsed_classes.has(subclass_ptr) && !parsing_classes.has(subclass_ptr)) {
+ Error err = _parse_class_level(subclass_ptr, p_class->subclasses[i], p_keep_state);
if (err)
return err;
}
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index d91e32249e..6c77968f44 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -2054,7 +2054,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
if (!p_only_functions) {
List<PropertyInfo> members;
- tmp.get_property_list(&members);
+ p_base.value.get_property_list(&members);
for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
if (String(E->get().name).find("/") == -1) {
@@ -2461,13 +2461,13 @@ static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDS
r_forced = r_result.size() > 0;
}
-Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) {
+Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) {
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
GDScriptParser parser;
- parser.parse(p_code, p_base_path, false, "", true);
+ parser.parse(p_code, p_path.get_base_dir(), false, p_path, true);
r_forced = false;
Set<String> options;
GDScriptCompletionContext context;
@@ -2478,7 +2478,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
if (!context._class || context._class->owner == NULL) {
context.base = p_owner;
- context.base_path = p_base_path;
+ context.base_path = p_path.get_base_dir();
}
bool is_function = false;
@@ -2884,7 +2884,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
#else
-Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) {
+Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) {
return OK;
}
@@ -3155,7 +3155,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
return ERR_CANT_RESOLVE;
}
-Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol, const String &p_base_path, Object *p_owner, LookupResult &r_result) {
+Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) {
//before parsing, try the usual stuff
if (ClassDB::class_exists(p_symbol)) {
@@ -3197,7 +3197,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
}
GDScriptParser parser;
- parser.parse(p_code, p_base_path, false, "", true);
+ parser.parse(p_code, p_path.get_base_dir(), false, p_path, true);
if (parser.get_completion_type() == GDScriptParser::COMPLETION_NONE) {
return ERR_CANT_RESOLVE;
@@ -3209,7 +3209,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
context.block = parser.get_completion_block();
context.line = parser.get_completion_line();
context.base = p_owner;
- context.base_path = p_base_path;
+ context.base_path = p_path.get_base_dir();
if (context._class && context._class->extends_class.size() > 0) {
bool success = false;
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index 5ebcddfd7c..0736f3d010 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -78,6 +78,7 @@ const char *GDScriptFunctions::get_func_name(Function p_func) {
"inverse_lerp",
"range_lerp",
"smoothstep",
+ "move_toward",
"dectime",
"randomize",
"randi",
@@ -341,7 +342,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
VALIDATE_ARG_NUM(0);
r_ret = Math::step_decimals((double)*p_args[0]);
ERR_EXPLAIN("GDScript method 'decimals' is deprecated and has been renamed to 'step_decimals', please update your code accordingly.");
- WARN_DEPRECATED
+ WARN_DEPRECATED;
} break;
case MATH_STEP_DECIMALS: {
VALIDATE_ARG_COUNT(1);
@@ -398,6 +399,13 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
VALIDATE_ARG_NUM(2);
r_ret = Math::smoothstep((double)*p_args[0], (double)*p_args[1], (double)*p_args[2]);
} break;
+ case MATH_MOVE_TOWARD: {
+ VALIDATE_ARG_COUNT(3);
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ r_ret = Math::move_toward((double)*p_args[0], (double)*p_args[1], (double)*p_args[2]);
+ } break;
case MATH_DECTIME: {
VALIDATE_ARG_COUNT(3);
VALIDATE_ARG_NUM(0);
@@ -1466,6 +1474,7 @@ bool GDScriptFunctions::is_deterministic(Function p_func) {
case MATH_INVERSE_LERP:
case MATH_RANGE_LERP:
case MATH_SMOOTHSTEP:
+ case MATH_MOVE_TOWARD:
case MATH_DECTIME:
case MATH_DEG2RAD:
case MATH_RAD2DEG:
@@ -1669,6 +1678,11 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
mi.return_val.type = Variant::REAL;
return mi;
} break;
+ case MATH_MOVE_TOWARD: {
+ MethodInfo mi("move_toward", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "delta"));
+ mi.return_val.type = Variant::REAL;
+ return mi;
+ } break;
case MATH_DECTIME: {
MethodInfo mi("dectime", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "amount"), PropertyInfo(Variant::REAL, "step"));
mi.return_val.type = Variant::REAL;
diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h
index c594480ff8..6ad70f2eb4 100644
--- a/modules/gdscript/gdscript_functions.h
+++ b/modules/gdscript/gdscript_functions.h
@@ -69,6 +69,7 @@ public:
MATH_INVERSE_LERP,
MATH_RANGE_LERP,
MATH_SMOOTHSTEP,
+ MATH_MOVE_TOWARD,
MATH_DECTIME,
MATH_RANDOMIZE,
MATH_RAND,
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index de15f939ce..ec3e72eef7 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -1995,7 +1995,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
}
}
- ERR_FAIL_V(op);
} break;
default: {
return p_node;
@@ -3369,7 +3368,7 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) {
return;
}
- if (!p_class->constant_expressions.empty() || !p_class->subclasses.empty() || !p_class->functions.empty() || !p_class->variables.empty()) {
+ if (!p_class->constant_expressions.empty() || !p_class->subclasses.empty() || !p_class->functions.empty() || !p_class->variables.empty() || p_class->classname_used) {
_set_error("'extends' must be used before anything else.");
return;
@@ -3497,7 +3496,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("'class_name' is only valid for the main class namespace.");
return;
}
- if (self_path.empty()) {
+ if (self_path.begins_with("res://") && self_path.find("::") != -1) {
_set_error("'class_name' not allowed in built-in scripts.");
return;
}
@@ -3506,6 +3505,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("'class_name' syntax: 'class_name <UniqueName>'");
return;
}
+ if (p_class->classname_used) {
+ _set_error("'class_name' already used for this class.");
+ return;
+ }
+
+ p_class->classname_used = true;
p_class->name = tokenizer->get_token_identifier(1);
@@ -4019,7 +4024,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
ERR_EXPLAIN("Exporting bit flags hint requires string constants.");
- WARN_DEPRECATED
+ WARN_DEPRECATED;
break;
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
@@ -4062,6 +4067,50 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
break;
}
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_RENDER") {
+
+ tokenizer->advance();
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' in layers 2D render hint.");
+ return;
+ }
+ current_export.hint = PROPERTY_HINT_LAYERS_2D_RENDER;
+ break;
+ }
+
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_PHYSICS") {
+
+ tokenizer->advance();
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' in layers 2D physics hint.");
+ return;
+ }
+ current_export.hint = PROPERTY_HINT_LAYERS_2D_PHYSICS;
+ break;
+ }
+
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_RENDER") {
+
+ tokenizer->advance();
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' in layers 3D render hint.");
+ return;
+ }
+ current_export.hint = PROPERTY_HINT_LAYERS_3D_RENDER;
+ break;
+ }
+
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_PHYSICS") {
+
+ tokenizer->advance();
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' in layers 3D physics hint.");
+ return;
+ }
+ current_export.hint = PROPERTY_HINT_LAYERS_3D_PHYSICS;
+ break;
+ }
+
if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING) {
//enumeration
current_export.hint = PROPERTY_HINT_ENUM;
@@ -5248,6 +5297,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) {
if (base_script.is_valid()) {
String ident = base;
+ Ref<GDScript> find_subclass = base_script;
for (int i = extend_iter; i < p_class->extends_class.size(); i++) {
@@ -5257,7 +5307,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) {
if (base_script->get_subclasses().has(subclass)) {
- base_script = base_script->get_subclasses()[subclass];
+ find_subclass = base_script->get_subclasses()[subclass];
} else if (base_script->get_constants().has(subclass)) {
Ref<GDScript> new_base_class = base_script->get_constants()[subclass];
@@ -5265,7 +5315,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) {
_set_error("Constant is not a class: " + ident, p_class->line);
return;
}
- base_script = new_base_class;
+ find_subclass = new_base_class;
} else {
_set_error("Could not find subclass: " + ident, p_class->line);
@@ -5273,7 +5323,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) {
}
}
- script = base_script;
+ script = find_subclass;
} else if (!base_class) {
@@ -6014,7 +6064,11 @@ bool GDScriptParser::_is_type_compatible(const DataType &p_container, const Data
}
GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
+#ifdef DEBUG_ENABLED
+ if (p_node->get_datatype().has_type && p_node->type != Node::TYPE_ARRAY && p_node->type != Node::TYPE_DICTIONARY) {
+#else
if (p_node->get_datatype().has_type) {
+#endif
return p_node->get_datatype();
}
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 809bff8f20..5e4de11357 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -149,6 +149,7 @@ public:
bool tool;
StringName name;
bool extends_used;
+ bool classname_used;
StringName extends_file;
Vector<StringName> extends_class;
DataType base_type;
@@ -198,6 +199,7 @@ public:
tool = false;
type = TYPE_CLASS;
extends_used = false;
+ classname_used = false;
end_line = -1;
owner = NULL;
}
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index b8048fb5dd..a93d1ceebb 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -376,6 +376,11 @@ static bool _is_hex(CharType c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
+static bool _is_bin(CharType c) {
+
+ return (c == '0' || c == '1');
+}
+
void GDScriptTokenizerText::_make_token(Token p_type) {
TokenData &tk = tk_rb[tk_rb_pos];
@@ -877,6 +882,7 @@ void GDScriptTokenizerText::_advance() {
bool period_found = false;
bool exponent_found = false;
bool hexa_found = false;
+ bool bin_found = false;
bool sign_found = false;
String str;
@@ -887,16 +893,28 @@ void GDScriptTokenizerText::_advance() {
if (period_found || exponent_found) {
_make_error("Invalid numeric constant at '.'");
return;
+ } else if (bin_found) {
+ _make_error("Invalid binary constant at '.'");
+ return;
+ } else if (hexa_found) {
+ _make_error("Invalid hexadecimal constant at '.'");
+ return;
}
period_found = true;
} else if (GETCHAR(i) == 'x') {
- if (hexa_found || str.length() != 1 || !((i == 1 && str[0] == '0') || (i == 2 && str[1] == '0' && str[0] == '-'))) {
+ if (hexa_found || bin_found || str.length() != 1 || !((i == 1 && str[0] == '0') || (i == 2 && str[1] == '0' && str[0] == '-'))) {
_make_error("Invalid numeric constant at 'x'");
return;
}
hexa_found = true;
+ } else if (GETCHAR(i) == 'b') {
+ if (hexa_found || bin_found || str.length() != 1 || !((i == 1 && str[0] == '0') || (i == 2 && str[1] == '0' && str[0] == '-'))) {
+ _make_error("Invalid numeric constant at 'b'");
+ return;
+ }
+ bin_found = true;
} else if (!hexa_found && GETCHAR(i) == 'e') {
- if (exponent_found) {
+ if (exponent_found || bin_found) {
_make_error("Invalid numeric constant at 'e'");
return;
}
@@ -905,6 +923,8 @@ void GDScriptTokenizerText::_advance() {
//all ok
} else if (hexa_found && _is_hex(GETCHAR(i))) {
+ } else if (bin_found && _is_bin(GETCHAR(i))) {
+
} else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) {
if (sign_found) {
_make_error("Invalid numeric constant at '-'");
@@ -930,6 +950,9 @@ void GDScriptTokenizerText::_advance() {
if (hexa_found) {
int64_t val = str.hex_to_int64();
_make_constant(val);
+ } else if (bin_found) {
+ int64_t val = str.bin_to_int64();
+ _make_constant(val);
} else if (period_found || exponent_found) {
double val = str.to_double();
_make_constant(val);
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 32a014e76d..3caa7b1d12 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -197,7 +197,7 @@ bool GridMap::get_collision_layer_bit(int p_bit) const {
void GridMap::set_theme(const Ref<MeshLibrary> &p_theme) {
ERR_EXPLAIN("GridMap.theme/set_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/set_mesh_library() instead.");
- WARN_DEPRECATED
+ WARN_DEPRECATED;
set_mesh_library(p_theme);
}
@@ -205,7 +205,7 @@ void GridMap::set_theme(const Ref<MeshLibrary> &p_theme) {
Ref<MeshLibrary> GridMap::get_theme() const {
ERR_EXPLAIN("GridMap.theme/get_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/get_mesh_library() instead.");
- WARN_DEPRECATED
+ WARN_DEPRECATED;
return get_mesh_library();
}
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index 657aa1f9ce..890bd730f7 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -1179,6 +1179,10 @@ void GridMapEditor::_floor_changed(float p_value) {
_update_selection_transform();
}
+void GridMapEditor::_floor_mouse_exited() {
+ floor->get_line_edit()->release_focus();
+}
+
void GridMapEditor::_bind_methods() {
ClassDB::bind_method("_text_changed", &GridMapEditor::_text_changed);
@@ -1188,6 +1192,7 @@ void GridMapEditor::_bind_methods() {
ClassDB::bind_method("_configure", &GridMapEditor::_configure);
ClassDB::bind_method("_item_selected_cbk", &GridMapEditor::_item_selected_cbk);
ClassDB::bind_method("_floor_changed", &GridMapEditor::_floor_changed);
+ ClassDB::bind_method("_floor_mouse_exited", &GridMapEditor::_floor_mouse_exited);
ClassDB::bind_method("_set_selection", &GridMapEditor::_set_selection);
ClassDB::bind_method(D_METHOD("_set_display_mode", "mode"), &GridMapEditor::_set_display_mode);
@@ -1221,6 +1226,8 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
spatial_editor_hb->add_child(floor);
floor->connect("value_changed", this, "_floor_changed");
+ floor->connect("mouse_exited", this, "_floor_mouse_exited");
+ floor->get_line_edit()->connect("mouse_exited", this, "_floor_mouse_exited");
spatial_editor_hb->add_child(memnew(VSeparator));
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index 8e1948ea7d..da36165d4e 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -225,6 +225,7 @@ class GridMapEditor : public VBoxContainer {
void _set_selection(bool p_active, const Vector3 p_begin = Vector3(), const Vector3 p_end = Vector3());
void _floor_changed(float p_value);
+ void _floor_mouse_exited();
void _delete_selection();
void _fill_selection();
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index 341d57f3e4..6c3ecee272 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -20,11 +20,6 @@ if env['tools']:
'glue/cs_glue_version.gen.h'
)
-vars = Variables()
-vars.Add(BoolVariable('mono_glue', 'Build with the mono glue sources', True))
-vars.Add(BoolVariable('xbuild_fallback', 'If MSBuild is not found, fallback to xbuild', False))
-vars.Update(env_mono)
-
# Glue sources
if env_mono['mono_glue']:
env_mono.Append(CPPDEFINES=['MONO_GLUE_ENABLED'])
diff --git a/modules/mono/build_scripts/godotsharptools_build.py b/modules/mono/build_scripts/godotsharptools_build.py
index af3a5cb5c6..17f9a990af 100644
--- a/modules/mono/build_scripts/godotsharptools_build.py
+++ b/modules/mono/build_scripts/godotsharptools_build.py
@@ -1,6 +1,5 @@
# Build GodotSharpTools solution
-
import os
from SCons.Script import Builder, Dir
@@ -53,21 +52,9 @@ def find_nuget_windows(env):
if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
return hint_path
- from . import mono_reg_utils as monoreg
-
- mono_root = ''
- bits = env['bits']
+ from . mono_reg_utils import find_mono_root_dir
- if bits == '32':
- if os.getenv('MONO32_PREFIX'):
- mono_root = os.getenv('MONO32_PREFIX')
- else:
- mono_root = monoreg.find_mono_root_dir(bits)
- else:
- if os.getenv('MONO64_PREFIX'):
- mono_root = os.getenv('MONO64_PREFIX')
- else:
- mono_root = monoreg.find_mono_root_dir(bits)
+ mono_root = env['mono_prefix'] or find_mono_root_dir(env['bits'])
if mono_root:
mono_bin_dir = os.path.join(mono_root, 'bin')
@@ -114,21 +101,9 @@ def find_msbuild_unix(filename):
def find_msbuild_windows(env):
- from . import mono_reg_utils as monoreg
+ from . mono_reg_utils import find_mono_root_dir, find_msbuild_tools_path_reg
- mono_root = ''
- bits = env['bits']
-
- if bits == '32':
- if os.getenv('MONO32_PREFIX'):
- mono_root = os.getenv('MONO32_PREFIX')
- else:
- mono_root = monoreg.find_mono_root_dir(bits)
- else:
- if os.getenv('MONO64_PREFIX'):
- mono_root = os.getenv('MONO64_PREFIX')
- else:
- mono_root = monoreg.find_mono_root_dir(bits)
+ mono_root = env['mono_prefix'] or find_mono_root_dir(env['bits'])
if not mono_root:
raise RuntimeError('Cannot find mono root directory')
@@ -148,7 +123,7 @@ def find_msbuild_windows(env):
}
return (msbuild_mono, framework_path, mono_msbuild_env)
- msbuild_tools_path = monoreg.find_msbuild_tools_path_reg()
+ msbuild_tools_path = find_msbuild_tools_path_reg()
if msbuild_tools_path:
return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), framework_path, {})
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 4cfa2a5b93..c549640d61 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -1,15 +1,30 @@
import imp
import os
+import os.path
import sys
import subprocess
from distutils.version import LooseVersion
-from SCons.Script import BoolVariable, Dir, Environment, Variables
+from SCons.Script import Dir, Environment
if os.name == 'nt':
from . import mono_reg_utils as monoreg
+android_arch_dirs = {
+ 'armv7': 'armeabi-v7a',
+ 'arm64v8': 'arm64-v8a',
+ 'x86': 'x86',
+ 'x86_64': 'x86_64'
+}
+
+
+def get_android_out_dir(env):
+ return os.path.join(Dir('#platform/android/java/libs').abspath,
+ 'release' if env['target'] == 'release' else 'debug',
+ android_arch_dirs[env['android_arch']])
+
+
def find_file_in_dir(directory, files, prefix='', extension=''):
if not extension.startswith('.'):
extension = '.' + extension
@@ -20,47 +35,47 @@ def find_file_in_dir(directory, files, prefix='', extension=''):
def copy_file(src_dir, dst_dir, name):
- from shutil import copyfile
+ from shutil import copy
- src_path = os.path.join(src_dir, name)
- dst_path = os.path.join(dst_dir, name)
+ src_path = os.path.join(Dir(src_dir).abspath, name)
+ dst_dir = Dir(dst_dir).abspath
if not os.path.isdir(dst_dir):
os.mkdir(dst_dir)
- copyfile(src_path, dst_path)
+ copy(src_path, dst_dir)
def configure(env, env_mono):
- envvars = Variables()
- envvars.Add(BoolVariable('mono_static', 'Statically link mono', False))
- envvars.Add(BoolVariable('copy_mono_root', 'Make a copy of the mono installation directory to bundle with the editor', False))
- envvars.Update(env)
-
bits = env['bits']
+ is_android = env['platform'] == 'android'
tools_enabled = env['tools']
mono_static = env['mono_static']
copy_mono_root = env['copy_mono_root']
+ mono_prefix = env['mono_prefix']
+
mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0']
+ if is_android and not env['android_arch'] in android_arch_dirs:
+ raise RuntimeError('This module does not support for the specified \'android_arch\': ' + env['android_arch'])
+
+ if is_android and tools_enabled:
+ # TODO: Implement this. We have to add the data directory to the apk, concretely the Api and Tools folders.
+ raise RuntimeError('This module does not currently support building for android with tools enabled')
+
+ if (os.getenv('MONO32_PREFIX') or os.getenv('MONO64_PREFIX')) and not mono_prefix:
+ print("WARNING: The environment variables 'MONO32_PREFIX' and 'MONO64_PREFIX' are deprecated; use the 'mono_prefix' SCons parameter instead")
+
if env['platform'] == 'windows':
- mono_root = ''
+ mono_root = mono_prefix
- if bits == '32':
- if os.getenv('MONO32_PREFIX'):
- mono_root = os.getenv('MONO32_PREFIX')
- elif os.name == 'nt':
- mono_root = monoreg.find_mono_root_dir(bits)
- else:
- if os.getenv('MONO64_PREFIX'):
- mono_root = os.getenv('MONO64_PREFIX')
- elif os.name == 'nt':
- mono_root = monoreg.find_mono_root_dir(bits)
+ if not mono_root and os.name == 'nt':
+ mono_root = monoreg.find_mono_root_dir(bits)
if not mono_root:
- raise RuntimeError('Mono installation directory not found')
+ raise RuntimeError("Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter")
print('Found Mono root directory: ' + mono_root)
@@ -113,21 +128,18 @@ def configure(env, env_mono):
if not mono_dll_name:
raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path)
- copy_file(mono_bin_path, 'bin', mono_dll_name + '.dll')
+ copy_file(mono_bin_path, '#bin', mono_dll_name + '.dll')
else:
is_apple = (sys.platform == 'darwin' or "osxcross" in env)
sharedlib_ext = '.dylib' if is_apple else '.so'
- mono_root = ''
+ mono_root = mono_prefix
mono_lib_path = ''
+ mono_so_name = ''
- if bits == '32':
- if os.getenv('MONO32_PREFIX'):
- mono_root = os.getenv('MONO32_PREFIX')
- else:
- if os.getenv('MONO64_PREFIX'):
- mono_root = os.getenv('MONO64_PREFIX')
+ if not mono_root and is_android:
+ raise RuntimeError("Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter")
if not mono_root and is_apple:
# Try with some known directories under OSX
@@ -142,7 +154,8 @@ def configure(env, env_mono):
if not mono_root and mono_static:
mono_root = pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext)
if not mono_root:
- raise RuntimeError('Building with mono_static=yes, but failed to find the mono prefix with pkg-config. Specify one manually')
+ raise RuntimeError("Building with mono_static=yes, but failed to find the mono prefix with pkg-config; " + \
+ "specify one manually with the 'mono_prefix' SCons parameter")
if mono_root:
print('Found Mono root directory: ' + mono_root)
@@ -174,6 +187,8 @@ def configure(env, env_mono):
if is_apple:
env.Append(LIBS=['iconv', 'pthread'])
+ elif is_android:
+ env.Append(LIBS=['m', 'dl'])
else:
env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
@@ -183,7 +198,7 @@ def configure(env, env_mono):
if not mono_so_name:
raise RuntimeError('Could not find mono shared library in: ' + mono_lib_path)
- copy_file(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext)
+ copy_file(mono_lib_path, '#bin', 'lib' + mono_so_name + sharedlib_ext)
else:
assert not mono_static
@@ -196,9 +211,6 @@ def configure(env, env_mono):
env.ParseConfig('pkg-config monosgen-2 --libs')
env_mono.ParseConfig('pkg-config monosgen-2 --cflags')
- mono_lib_path = ''
- mono_so_name = ''
-
tmpenv = Environment()
tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
tmpenv.ParseConfig('pkg-config monosgen-2 --libs-only-L')
@@ -213,11 +225,13 @@ def configure(env, env_mono):
if not mono_so_name:
raise RuntimeError('Could not find mono shared library in: ' + str(tmpenv['LIBPATH']))
- copy_file(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext)
+ if not mono_static:
+ libs_output_dir = get_android_out_dir(env) if is_android else '#bin'
+ copy_file(mono_lib_path, libs_output_dir, 'lib' + mono_so_name + sharedlib_ext)
env.Append(LINKFLAGS='-rdynamic')
- if not tools_enabled:
+ if not tools_enabled and not is_android:
if not mono_root:
mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip()
@@ -241,7 +255,7 @@ def make_template_dir(env, mono_root):
template_dir_name = ''
- if platform in ['windows', 'osx', 'x11']:
+ if platform in ['windows', 'osx', 'x11', 'android']:
template_dir_name = 'data.mono.%s.%s.%s' % (platform, env['bits'], target)
else:
assert False
@@ -256,12 +270,13 @@ def make_template_dir(env, mono_root):
# Copy etc/mono/
- template_mono_config_dir = os.path.join(template_mono_root_dir, 'etc', 'mono')
- copy_mono_etc_dir(mono_root, template_mono_config_dir, env['platform'])
+ if platform != 'android':
+ template_mono_config_dir = os.path.join(template_mono_root_dir, 'etc', 'mono')
+ copy_mono_etc_dir(mono_root, template_mono_config_dir, env['platform'])
# Copy the required shared libraries
- copy_mono_shared_libs(mono_root, template_mono_root_dir, env['platform'])
+ copy_mono_shared_libs(env, mono_root, template_mono_root_dir)
def copy_mono_root_files(env, mono_root):
@@ -285,7 +300,7 @@ def copy_mono_root_files(env, mono_root):
# Copy the required shared libraries
- copy_mono_shared_libs(mono_root, editor_mono_root_dir, env['platform'])
+ copy_mono_shared_libs(env, mono_root, editor_mono_root_dir)
# Copy framework assemblies
@@ -332,39 +347,55 @@ def copy_mono_etc_dir(mono_root, target_mono_config_dir, platform):
copy_tree(os.path.join(mono_etc_dir, '2.0'), os.path.join(target_mono_config_dir, '2.0'))
copy_tree(os.path.join(mono_etc_dir, '4.0'), os.path.join(target_mono_config_dir, '4.0'))
copy_tree(os.path.join(mono_etc_dir, '4.5'), os.path.join(target_mono_config_dir, '4.5'))
- copy_tree(os.path.join(mono_etc_dir, 'mconfig'), os.path.join(target_mono_config_dir, 'mconfig'))
+ if os.path.isdir(os.path.join(mono_etc_dir, 'mconfig')):
+ copy_tree(os.path.join(mono_etc_dir, 'mconfig'), os.path.join(target_mono_config_dir, 'mconfig'))
for file in glob(os.path.join(mono_etc_dir, '*')):
if os.path.isfile(file):
copy(file, target_mono_config_dir)
-def copy_mono_shared_libs(mono_root, target_mono_root_dir, platform):
+def copy_mono_shared_libs(env, mono_root, target_mono_root_dir):
from shutil import copy
+ def copy_if_exists(src, dst):
+ if os.path.isfile(src):
+ copy(src, dst)
+
+ platform = env['platform']
+
if platform == 'windows':
target_mono_bin_dir = os.path.join(target_mono_root_dir, 'bin')
if not os.path.isdir(target_mono_bin_dir):
os.makedirs(target_mono_bin_dir)
- copy(os.path.join(mono_root, 'bin', 'MonoPosixHelper.dll'), os.path.join(target_mono_bin_dir, 'MonoPosixHelper.dll'))
+ copy(os.path.join(mono_root, 'bin', 'MonoPosixHelper.dll'), target_mono_bin_dir)
else:
- target_mono_lib_dir = os.path.join(target_mono_root_dir, 'lib')
+ target_mono_lib_dir = get_android_out_dir(env) if platform == 'android' else os.path.join(target_mono_root_dir, 'lib')
if not os.path.isdir(target_mono_lib_dir):
os.makedirs(target_mono_lib_dir)
if platform == 'osx':
- copy(os.path.join(mono_root, 'lib', 'libMonoPosixHelper.dylib'), os.path.join(target_mono_lib_dir, 'libMonoPosixHelper.dylib'))
- elif platform == 'x11':
- copy(os.path.join(mono_root, 'lib', 'libmono-btls-shared.so'), os.path.join(target_mono_lib_dir, 'libmono-btls-shared.so'))
- copy(os.path.join(mono_root, 'lib', 'libMonoPosixHelper.so'), os.path.join(target_mono_lib_dir, 'libMonoPosixHelper.so'))
+ # TODO: Make sure nothing is missing
+ copy(os.path.join(mono_root, 'lib', 'libMonoPosixHelper.dylib'), target_mono_lib_dir)
+ elif platform == 'x11' or platform == 'android':
+ lib_file_names = [lib_name + '.so' for lib_name in [
+ 'libmono-btls-shared', 'libmono-ee-interp', 'libmono-native', 'libMonoPosixHelper',
+ 'libmono-profiler-aot', 'libmono-profiler-coverage', 'libmono-profiler-log', 'libMonoSupportW'
+ ]]
+
+ for lib_file_name in lib_file_names:
+ copy_if_exists(os.path.join(mono_root, 'lib', lib_file_name), target_mono_lib_dir)
def configure_for_mono_version(env, mono_version):
if mono_version is None:
- raise RuntimeError('Mono JIT compiler version not found')
+ if os.getenv('MONO_VERSION'):
+ mono_version = os.getenv('MONO_VERSION')
+ else:
+ raise RuntimeError("Mono JIT compiler version not found; specify one manually with the 'MONO_VERSION' environment variable")
print('Found Mono JIT compiler version: ' + str(mono_version))
if mono_version >= LooseVersion('5.12.0'):
env.Append(CPPFLAGS=['-DHAS_PENDING_EXCEPTIONS'])
diff --git a/modules/mono/build_scripts/patches/fix-mono-android-tkill.diff b/modules/mono/build_scripts/patches/fix-mono-android-tkill.diff
new file mode 100644
index 0000000000..05f8dcadcc
--- /dev/null
+++ b/modules/mono/build_scripts/patches/fix-mono-android-tkill.diff
@@ -0,0 +1,70 @@
+diff --git a/libgc/include/private/gcconfig.h b/libgc/include/private/gcconfig.h
+index e2bdf13ac3e..f962200ba4e 100644
+--- a/libgc/include/private/gcconfig.h
++++ b/libgc/include/private/gcconfig.h
+@@ -2255,6 +2255,14 @@
+ # define GETPAGESIZE() getpagesize()
+ # endif
+
++#if defined(HOST_ANDROID) && !(__ANDROID_API__ >= 23) \
++ && ((defined(MIPS) && (CPP_WORDSZ == 32)) \
++ || defined(ARM32) || defined(I386) /* but not x32 */)
++ /* tkill() exists only on arm32/mips(32)/x86. */
++ /* NDK r11+ deprecates tkill() but keeps it for Mono clients. */
++# define USE_TKILL_ON_ANDROID
++#endif
++
+ # if defined(SUNOS5) || defined(DRSNX) || defined(UTS4)
+ /* OS has SVR4 generic features. Probably others also qualify. */
+ # define SVR4
+diff --git a/libgc/pthread_stop_world.c b/libgc/pthread_stop_world.c
+index f93ce26b562..4a49a6d578c 100644
+--- a/libgc/pthread_stop_world.c
++++ b/libgc/pthread_stop_world.c
+@@ -336,7 +336,7 @@ void GC_push_all_stacks()
+ pthread_t GC_stopping_thread;
+ int GC_stopping_pid;
+
+-#ifdef HOST_ANDROID
++#ifdef USE_TKILL_ON_ANDROID
+ static
+ int android_thread_kill(pid_t tid, int sig)
+ {
+diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c
+index ad9b8823f8f..3542b32b540 100644
+--- a/mono/metadata/threads.c
++++ b/mono/metadata/threads.c
+@@ -77,8 +77,12 @@ mono_native_thread_join_handle (HANDLE thread_handle, gboolean close_handle);
+ #include <zircon/syscalls.h>
+ #endif
+
+-#if defined(HOST_ANDROID) && !defined(TARGET_ARM64) && !defined(TARGET_AMD64)
+-#define USE_TKILL_ON_ANDROID 1
++#if defined(HOST_ANDROID) && !(__ANDROID_API__ >= 23) \
++ && ((defined(MIPS) && (CPP_WORDSZ == 32)) \
++ || defined(ARM32) || defined(I386) /* but not x32 */)
++ /* tkill() exists only on arm32/mips(32)/x86. */
++ /* NDK r11+ deprecates tkill() but keeps it for Mono clients. */
++# define USE_TKILL_ON_ANDROID
+ #endif
+
+ #ifdef HOST_ANDROID
+diff --git a/mono/utils/mono-threads-posix.c b/mono/utils/mono-threads-posix.c
+index 3e4bf93de5f..79c9f731fe7 100644
+--- a/mono/utils/mono-threads-posix.c
++++ b/mono/utils/mono-threads-posix.c
+@@ -31,8 +31,12 @@
+
+ #include <errno.h>
+
+-#if defined(HOST_ANDROID) && !defined(TARGET_ARM64) && !defined(TARGET_AMD64)
+-#define USE_TKILL_ON_ANDROID 1
++#if defined(HOST_ANDROID) && !(__ANDROID_API__ >= 23) \
++ && ((defined(MIPS) && (CPP_WORDSZ == 32)) \
++ || defined(ARM32) || defined(I386) /* but not x32 */)
++ /* tkill() exists only on arm32/mips(32)/x86. */
++ /* NDK r11+ deprecates tkill() but keeps it for Mono clients. */
++# define USE_TKILL_ON_ANDROID
+ #endif
+
+ #ifdef USE_TKILL_ON_ANDROID
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 3b2e96765e..9adf4ee6e5 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -8,6 +8,16 @@ def configure(env):
env.use_ptrcall = True
env.add_module_version_string('mono')
+ from SCons.Script import BoolVariable, PathVariable, Variables
+
+ envvars = Variables()
+ envvars.Add(PathVariable('mono_prefix', 'Path to the mono installation directory for the target platform and architecture', '', PathVariable.PathAccept))
+ envvars.Add(BoolVariable('mono_static', 'Statically link mono', False))
+ envvars.Add(BoolVariable('mono_glue', 'Build with the mono glue sources', True))
+ envvars.Add(BoolVariable('copy_mono_root', 'Make a copy of the mono installation directory to bundle with the editor', False))
+ envvars.Add(BoolVariable('xbuild_fallback', 'If MSBuild is not found, fallback to xbuild', False))
+ envvars.Update(env)
+
def get_doc_classes():
return [
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index bfbd6ca80e..72199281ff 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -1855,6 +1855,34 @@ void CSharpInstance::_call_notification(int p_notification) {
}
}
+String CSharpInstance::to_string(bool *r_valid) {
+ MonoObject *mono_object = get_mono_object();
+
+ if (mono_object == NULL) {
+ if (r_valid)
+ *r_valid = false;
+ return String();
+ }
+
+ MonoException *exc = NULL;
+ MonoString *result = GDMonoUtils::object_to_string(mono_object, &exc);
+
+ if (exc) {
+ GDMonoUtils::set_pending_exception(exc);
+ if (r_valid)
+ *r_valid = false;
+ return String();
+ }
+
+ if (result == NULL) {
+ if (r_valid)
+ *r_valid = false;
+ return String();
+ }
+
+ return GDMonoMarshal::mono_string_to_godot(result);
+}
+
Ref<Script> CSharpInstance::get_script() const {
return script;
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 298d55c4df..4a1fb8e5ed 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -261,6 +261,8 @@ public:
virtual void notification(int p_notification);
void _call_notification(int p_notification);
+ virtual String to_string(bool *r_valid);
+
virtual Ref<Script> get_script() const;
virtual ScriptLanguage *get_language();
@@ -378,7 +380,6 @@ public:
virtual bool supports_builtin_mode() const;
/* TODO? */ virtual int find_function(const String &p_function, const String &p_code) const { return -1; }
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
- /* TODO? */ Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, String &r_call_hint) { return ERR_UNAVAILABLE; }
virtual String _get_indentation() const;
/* TODO? */ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {}
/* TODO */ virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) {}
diff --git a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs
index 967e3bcc19..e5044feb75 100644
--- a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs
+++ b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs
@@ -186,7 +186,7 @@ namespace GodotSharpTools.Build
private string BuildArguments(string loggerAssemblyPath, string loggerOutputDir, List<string> customProperties)
{
- string arguments = string.Format(@"""{0}"" /v:normal /t:Build ""/p:{1}"" ""/l:{2},{3};{4}""",
+ string arguments = string.Format(@"""{0}"" /v:normal /t:Rebuild ""/p:{1}"" ""/l:{2},{3};{4}""",
solution,
"Configuration=" + config,
typeof(GodotBuildLogger).FullName,
@@ -196,7 +196,7 @@ namespace GodotSharpTools.Build
foreach (string customProperty in customProperties)
{
- arguments += " \"/p:" + customProperty + "\"";
+ arguments += " /p:" + customProperty;
}
return arguments;
diff --git a/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs b/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs
index e45dd2025b..44a43f0ddd 100644
--- a/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs
+++ b/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Runtime.CompilerServices;
namespace GodotSharpTools.Editor
@@ -62,7 +63,7 @@ namespace GodotSharpTools.Editor
{
// OSX export templates are contained in a zip, so we place
// our custom template inside it and let Godot do the rest.
- return !featureSet.Contains("OSX");
+ return !featureSet.Any(f => new[] {"OSX", "Android"}.Contains(f));
}
[MethodImpl(MethodImplOptions.InternalCall)]
diff --git a/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs b/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs
index 89279c69a6..f4ab11a222 100644
--- a/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs
+++ b/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs
@@ -80,7 +80,7 @@ namespace GodotSharpTools.Project
toolsGroup.AddProperty("DebugSymbols", "true");
toolsGroup.AddProperty("DebugType", "portable");
toolsGroup.AddProperty("Optimize", "false");
- toolsGroup.AddProperty("DefineConstants", "DEBUG;TOOLS;");
+ toolsGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;TOOLS;");
toolsGroup.AddProperty("ErrorReport", "prompt");
toolsGroup.AddProperty("WarningLevel", "4");
toolsGroup.AddProperty("ConsolePause", "false");
@@ -161,7 +161,7 @@ namespace GodotSharpTools.Project
debugGroup.AddProperty("DebugSymbols", "true");
debugGroup.AddProperty("DebugType", "portable");
debugGroup.AddProperty("Optimize", "false");
- debugGroup.AddProperty("DefineConstants", "DEBUG;");
+ debugGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;");
debugGroup.AddProperty("ErrorReport", "prompt");
debugGroup.AddProperty("WarningLevel", "4");
debugGroup.AddProperty("ConsolePause", "false");
@@ -170,6 +170,7 @@ namespace GodotSharpTools.Project
releaseGroup.Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ";
releaseGroup.AddProperty("DebugType", "portable");
releaseGroup.AddProperty("Optimize", "true");
+ releaseGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;");
releaseGroup.AddProperty("ErrorReport", "prompt");
releaseGroup.AddProperty("WarningLevel", "4");
releaseGroup.AddProperty("ConsolePause", "false");
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index a408716641..cd7774e7a1 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -2300,9 +2300,14 @@ void BindingsGenerator::_populate_object_type_interfaces() {
if (method_info.name.empty())
continue;
+ String cname = method_info.name;
+
+ if (blacklisted_methods.find(itype.cname) && blacklisted_methods[itype.cname].find(cname))
+ continue;
+
MethodInterface imethod;
imethod.name = method_info.name;
- imethod.cname = imethod.name;
+ imethod.cname = cname;
if (method_info.flags & METHOD_FLAG_VIRTUAL)
imethod.is_virtual = true;
@@ -2975,6 +2980,13 @@ void BindingsGenerator::_populate_global_constants() {
}
}
+void BindingsGenerator::_initialize_blacklisted_methods() {
+
+ blacklisted_methods["Object"].push_back("to_string"); // there is already ToString
+ blacklisted_methods["Object"].push_back("_to_string"); // override ToString instead
+ blacklisted_methods["Object"].push_back("_init"); // never called in C# (TODO: implement it)
+}
+
void BindingsGenerator::_log(const char *p_format, ...) {
if (log_print_enabled) {
@@ -2992,6 +3004,8 @@ void BindingsGenerator::_initialize() {
enum_types.clear();
+ _initialize_blacklisted_methods();
+
_populate_object_type_interfaces();
_populate_builtin_type_interfaces();
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index bdba28c267..ffc73a7e3e 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -491,6 +491,10 @@ class BindingsGenerator {
List<InternalCall> core_custom_icalls;
List<InternalCall> editor_custom_icalls;
+ Map<StringName, List<StringName> > blacklisted_methods;
+
+ void _initialize_blacklisted_methods();
+
struct NameCache {
StringName type_void;
StringName type_Array;
diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp
index de3fd91223..a962d6df27 100644
--- a/modules/mono/editor/godotsharp_builds.cpp
+++ b/modules/mono/editor/godotsharp_builds.cpp
@@ -30,6 +30,7 @@
#include "godotsharp_builds.h"
+#include "core/os/os.h"
#include "core/vector.h"
#include "main/main.h"
@@ -351,7 +352,7 @@ bool GodotSharpBuilds::make_api_assembly(APIAssembly::Type p_api_type) {
return true;
}
-bool GodotSharpBuilds::build_project_blocking(const String &p_config) {
+bool GodotSharpBuilds::build_project_blocking(const String &p_config, const Vector<String> &p_godot_defines) {
if (!FileAccess::exists(GodotSharpDirs::get_project_sln_path()))
return true; // No solution to build
@@ -366,6 +367,29 @@ bool GodotSharpBuilds::build_project_blocking(const String &p_config) {
pr.step("Building project solution", 0);
MonoBuildInfo build_info(GodotSharpDirs::get_project_sln_path(), p_config);
+
+ // Add Godot defines
+#ifdef WINDOWS_ENABLED
+ String constants = "GodotDefineConstants=\"";
+#else
+ String constants = "GodotDefineConstants=\\\"";
+#endif
+
+ for (int i = 0; i < p_godot_defines.size(); i++) {
+ constants += "GODOT_" + p_godot_defines[i].to_upper().replace("-", "_").replace(" ", "_").replace(";", "_") + ";";
+ }
+
+#ifdef REAL_T_IS_DOUBLE
+ constants += "GODOT_REAL_T_IS_DOUBLE;";
+#endif
+
+#ifdef WINDOWS_ENABLED
+ constants += "\"";
+#else
+ constants += "\\\"";
+#endif
+ build_info.custom_props.push_back(constants);
+
if (!GodotSharpBuilds::get_singleton()->build(build_info)) {
GodotSharpBuilds::show_build_error_dialog("Failed to build project solution");
return false;
@@ -393,7 +417,10 @@ bool GodotSharpBuilds::editor_build_callback() {
ERR_FAIL_COND_V(copy_err != OK, false);
}
- return build_project_blocking("Tools");
+ Vector<String> godot_defines;
+ godot_defines.push_back(OS::get_singleton()->get_name());
+ godot_defines.push_back(sizeof(void *) == 4 ? "32" : "64");
+ return build_project_blocking("Tools", godot_defines);
}
GodotSharpBuilds *GodotSharpBuilds::singleton = NULL;
diff --git a/modules/mono/editor/godotsharp_builds.h b/modules/mono/editor/godotsharp_builds.h
index 652d30538a..2e9050e12e 100644
--- a/modules/mono/editor/godotsharp_builds.h
+++ b/modules/mono/editor/godotsharp_builds.h
@@ -92,7 +92,7 @@ public:
static bool make_api_assembly(APIAssembly::Type p_api_type);
- static bool build_project_blocking(const String &p_config);
+ static bool build_project_blocking(const String &p_config, const Vector<String> &p_godot_defines);
static bool editor_build_callback();
diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index ee5fed1a0c..126178125f 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -94,7 +94,12 @@ void GodotSharpExport::_export_begin(const Set<String> &p_features, bool p_debug
ERR_FAIL_COND(!_add_file(scripts_metadata_path, scripts_metadata_path));
- ERR_FAIL_COND(!GodotSharpBuilds::build_project_blocking(build_config));
+ // Turn export features into defines
+ Vector<String> godot_defines;
+ for (Set<String>::Element *E = p_features.front(); E; E = E->next()) {
+ godot_defines.push_back(E->get());
+ }
+ ERR_FAIL_COND(!GodotSharpBuilds::build_project_blocking(build_config, godot_defines));
// Add dependency assemblies
@@ -120,11 +125,21 @@ void GodotSharpExport::_export_begin(const Set<String> &p_features, bool p_debug
bool load_success = GDMono::get_singleton()->load_assembly_from(project_dll_name,
project_dll_src_path, &scripts_assembly, /* refonly: */ true);
- ERR_EXPLAIN("Cannot load refonly assembly: " + project_dll_name);
+ ERR_EXPLAIN("Cannot load assembly (refonly): " + project_dll_name);
ERR_FAIL_COND(!load_success);
Vector<String> search_dirs;
- GDMonoAssembly::fill_search_dirs(search_dirs, build_config);
+ String templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG);
+ String android_bcl_dir = templates_dir.plus_file("android-bcl");
+
+ String custom_lib_dir;
+
+ if (p_features.find("Android") && DirAccess::exists(android_bcl_dir)) {
+ custom_lib_dir = android_bcl_dir;
+ }
+
+ GDMonoAssembly::fill_search_dirs(search_dirs, build_config, custom_lib_dir);
+
Error depend_error = _get_assembly_dependencies(scripts_assembly, search_dirs, dependencies);
ERR_FAIL_COND(depend_error != OK);
}
@@ -147,7 +162,7 @@ void GodotSharpExport::_export_begin(const Set<String> &p_features, bool p_debug
int i = 0;
for (const Set<String>::Element *E = p_features.front(); E; E = E->next()) {
MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E->get());
- mono_array_set(features, MonoString *, i, boxed);
+ mono_array_setref(features, i, boxed);
i++;
}
@@ -229,8 +244,10 @@ Error GodotSharpExport::_get_assembly_dependencies(GDMonoAssembly *p_assembly, c
r_dependencies.insert(ref_name, ref_assembly->get_path());
Error err = _get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies);
- if (err != OK)
- return err;
+ if (err != OK) {
+ ERR_EXPLAIN("Cannot load one of the dependencies for the assembly: " + ref_name);
+ ERR_FAIL_V(err);
+ }
}
return OK;
diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp
index 21ce9ca5c4..5d9e39b6c2 100644
--- a/modules/mono/editor/mono_bottom_panel.cpp
+++ b/modules/mono/editor/mono_bottom_panel.cpp
@@ -175,7 +175,10 @@ void MonoBottomPanel::_build_project_pressed() {
ERR_FAIL_COND(copy_err != OK);
}
- bool build_success = GodotSharpBuilds::get_singleton()->build_project_blocking("Tools");
+ Vector<String> godot_defines;
+ godot_defines.push_back(OS::get_singleton()->get_name());
+ godot_defines.push_back((sizeof(void *) == 4 ? "32" : "64"));
+ bool build_success = GodotSharpBuilds::get_singleton()->build_project_blocking("Tools", godot_defines);
if (build_success) {
// Notify running game for hot-reload
diff --git a/modules/mono/glue/Managed/Files/AABB.cs b/modules/mono/glue/Managed/Files/AABB.cs
index 33b2b46712..a2ebbc0736 100644
--- a/modules/mono/glue/Managed/Files/AABB.cs
+++ b/modules/mono/glue/Managed/Files/AABB.cs
@@ -414,6 +414,21 @@ namespace Godot
_position = position;
_size = size;
}
+ public AABB(Vector3 position, real_t width, real_t height, real_t depth)
+ {
+ _position = position;
+ _size = new Vector3(width, height, depth);
+ }
+ public AABB(real_t x, real_t y, real_t z, Vector3 size)
+ {
+ _position = new Vector3(x, y, z);
+ _size = size;
+ }
+ public AABB(real_t x, real_t y, real_t z, real_t width, real_t height, real_t depth)
+ {
+ _position = new Vector3(x, y, z);
+ _size = new Vector3(width, height, depth);
+ }
public static bool operator ==(AABB left, AABB right)
{
diff --git a/modules/mono/glue/Managed/Files/Basis.cs b/modules/mono/glue/Managed/Files/Basis.cs
index ac9576cebd..9cc31a0557 100644
--- a/modules/mono/glue/Managed/Files/Basis.cs
+++ b/modules/mono/glue/Managed/Files/Basis.cs
@@ -260,13 +260,13 @@ namespace Godot
Vector3 euler;
euler.z = 0.0f;
- real_t mxy = m.Row1[2];
+ real_t mzy = m.Row1[2];
- if (mxy < 1.0f)
+ if (mzy < 1.0f)
{
- if (mxy > -1.0f)
+ if (mzy > -1.0f)
{
- euler.x = Mathf.Asin(-mxy);
+ euler.x = Mathf.Asin(-mzy);
euler.y = Mathf.Atan2(m.Row0[2], m.Row2[2]);
euler.z = Mathf.Atan2(m.Row1[0], m.Row1[1]);
}
@@ -418,19 +418,11 @@ namespace Godot
public Basis Scaled(Vector3 scale)
{
- var m = this;
-
- m.Row0[0] *= scale.x;
- m.Row0[1] *= scale.x;
- m.Row0[2] *= scale.x;
- m.Row1[0] *= scale.y;
- m.Row1[1] *= scale.y;
- m.Row1[2] *= scale.y;
- m.Row2[0] *= scale.z;
- m.Row2[1] *= scale.z;
- m.Row2[2] *= scale.z;
-
- return m;
+ var b = this;
+ b.Row0 *= scale.x;
+ b.Row1 *= scale.y;
+ b.Row2 *= scale.z;
+ return b;
}
public real_t Tdotx(Vector3 with)
@@ -583,31 +575,29 @@ namespace Godot
public Basis(Vector3 axis, real_t phi)
{
- var axis_sq = new Vector3(axis.x * axis.x, axis.y * axis.y, axis.z * axis.z);
-
+ Vector3 axisSq = new Vector3(axis.x * axis.x, axis.y * axis.y, axis.z * axis.z);
real_t cosine = Mathf.Cos(phi);
+ Row0.x = axisSq.x + cosine * (1.0f - axisSq.x);
+ Row1.y = axisSq.y + cosine * (1.0f - axisSq.y);
+ Row2.z = axisSq.z + cosine * (1.0f - axisSq.z);
+
real_t sine = Mathf.Sin(phi);
+ real_t t = 1.0f - cosine;
- Row0 = new Vector3
- (
- axis_sq.x + cosine * (1.0f - axis_sq.x),
- axis.x * axis.y * (1.0f - cosine) - axis.z * sine,
- axis.z * axis.x * (1.0f - cosine) + axis.y * sine
- );
+ real_t xyzt = axis.x * axis.y * t;
+ real_t zyxs = axis.z * sine;
+ Row0.y = xyzt - zyxs;
+ Row1.x = xyzt + zyxs;
- Row1 = new Vector3
- (
- axis.x * axis.y * (1.0f - cosine) + axis.z * sine,
- axis_sq.y + cosine * (1.0f - axis_sq.y),
- axis.y * axis.z * (1.0f - cosine) - axis.x * sine
- );
+ xyzt = axis.x * axis.z * t;
+ zyxs = axis.y * sine;
+ Row0.z = xyzt + zyxs;
+ Row2.x = xyzt - zyxs;
- Row2 = new Vector3
- (
- axis.z * axis.x * (1.0f - cosine) - axis.y * sine,
- axis.y * axis.z * (1.0f - cosine) + axis.x * sine,
- axis_sq.z + cosine * (1.0f - axis_sq.z)
- );
+ xyzt = axis.y * axis.z * t;
+ zyxs = axis.x * sine;
+ Row1.z = xyzt - zyxs;
+ Row2.y = xyzt + zyxs;
}
public Basis(Vector3 column0, Vector3 column1, Vector3 column2)
@@ -622,11 +612,12 @@ namespace Godot
// We need to assign the struct fields here first so we can't do it that way...
}
- internal Basis(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz)
+ // Arguments are named such that xy is equal to calling x.y
+ internal Basis(real_t xx, real_t yx, real_t zx, real_t xy, real_t yy, real_t zy, real_t xz, real_t yz, real_t zz)
{
- Row0 = new Vector3(xx, xy, xz);
- Row1 = new Vector3(yx, yy, yz);
- Row2 = new Vector3(zx, zy, zz);
+ Row0 = new Vector3(xx, yx, zx);
+ Row1 = new Vector3(xy, yy, zy);
+ Row2 = new Vector3(xz, yz, zz);
}
public static Basis operator *(Basis left, Basis right)
diff --git a/modules/mono/glue/Managed/Files/Mathf.cs b/modules/mono/glue/Managed/Files/Mathf.cs
index ff26c7fddf..2d8c63fe7f 100644
--- a/modules/mono/glue/Managed/Files/Mathf.cs
+++ b/modules/mono/glue/Managed/Files/Mathf.cs
@@ -44,9 +44,9 @@ namespace Godot
return (real_t)Math.Atan(s);
}
- public static real_t Atan2(real_t x, real_t y)
+ public static real_t Atan2(real_t y, real_t x)
{
- return (real_t)Math.Atan2(x, y);
+ return (real_t)Math.Atan2(y, x);
}
public static Vector2 Cartesian2Polar(real_t x, real_t y)
@@ -210,6 +210,11 @@ namespace Godot
return a < b ? a : b;
}
+ public static real_t MoveToward(real_t from, real_t to, real_t delta)
+ {
+ return Abs(to - from) <= delta ? to : from + Sign(to - from) * delta;
+ }
+
public static int NearestPo2(int value)
{
value--;
diff --git a/modules/mono/glue/Managed/Files/Transform2D.cs b/modules/mono/glue/Managed/Files/Transform2D.cs
index f7bb41d523..33ff286769 100644
--- a/modules/mono/glue/Managed/Files/Transform2D.cs
+++ b/modules/mono/glue/Managed/Files/Transform2D.cs
@@ -298,6 +298,7 @@ namespace Godot
origin = originPos;
}
+ // Arguments are named such that xy is equal to calling x.y
public Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy)
{
x = new Vector2(xx, xy);
diff --git a/modules/mono/glue/Managed/Files/Vector2.cs b/modules/mono/glue/Managed/Files/Vector2.cs
index bb1950e1a8..a7f26283a7 100644
--- a/modules/mono/glue/Managed/Files/Vector2.cs
+++ b/modules/mono/glue/Managed/Files/Vector2.cs
@@ -186,6 +186,14 @@ namespace Godot
return res;
}
+ public Vector2 MoveToward(Vector2 to, real_t delta)
+ {
+ var v = this;
+ var vd = to - v;
+ var len = vd.Length();
+ return len <= delta || len < Mathf.Epsilon ? to : v + vd / len * delta;
+ }
+
public Vector2 Normalized()
{
var v = this;
diff --git a/modules/mono/glue/Managed/Files/Vector3.cs b/modules/mono/glue/Managed/Files/Vector3.cs
index 283cb6341a..16803ae55c 100644
--- a/modules/mono/glue/Managed/Files/Vector3.cs
+++ b/modules/mono/glue/Managed/Files/Vector3.cs
@@ -190,6 +190,14 @@ namespace Godot
);
}
+ public Vector3 MoveToward(Vector3 to, real_t delta)
+ {
+ var v = this;
+ var vd = to - v;
+ var len = vd.Length();
+ return len <= delta || len < Mathf.Epsilon ? to : v + vd / len * delta;
+ }
+
public Axis MaxAxis()
{
return x < y ? (y < z ? Axis.Z : Axis.Y) : (x < z ? Axis.Z : Axis.X);
diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp
index 7385014a53..75b2dfce9a 100644
--- a/modules/mono/glue/base_object_glue.cpp
+++ b/modules/mono/glue/base_object_glue.cpp
@@ -166,7 +166,7 @@ MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) {
int i = 0;
for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E->get().name);
- mono_array_set(result, MonoString *, i, boxed);
+ mono_array_setref(result, i, boxed);
i++;
}
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 19e49d29f9..7699e0d0cd 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -251,17 +251,19 @@ void GDMono::initialize() {
String bundled_config_dir = GodotSharpDirs::get_data_mono_etc_dir();
#ifdef TOOLS_ENABLED
- if (DirAccess::exists(bundled_assembly_rootdir) && DirAccess::exists(bundled_config_dir)) {
+ if (DirAccess::exists(bundled_assembly_rootdir)) {
assembly_rootdir = bundled_assembly_rootdir;
+ }
+
+ if (DirAccess::exists(bundled_config_dir)) {
config_dir = bundled_config_dir;
}
#ifdef WINDOWS_ENABLED
if (assembly_rootdir.empty() || config_dir.empty()) {
+ ERR_PRINT("Cannot find Mono in the registry");
// Assertion: if they are not set, then they weren't found in the registry
CRASH_COND(mono_reg_info.assembly_dir.length() > 0 || mono_reg_info.config_dir.length() > 0);
-
- ERR_PRINT("Cannot find Mono in the registry");
}
#endif // WINDOWS_ENABLED
@@ -807,6 +809,8 @@ Error GDMono::_unload_scripts_domain() {
mono_gc_collect(mono_gc_max_generation());
+ GDMonoUtils::clear_godot_api_cache();
+
_domain_assemblies_cleanup(mono_domain_get_id(scripts_domain));
core_api_assembly = NULL;
@@ -926,6 +930,7 @@ Error GDMono::reload_scripts_domain() {
Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
CRASH_COND(p_domain == NULL);
+ CRASH_COND(p_domain == SCRIPTS_DOMAIN); // Should use _unload_scripts_domain() instead
String domain_name = mono_domain_get_friendly_name(p_domain);
@@ -1078,8 +1083,6 @@ GDMono::~GDMono() {
}
assemblies.clear();
- GDMonoUtils::clear_cache();
-
print_verbose("Mono: Runtime cleanup...");
mono_jit_cleanup(root_domain);
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 8fec28b186..f1f0015ac9 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -46,11 +46,17 @@ bool GDMonoAssembly::in_preload = false;
Vector<String> GDMonoAssembly::search_dirs;
-void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config) {
+void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config, const String &p_custom_bcl_dir) {
- const char *rootdir = mono_assembly_getrootdir();
- if (rootdir) {
- String framework_dir = String::utf8(rootdir).plus_file("mono").plus_file("4.5");
+ String framework_dir;
+
+ if (!p_custom_bcl_dir.empty()) {
+ framework_dir = p_custom_bcl_dir;
+ } else if (mono_assembly_getrootdir()) {
+ framework_dir = String::utf8(mono_assembly_getrootdir()).plus_file("mono").plus_file("4.5");
+ }
+
+ if (!framework_dir.empty()) {
r_search_dirs.push_back(framework_dir);
r_search_dirs.push_back(framework_dir.plus_file("Facades"));
}
diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h
index 32432af37d..39749dfc1d 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.h
+++ b/modules/mono/mono_gd/gd_mono_assembly.h
@@ -122,7 +122,7 @@ public:
GDMonoClass *get_object_derived_class(const StringName &p_class);
- static void fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config = String());
+ static void fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config = String(), const String &p_custom_bcl_dir = String());
static GDMonoAssembly *load_from(const String &p_name, const String &p_path, bool p_refonly);
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index c462b8f71d..87157ed233 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -1019,7 +1019,7 @@ MonoArray *PoolStringArray_to_mono_array(const PoolStringArray &p_array) {
for (int i = 0; i < p_array.size(); i++) {
MonoString *boxed = mono_string_from_godot(r[i]);
- mono_array_set(ret, MonoString *, i, boxed);
+ mono_array_setref(ret, i, boxed);
}
return ret;
diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp
index f290c6c8ac..968b316a3e 100644
--- a/modules/mono/mono_gd/gd_mono_method.cpp
+++ b/modules/mono/mono_gd/gd_mono_method.cpp
@@ -109,7 +109,7 @@ MonoObject *GDMonoMethod::invoke(MonoObject *p_object, const Variant **p_params,
for (int i = 0; i < params_count; i++) {
MonoObject *boxed_param = GDMonoMarshal::variant_to_mono_object(p_params[i], param_types[i]);
- mono_array_set(params, MonoObject *, i, boxed_param);
+ mono_array_setref(params, i, boxed_param);
}
MonoException *exc = NULL;
diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp
index 5842e26241..f1da00638f 100644
--- a/modules/mono/mono_gd/gd_mono_property.cpp
+++ b/modules/mono/mono_gd/gd_mono_property.cpp
@@ -142,7 +142,7 @@ bool GDMonoProperty::has_setter() {
void GDMonoProperty::set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc) {
MonoMethod *prop_method = mono_property_get_set_method(mono_property);
MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), 1);
- mono_array_set(params, MonoObject *, 0, p_value);
+ mono_array_setref(params, 0, p_value);
MonoException *exc = NULL;
GDMonoUtils::runtime_invoke_array(prop_method, p_object, params, &exc);
if (exc) {
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 413c8cba85..1b32f1126e 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -50,6 +50,7 @@ MonoCache mono_cache;
#define CACHE_AND_CHECK(m_var, m_val) \
{ \
+ CRASH_COND(m_var != NULL); \
m_var = m_val; \
if (!m_var) { \
ERR_EXPLAIN("Mono Cache: Member " #m_var " is null"); \
@@ -65,7 +66,9 @@ MonoCache mono_cache;
#define CACHE_METHOD_THUNK_AND_CHECK(m_class, m_method, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.methodthunk_##m_class##_##m_method, m_val)
#define CACHE_PROPERTY_AND_CHECK(m_class, m_property, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.property_##m_class##_##m_property, m_val)
-void MonoCache::clear_members() {
+void MonoCache::clear_corlib_cache() {
+
+ corlib_cache_updated = false;
class_MonoObject = NULL;
class_bool = NULL;
@@ -93,6 +96,11 @@ void MonoCache::clear_members() {
#endif
class_KeyNotFoundException = NULL;
+}
+
+void MonoCache::clear_godot_api_cache() {
+
+ godot_api_cache_updated = false;
rawclass_Dictionary = NULL;
@@ -176,12 +184,6 @@ void MonoCache::clear_members() {
task_scheduler_handle = Ref<MonoGCHandle>();
}
-void MonoCache::cleanup() {
-
- corlib_cache_updated = false;
- godot_api_cache_updated = false;
-}
-
#define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class))
#define GODOT_API_NS_CLAS(m_ns, m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(m_ns, #m_class))
@@ -281,13 +283,10 @@ void update_godot_api_cache() {
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, (ArrayGetElementType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("ArrayGetElementType", 2));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, (DictionaryGetKeyValueTypes)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("DictionaryGetKeyValueTypes", 3));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, (ArrayGetElementType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("ArrayGetElementType", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, (DictionaryGetKeyValueTypes)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("DictionaryGetKeyValueTypes", 3));
-
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType, (GenericIEnumerableIsAssignableFromType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIEnumerableIsAssignableFromType", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType, (GenericIDictionaryIsAssignableFromType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIDictionaryIsAssignableFromType", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info, (GenericIEnumerableIsAssignableFromType_with_info)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIEnumerableIsAssignableFromType", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info, (GenericIEnumerableIsAssignableFromType_with_info)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIDictionaryIsAssignableFromType", 3));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info, (GenericIDictionaryIsAssignableFromType_with_info)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIDictionaryIsAssignableFromType", 3));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericArrayType, (MakeGenericArrayType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("MakeGenericArrayType", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericDictionaryType, (MakeGenericDictionaryType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("MakeGenericDictionaryType", 2));
@@ -310,11 +309,6 @@ void update_godot_api_cache() {
mono_cache.godot_api_cache_updated = true;
}
-void clear_cache() {
- mono_cache.cleanup();
- mono_cache.clear_members();
-}
-
MonoObject *unmanaged_get_managed(Object *unmanaged) {
if (!unmanaged)
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index ee239be959..00e1ffdd31 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -218,14 +218,12 @@ struct MonoCache {
bool corlib_cache_updated;
bool godot_api_cache_updated;
- void clear_members();
- void cleanup();
+ void clear_corlib_cache();
+ void clear_godot_api_cache();
MonoCache() {
- corlib_cache_updated = false;
- godot_api_cache_updated = false;
-
- clear_members();
+ clear_corlib_cache();
+ clear_godot_api_cache();
}
};
@@ -233,7 +231,13 @@ extern MonoCache mono_cache;
void update_corlib_cache();
void update_godot_api_cache();
-void clear_cache();
+
+inline void clear_corlib_cache() {
+ mono_cache.clear_corlib_cache();
+}
+inline void clear_godot_api_cache() {
+ mono_cache.clear_godot_api_cache();
+}
_FORCE_INLINE_ void hash_combine(uint32_t &p_hash, const uint32_t &p_with_hash) {
p_hash ^= p_with_hash + 0x9e3779b9 + (p_hash << 6) + (p_hash >> 2);
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index 5d37e8212f..0e1739b754 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -95,7 +95,7 @@ Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argc
for (int i = 0; i < signal_argc; i++) {
MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_args[i]);
- mono_array_set(signal_args, MonoObject *, i, boxed);
+ mono_array_setref(signal_args, i, boxed);
}
MonoException *exc = NULL;
diff --git a/modules/opus/audio_stream_opus.cpp b/modules/opus/audio_stream_opus.cpp
index fda82295de..70d0f770d8 100644
--- a/modules/opus/audio_stream_opus.cpp
+++ b/modules/opus/audio_stream_opus.cpp
@@ -313,7 +313,7 @@ int AudioStreamPlaybackOpus::mix(int16_t *p_buffer, int p_frames) {
bool ok = op_pcm_seek(opus_file, (loop_restart_time * osrate) + pre_skip) == 0;
if (!ok) {
playing = false;
- ERR_PRINT("loop restart time rejected")
+ ERR_PRINT("Loop restart time rejected");
}
frames_mixed = (loop_restart_time * osrate) + pre_skip;
diff --git a/modules/recast/navigation_mesh_editor_plugin.cpp b/modules/recast/navigation_mesh_editor_plugin.cpp
index 62108620bd..9f30806925 100644
--- a/modules/recast/navigation_mesh_editor_plugin.cpp
+++ b/modules/recast/navigation_mesh_editor_plugin.cpp
@@ -54,18 +54,18 @@ void NavigationMeshEditor::_notification(int p_option) {
}
void NavigationMeshEditor::_bake_pressed() {
+ button_bake->set_pressed(false);
ERR_FAIL_COND(!node);
const String conf_warning = node->get_configuration_warning();
if (!conf_warning.empty()) {
err_dialog->set_text(conf_warning);
err_dialog->popup_centered_minsize();
- button_bake->set_pressed(false);
return;
}
- NavigationMeshGenerator::clear(node->get_navigation_mesh());
- NavigationMeshGenerator::bake(node->get_navigation_mesh(), node);
+ EditorNavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh());
+ EditorNavigationMeshGenerator::get_singleton()->bake(node->get_navigation_mesh(), node);
node->update_gizmo();
}
@@ -73,7 +73,7 @@ void NavigationMeshEditor::_bake_pressed() {
void NavigationMeshEditor::_clear_pressed() {
if (node)
- NavigationMeshGenerator::clear(node->get_navigation_mesh());
+ EditorNavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh());
button_bake->set_pressed(false);
bake_info->set_text("");
diff --git a/modules/recast/navigation_mesh_generator.cpp b/modules/recast/navigation_mesh_generator.cpp
index 79ccbbb030..0cac07e3e7 100644
--- a/modules/recast/navigation_mesh_generator.cpp
+++ b/modules/recast/navigation_mesh_generator.cpp
@@ -29,14 +29,31 @@
/*************************************************************************/
#include "navigation_mesh_generator.h"
-
-void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) {
+#include "core/math/quick_hull.h"
+#include "core/os/thread.h"
+#include "editor/editor_settings.h"
+#include "scene/3d/collision_shape.h"
+#include "scene/3d/mesh_instance.h"
+#include "scene/3d/physics_body.h"
+#include "scene/resources/box_shape.h"
+#include "scene/resources/capsule_shape.h"
+#include "scene/resources/concave_polygon_shape.h"
+#include "scene/resources/convex_polygon_shape.h"
+#include "scene/resources/cylinder_shape.h"
+#include "scene/resources/plane_shape.h"
+#include "scene/resources/primitive_meshes.h"
+#include "scene/resources/shape.h"
+#include "scene/resources/sphere_shape.h"
+
+EditorNavigationMeshGenerator *EditorNavigationMeshGenerator::singleton = NULL;
+
+void EditorNavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) {
p_verticies.push_back(p_vec3.x);
p_verticies.push_back(p_vec3.y);
p_verticies.push_back(p_vec3.z);
}
-void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+void EditorNavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
int current_vertex_count = 0;
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
@@ -91,23 +108,132 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
}
}
-void NavigationMeshGenerator::_parse_geometry(const Transform &p_base_inverse, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices) {
+void EditorNavigationMeshGenerator::_add_faces(const PoolVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+ int face_count = p_faces.size() / 3;
+ int current_vertex_count = p_verticies.size() / 3;
+
+ for (int j = 0; j < face_count; j++) {
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 0]), p_verticies);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 1]), p_verticies);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 2]), p_verticies);
+
+ p_indices.push_back(current_vertex_count + (j * 3 + 0));
+ p_indices.push_back(current_vertex_count + (j * 3 + 2));
+ p_indices.push_back(current_vertex_count + (j * 3 + 1));
+ }
+}
+
+void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask) {
- if (Object::cast_to<MeshInstance>(p_node)) {
+ if (Object::cast_to<MeshInstance>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(p_node);
Ref<Mesh> mesh = mesh_instance->get_mesh();
if (mesh.is_valid()) {
- _add_mesh(mesh, p_base_inverse * mesh_instance->get_global_transform(), p_verticies, p_indices);
+ _add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_verticies, p_indices);
}
}
+ if (Object::cast_to<StaticBody>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_MESH_INSTANCES) {
+ StaticBody *static_body = Object::cast_to<StaticBody>(p_node);
+
+ if (static_body->get_collision_layer() & p_collision_mask) {
+
+ for (int i = 0; i < p_node->get_child_count(); ++i) {
+ Node *child = p_node->get_child(i);
+ if (Object::cast_to<CollisionShape>(child)) {
+ CollisionShape *col_shape = Object::cast_to<CollisionShape>(child);
+
+ Transform transform = p_accumulated_transform * static_body->get_transform() * col_shape->get_transform();
+
+ Ref<Mesh> mesh;
+ Ref<Shape> s = col_shape->get_shape();
+
+ BoxShape *box = Object::cast_to<BoxShape>(*s);
+ if (box) {
+ Ref<CubeMesh> cube_mesh;
+ cube_mesh.instance();
+ cube_mesh->set_size(box->get_extents() * 2.0);
+ mesh = cube_mesh;
+ }
+
+ CapsuleShape *capsule = Object::cast_to<CapsuleShape>(*s);
+ if (capsule) {
+ Ref<CapsuleMesh> capsule_mesh;
+ capsule_mesh.instance();
+ capsule_mesh->set_radius(capsule->get_radius());
+ capsule_mesh->set_mid_height(capsule->get_height() / 2.0);
+ mesh = capsule_mesh;
+ }
+
+ CylinderShape *cylinder = Object::cast_to<CylinderShape>(*s);
+ if (cylinder) {
+ Ref<CylinderMesh> cylinder_mesh;
+ cylinder_mesh.instance();
+ cylinder_mesh->set_height(cylinder->get_height());
+ cylinder_mesh->set_bottom_radius(cylinder->get_radius());
+ cylinder_mesh->set_top_radius(cylinder->get_radius());
+ mesh = cylinder_mesh;
+ }
+
+ SphereShape *sphere = Object::cast_to<SphereShape>(*s);
+ if (sphere) {
+ Ref<SphereMesh> sphere_mesh;
+ sphere_mesh.instance();
+ sphere_mesh->set_radius(sphere->get_radius());
+ sphere_mesh->set_height(sphere->get_radius() * 2.0);
+ mesh = sphere_mesh;
+ }
+
+ ConcavePolygonShape *concave_polygon = Object::cast_to<ConcavePolygonShape>(*s);
+ if (concave_polygon) {
+ _add_faces(concave_polygon->get_faces(), transform, p_verticies, p_indices);
+ }
+
+ ConvexPolygonShape *convex_polygon = Object::cast_to<ConvexPolygonShape>(*s);
+ if (convex_polygon) {
+ Vector<Vector3> varr = Variant(convex_polygon->get_points());
+ Geometry::MeshData md;
+
+ Error err = QuickHull::build(varr, md);
+
+ if (err == OK) {
+ PoolVector3Array faces;
+
+ for (int j = 0; j < md.faces.size(); ++j) {
+ Geometry::MeshData::Face face = md.faces[j];
+
+ for (int k = 2; k < face.indices.size(); ++k) {
+ faces.push_back(md.vertices[face.indices[0]]);
+ faces.push_back(md.vertices[face.indices[k - 1]]);
+ faces.push_back(md.vertices[face.indices[k]]);
+ }
+ }
+
+ _add_faces(faces, transform, p_verticies, p_indices);
+ }
+ }
+
+ if (mesh.is_valid()) {
+ _add_mesh(mesh, transform, p_verticies, p_indices);
+ }
+ }
+ }
+ }
+ }
+
+ if (Object::cast_to<Spatial>(p_node)) {
+
+ Spatial *spatial = Object::cast_to<Spatial>(p_node);
+ p_accumulated_transform = p_accumulated_transform * spatial->get_transform();
+ }
+
for (int i = 0; i < p_node->get_child_count(); i++) {
- _parse_geometry(p_base_inverse, p_node->get_child(i), p_verticies, p_indices);
+ _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_verticies, p_indices, p_generate_from, p_collision_mask);
}
}
-void NavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh) {
+void EditorNavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh) {
PoolVector<Vector3> nav_vertices;
@@ -135,7 +261,7 @@ void NavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_mesh(con
}
}
-void NavigationMeshGenerator::_build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep,
+void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep,
rcHeightfield *hf, rcCompactHeightfield *chf, rcContourSet *cset, rcPolyMesh *poly_mesh, rcPolyMeshDetail *detail_mesh,
Vector<float> &vertices, Vector<int> &indices) {
rcContext ctx;
@@ -257,7 +383,18 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(Ref<NavigationMesh>
detail_mesh = 0;
}
-void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) {
+EditorNavigationMeshGenerator *EditorNavigationMeshGenerator::get_singleton() {
+ return singleton;
+}
+
+EditorNavigationMeshGenerator::EditorNavigationMeshGenerator() {
+ singleton = this;
+}
+
+EditorNavigationMeshGenerator::~EditorNavigationMeshGenerator() {
+}
+
+void EditorNavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) {
ERR_FAIL_COND(!p_nav_mesh.is_valid());
@@ -267,7 +404,7 @@ void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node)
Vector<float> vertices;
Vector<int> indices;
- _parse_geometry(Object::cast_to<Spatial>(p_node)->get_global_transform().affine_inverse(), p_node, vertices, indices);
+ _parse_geometry(Object::cast_to<Spatial>(p_node)->get_transform().affine_inverse(), p_node, vertices, indices, p_nav_mesh->get_parsed_geometry_type(), p_nav_mesh->get_collision_mask());
if (vertices.size() > 0 && indices.size() > 0) {
@@ -297,9 +434,14 @@ void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node)
ep.step(TTR("Done!"), 11);
}
-void NavigationMeshGenerator::clear(Ref<NavigationMesh> p_nav_mesh) {
+void EditorNavigationMeshGenerator::clear(Ref<NavigationMesh> p_nav_mesh) {
if (p_nav_mesh.is_valid()) {
p_nav_mesh->clear_polygons();
p_nav_mesh->set_vertices(PoolVector<Vector3>());
}
}
+
+void EditorNavigationMeshGenerator::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("bake", "nav_mesh", "root_node"), &EditorNavigationMeshGenerator::bake);
+ ClassDB::bind_method(D_METHOD("clear", "nav_mesh"), &EditorNavigationMeshGenerator::clear);
+}
diff --git a/modules/recast/navigation_mesh_generator.h b/modules/recast/navigation_mesh_generator.h
index 3adc01ccda..30a6e3c835 100644
--- a/modules/recast/navigation_mesh_generator.h
+++ b/modules/recast/navigation_mesh_generator.h
@@ -31,20 +31,23 @@
#ifndef NAVIGATION_MESH_GENERATOR_H
#define NAVIGATION_MESH_GENERATOR_H
-#include "core/os/thread.h"
#include "editor/editor_node.h"
-#include "editor/editor_settings.h"
-#include "scene/3d/mesh_instance.h"
#include "scene/3d/navigation_mesh.h"
-#include "scene/resources/shape.h"
#include <Recast.h>
-class NavigationMeshGenerator {
+class EditorNavigationMeshGenerator : public Object {
+ GDCLASS(EditorNavigationMeshGenerator, Object);
+
+ static EditorNavigationMeshGenerator *singleton;
+
protected:
+ static void _bind_methods();
+
static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies);
static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
- static void _parse_geometry(const Transform &p_base_inverse, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices);
+ static void _add_faces(const PoolVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
+ static void _parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask);
static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh);
static void _build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep,
@@ -52,8 +55,13 @@ protected:
rcPolyMeshDetail *detail_mesh, Vector<float> &vertices, Vector<int> &indices);
public:
- static void bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node);
- static void clear(Ref<NavigationMesh> p_nav_mesh);
+ static EditorNavigationMeshGenerator *get_singleton();
+
+ EditorNavigationMeshGenerator();
+ ~EditorNavigationMeshGenerator();
+
+ void bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node);
+ void clear(Ref<NavigationMesh> p_nav_mesh);
};
#endif // NAVIGATION_MESH_GENERATOR_H
diff --git a/modules/recast/register_types.cpp b/modules/recast/register_types.cpp
index f272cc4236..247d7f6144 100644
--- a/modules/recast/register_types.cpp
+++ b/modules/recast/register_types.cpp
@@ -32,8 +32,23 @@
#include "navigation_mesh_editor_plugin.h"
+#ifdef TOOLS_ENABLED
+EditorNavigationMeshGenerator *_nav_mesh_generator = NULL;
+#endif
+
void register_recast_types() {
+#ifdef TOOLS_ENABLED
EditorPlugins::add_by_type<NavigationMeshEditorPlugin>();
+ _nav_mesh_generator = memnew(EditorNavigationMeshGenerator);
+ ClassDB::register_class<EditorNavigationMeshGenerator>();
+ Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationMeshGenerator", EditorNavigationMeshGenerator::get_singleton()));
+#endif
}
-void unregister_recast_types() {}
+void unregister_recast_types() {
+#ifdef TOOLS_ENABLED
+ if (_nav_mesh_generator) {
+ memdelete(_nav_mesh_generator);
+ }
+#endif
+}
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index 292ac5e97e..b5f4718c72 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -273,6 +273,7 @@ void AudioStreamOGGVorbis::_bind_methods() {
AudioStreamOGGVorbis::AudioStreamOGGVorbis() {
data = NULL;
+ data_len = 0;
length = 0;
sample_rate = 1;
channels = 1;
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index bd84a28c84..a9340b1498 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -122,13 +122,13 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
}
if (idxG == -1) {
- ERR_PRINT("TinyEXR: G channel not found.")
+ ERR_PRINT("TinyEXR: G channel not found.");
// @todo { free exr_image }
return ERR_FILE_CORRUPT;
}
if (idxB == -1) {
- ERR_PRINT("TinyEXR: B channel not found.")
+ ERR_PRINT("TinyEXR: B channel not found.");
// @todo { free exr_image }
return ERR_FILE_CORRUPT;
}
diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
index 74d5f29c02..21e8a38c16 100644
--- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
+++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
@@ -102,114 +102,117 @@
</constant>
<constant name="MATH_RANGE_LERP" value="28" enum="BuiltinFunc">
</constant>
- <constant name="MATH_DECTIME" value="29" enum="BuiltinFunc">
+ <constant name="MATH_MOVE_TOWARD" value="29" enum="BuiltinFunc">
+ Moves the number toward a value, based on the third input.
+ </constant>
+ <constant name="MATH_DECTIME" value="30" enum="BuiltinFunc">
Return the result of 'value' decreased by 'step' * 'amount'.
</constant>
- <constant name="MATH_RANDOMIZE" value="30" enum="BuiltinFunc">
+ <constant name="MATH_RANDOMIZE" value="31" enum="BuiltinFunc">
Randomize the seed (or the internal state) of the random number generator. Current implementation reseeds using a number based on time.
</constant>
- <constant name="MATH_RAND" value="31" enum="BuiltinFunc">
+ <constant name="MATH_RAND" value="32" enum="BuiltinFunc">
Return a random 32 bits integer value. To obtain a random value between 0 to N (where N is smaller than 2^32 - 1), you can use it with the remainder function.
</constant>
- <constant name="MATH_RANDF" value="32" enum="BuiltinFunc">
+ <constant name="MATH_RANDF" value="33" enum="BuiltinFunc">
Return a random floating-point value between 0 and 1. To obtain a random value between 0 to N, you can use it with multiplication.
</constant>
- <constant name="MATH_RANDOM" value="33" enum="BuiltinFunc">
+ <constant name="MATH_RANDOM" value="34" enum="BuiltinFunc">
Return a random floating-point value between the two inputs.
</constant>
- <constant name="MATH_SEED" value="34" enum="BuiltinFunc">
+ <constant name="MATH_SEED" value="35" enum="BuiltinFunc">
Set the seed for the random number generator.
</constant>
- <constant name="MATH_RANDSEED" value="35" enum="BuiltinFunc">
+ <constant name="MATH_RANDSEED" value="36" enum="BuiltinFunc">
Return a random value from the given seed, along with the new seed.
</constant>
- <constant name="MATH_DEG2RAD" value="36" enum="BuiltinFunc">
+ <constant name="MATH_DEG2RAD" value="37" enum="BuiltinFunc">
Convert the input from degrees to radians.
</constant>
- <constant name="MATH_RAD2DEG" value="37" enum="BuiltinFunc">
+ <constant name="MATH_RAD2DEG" value="38" enum="BuiltinFunc">
Convert the input from radians to degrees.
</constant>
- <constant name="MATH_LINEAR2DB" value="38" enum="BuiltinFunc">
+ <constant name="MATH_LINEAR2DB" value="39" enum="BuiltinFunc">
Convert the input from linear volume to decibel volume.
</constant>
- <constant name="MATH_DB2LINEAR" value="39" enum="BuiltinFunc">
+ <constant name="MATH_DB2LINEAR" value="40" enum="BuiltinFunc">
Convert the input from decibel volume to linear volume.
</constant>
- <constant name="MATH_POLAR2CARTESIAN" value="40" enum="BuiltinFunc">
+ <constant name="MATH_POLAR2CARTESIAN" value="41" enum="BuiltinFunc">
Converts a 2D point expressed in the polar coordinate system (a distance from the origin [code]r[/code] and an angle [code]th[/code]) to the cartesian coordinate system (x and y axis).
</constant>
- <constant name="MATH_CARTESIAN2POLAR" value="41" enum="BuiltinFunc">
+ <constant name="MATH_CARTESIAN2POLAR" value="42" enum="BuiltinFunc">
Converts a 2D point expressed in the cartesian coordinate system (x and y axis) to the polar coordinate system (a distance from the origin and an angle).
</constant>
- <constant name="MATH_WRAP" value="42" enum="BuiltinFunc">
+ <constant name="MATH_WRAP" value="43" enum="BuiltinFunc">
</constant>
- <constant name="MATH_WRAPF" value="43" enum="BuiltinFunc">
+ <constant name="MATH_WRAPF" value="44" enum="BuiltinFunc">
</constant>
- <constant name="LOGIC_MAX" value="44" enum="BuiltinFunc">
+ <constant name="LOGIC_MAX" value="45" enum="BuiltinFunc">
Return the greater of the two numbers, also known as their maximum.
</constant>
- <constant name="LOGIC_MIN" value="45" enum="BuiltinFunc">
+ <constant name="LOGIC_MIN" value="46" enum="BuiltinFunc">
Return the lesser of the two numbers, also known as their minimum.
</constant>
- <constant name="LOGIC_CLAMP" value="46" enum="BuiltinFunc">
+ <constant name="LOGIC_CLAMP" value="47" enum="BuiltinFunc">
Return the input clamped inside the given range, ensuring the result is never outside it. Equivalent to [code]min(max(input, range_low), range_high)[/code].
</constant>
- <constant name="LOGIC_NEAREST_PO2" value="47" enum="BuiltinFunc">
+ <constant name="LOGIC_NEAREST_PO2" value="48" enum="BuiltinFunc">
Return the nearest power of 2 to the input.
</constant>
- <constant name="OBJ_WEAKREF" value="48" enum="BuiltinFunc">
+ <constant name="OBJ_WEAKREF" value="49" enum="BuiltinFunc">
Create a [WeakRef] from the input.
</constant>
- <constant name="FUNC_FUNCREF" value="49" enum="BuiltinFunc">
+ <constant name="FUNC_FUNCREF" value="50" enum="BuiltinFunc">
Create a [FuncRef] from the input.
</constant>
- <constant name="TYPE_CONVERT" value="50" enum="BuiltinFunc">
+ <constant name="TYPE_CONVERT" value="51" enum="BuiltinFunc">
Convert between types.
</constant>
- <constant name="TYPE_OF" value="51" enum="BuiltinFunc">
+ <constant name="TYPE_OF" value="52" enum="BuiltinFunc">
Return the type of the input as an integer. Check [enum Variant.Type] for the integers that might be returned.
</constant>
- <constant name="TYPE_EXISTS" value="52" enum="BuiltinFunc">
+ <constant name="TYPE_EXISTS" value="53" enum="BuiltinFunc">
Checks if a type is registered in the [ClassDB].
</constant>
- <constant name="TEXT_CHAR" value="53" enum="BuiltinFunc">
+ <constant name="TEXT_CHAR" value="54" enum="BuiltinFunc">
Return a character with the given ascii value.
</constant>
- <constant name="TEXT_STR" value="54" enum="BuiltinFunc">
+ <constant name="TEXT_STR" value="55" enum="BuiltinFunc">
Convert the input to a string.
</constant>
- <constant name="TEXT_PRINT" value="55" enum="BuiltinFunc">
+ <constant name="TEXT_PRINT" value="56" enum="BuiltinFunc">
Print the given string to the output window.
</constant>
- <constant name="TEXT_PRINTERR" value="56" enum="BuiltinFunc">
+ <constant name="TEXT_PRINTERR" value="57" enum="BuiltinFunc">
Print the given string to the standard error output.
</constant>
- <constant name="TEXT_PRINTRAW" value="57" enum="BuiltinFunc">
+ <constant name="TEXT_PRINTRAW" value="58" enum="BuiltinFunc">
Print the given string to the standard output, without adding a newline.
</constant>
- <constant name="VAR_TO_STR" value="58" enum="BuiltinFunc">
+ <constant name="VAR_TO_STR" value="59" enum="BuiltinFunc">
Serialize a [Variant] to a string.
</constant>
- <constant name="STR_TO_VAR" value="59" enum="BuiltinFunc">
+ <constant name="STR_TO_VAR" value="60" enum="BuiltinFunc">
Deserialize a [Variant] from a string serialized using [code]VAR_TO_STR[/code].
</constant>
- <constant name="VAR_TO_BYTES" value="60" enum="BuiltinFunc">
+ <constant name="VAR_TO_BYTES" value="61" enum="BuiltinFunc">
Serialize a [Variant] to a [PoolByteArray].
</constant>
- <constant name="BYTES_TO_VAR" value="61" enum="BuiltinFunc">
+ <constant name="BYTES_TO_VAR" value="62" enum="BuiltinFunc">
Deserialize a [Variant] from a [PoolByteArray] serialized using [code]VAR_TO_BYTES[/code].
</constant>
- <constant name="COLORN" value="62" enum="BuiltinFunc">
+ <constant name="COLORN" value="63" enum="BuiltinFunc">
Return the [Color] with the given name and alpha ranging from 0 to 1. Note: names are defined in color_names.inc.
</constant>
- <constant name="MATH_SMOOTHSTEP" value="63" enum="BuiltinFunc">
+ <constant name="MATH_SMOOTHSTEP" value="64" enum="BuiltinFunc">
Return a number smoothly interpolated between the first two inputs, based on the third input. Similar to [code]MATH_LERP[/code], but interpolates faster at the beginning and slower at the end. Using Hermite interpolation formula:
[codeblock]
var t = clamp((weight - from) / (to - from), 0.0, 1.0)
return t * t * (3.0 - 2.0 * t)
[/codeblock]
</constant>
- <constant name="FUNC_MAX" value="64" enum="BuiltinFunc">
+ <constant name="FUNC_MAX" value="65" enum="BuiltinFunc">
The maximum value the [member function] property can have.
</constant>
</constants>
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 8f311d11f4..85fc867901 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -46,15 +46,7 @@ bool VisualScriptNode::is_breakpoint() const {
return breakpoint;
}
-void VisualScriptNode::_notification(int p_what) {
-
- if (p_what == NOTIFICATION_POSTINITIALIZE) {
- validate_input_default_values();
- }
-}
-
void VisualScriptNode::ports_changed_notify() {
- validate_input_default_values();
emit_signal("ports_changed");
}
@@ -273,11 +265,7 @@ void VisualScript::_node_ports_changed(int p_id) {
Function &func = functions[function];
Ref<VisualScriptNode> vsn = func.nodes[p_id].node;
- if (OS::get_singleton()->get_main_loop() &&
- Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop()) &&
- Engine::get_singleton()->is_editor_hint()) {
- vsn->validate_input_default_values(); //force validate default values when editing on editor
- }
+ vsn->validate_input_default_values();
//must revalidate all the functions
@@ -353,6 +341,7 @@ void VisualScript::add_node(const StringName &p_func, int p_id, const Ref<Visual
Ref<VisualScriptNode> vsn = p_node;
vsn->connect("ports_changed", this, "_node_ports_changed", varray(p_id));
vsn->scripts_used.insert(this);
+ vsn->validate_input_default_values(); // Validate when fully loaded
func.nodes[p_id] = nd;
}
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 91748d077b..89f32f54f7 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -54,7 +54,6 @@ class VisualScriptNode : public Resource {
void validate_input_default_values();
protected:
- void _notification(int p_what);
void ports_changed_notify();
static void _bind_methods();
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index d207656705..75b79f8929 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -68,6 +68,7 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
"lerp",
"inverse_lerp",
"range_lerp",
+ "move_toward",
"dectime",
"randomize",
"randi",
@@ -206,6 +207,7 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
case MATH_LERP:
case MATH_INVERSE_LERP:
case MATH_SMOOTHSTEP:
+ case MATH_MOVE_TOWARD:
case MATH_DECTIME:
case MATH_WRAP:
case MATH_WRAPF:
@@ -347,6 +349,14 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
else
return PropertyInfo(Variant::REAL, "weight");
} break;
+ case MATH_MOVE_TOWARD: {
+ if (p_idx == 0)
+ return PropertyInfo(Variant::REAL, "from");
+ else if (p_idx == 1)
+ return PropertyInfo(Variant::REAL, "to");
+ else
+ return PropertyInfo(Variant::REAL, "delta");
+ } break;
case MATH_DECTIME: {
if (p_idx == 0)
return PropertyInfo(Variant::REAL, "value");
@@ -580,6 +590,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case MATH_INVERSE_LERP:
case MATH_RANGE_LERP:
case MATH_SMOOTHSTEP:
+ case MATH_MOVE_TOWARD:
case MATH_DECTIME: {
t = Variant::REAL;
@@ -916,6 +927,13 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
VALIDATE_ARG_NUM(2);
*r_return = Math::smoothstep((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
+ case VisualScriptBuiltinFunc::MATH_MOVE_TOWARD: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ *r_return = Math::move_toward((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
+ } break;
case VisualScriptBuiltinFunc::MATH_DECTIME: {
VALIDATE_ARG_NUM(0);
@@ -1363,6 +1381,7 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(MATH_LERP);
BIND_ENUM_CONSTANT(MATH_INVERSE_LERP);
BIND_ENUM_CONSTANT(MATH_RANGE_LERP);
+ BIND_ENUM_CONSTANT(MATH_MOVE_TOWARD);
BIND_ENUM_CONSTANT(MATH_DECTIME);
BIND_ENUM_CONSTANT(MATH_RANDOMIZE);
BIND_ENUM_CONSTANT(MATH_RAND);
@@ -1453,6 +1472,7 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/inverse_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_INVERSE_LERP>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/range_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANGE_LERP>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/smoothstep", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SMOOTHSTEP>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/move_toward", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_MOVE_TOWARD>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/dectime", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DECTIME>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/randomize", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDOMIZE>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/rand", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RAND>);
diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h
index 50854c16b1..3e452cd94f 100644
--- a/modules/visual_script/visual_script_builtin_funcs.h
+++ b/modules/visual_script/visual_script_builtin_funcs.h
@@ -67,6 +67,7 @@ public:
MATH_LERP,
MATH_INVERSE_LERP,
MATH_RANGE_LERP,
+ MATH_MOVE_TOWARD,
MATH_DECTIME,
MATH_RANDOMIZE,
MATH_RAND,
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 5c408cf29e..f84f2c90cd 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -2111,6 +2111,9 @@ void VisualScriptEditor::clear_executing_line() {
void VisualScriptEditor::trim_trailing_whitespace() {
}
+void VisualScriptEditor::insert_final_newline() {
+}
+
void VisualScriptEditor::convert_indent_to_spaces() {
}
@@ -2218,7 +2221,7 @@ Control *VisualScriptEditor::get_edit_menu() {
void VisualScriptEditor::_change_base_type() {
- select_base_type->popup_create(true);
+ select_base_type->popup_create(true, true);
}
void VisualScriptEditor::clear_edit_menu() {
@@ -2726,93 +2729,98 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
Ref<VisualScriptFunctionCall> vsfc = vsn;
vsfc->set_function(p_text);
- VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
- if (tg.type == Variant::OBJECT) {
- vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE);
- vsfc->set_base_type(String(""));
- if (tg.gdclass != StringName()) {
- vsfc->set_base_type(tg.gdclass);
+ if (p_connecting) {
+ VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
- } else if (script->get_node(edited_func, port_action_node).is_valid()) {
- PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint;
- String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+ if (tg.type == Variant::OBJECT) {
+ vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE);
+ vsfc->set_base_type(String(""));
+ if (tg.gdclass != StringName()) {
+ vsfc->set_base_type(tg.gdclass);
- if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
- vsfc->set_base_type(base_type);
+ } else if (script->get_node(edited_func, port_action_node).is_valid()) {
+ PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint;
+ String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+
+ if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
+ vsfc->set_base_type(base_type);
+ }
+ if (p_text == "call" || p_text == "call_deferred") {
+ vsfc->set_function(String(""));
+ }
}
- if (p_text == "call" || p_text == "call_deferred") {
- vsfc->set_function(String(""));
+ if (tg.script.is_valid()) {
+ vsfc->set_base_script(tg.script->get_path());
}
+ } else if (tg.type == Variant::NIL) {
+ vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE);
+ vsfc->set_base_type(String(""));
+ } else {
+ vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE);
+ vsfc->set_basic_type(tg.type);
}
- if (tg.script.is_valid()) {
- vsfc->set_base_script(tg.script->get_path());
- }
- } else if (tg.type == Variant::NIL) {
- vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE);
- vsfc->set_base_type(String(""));
- } else {
- vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE);
- vsfc->set_basic_type(tg.type);
}
}
- if (Object::cast_to<VisualScriptPropertySet>(vsn.ptr())) {
-
- Ref<VisualScriptPropertySet> vsp = vsn;
+ // if connecting from another node the call mode shouldn't be self
+ if (p_connecting) {
+ if (Object::cast_to<VisualScriptPropertySet>(vsn.ptr())) {
+ Ref<VisualScriptPropertySet> vsp = vsn;
- VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
- if (tg.type == Variant::OBJECT) {
- vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE);
- vsp->set_base_type(String(""));
- if (tg.gdclass != StringName()) {
- vsp->set_base_type(tg.gdclass);
+ VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
+ if (tg.type == Variant::OBJECT) {
+ vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE);
+ vsp->set_base_type(String(""));
+ if (tg.gdclass != StringName()) {
+ vsp->set_base_type(tg.gdclass);
- } else if (script->get_node(edited_func, port_action_node).is_valid()) {
- PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint;
- String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+ } else if (script->get_node(edited_func, port_action_node).is_valid()) {
+ PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint;
+ String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
- if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
- vsp->set_base_type(base_type);
+ if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
+ vsp->set_base_type(base_type);
+ }
}
+ if (tg.script.is_valid()) {
+ vsp->set_base_script(tg.script->get_path());
+ }
+ } else if (tg.type == Variant::NIL) {
+ vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE);
+ vsp->set_base_type(String(""));
+ } else {
+ vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_BASIC_TYPE);
+ vsp->set_basic_type(tg.type);
}
- if (tg.script.is_valid()) {
- vsp->set_base_script(tg.script->get_path());
- }
- } else if (tg.type == Variant::NIL) {
- vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE);
- vsp->set_base_type(String(""));
- } else {
- vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_BASIC_TYPE);
- vsp->set_basic_type(tg.type);
}
- }
- if (Object::cast_to<VisualScriptPropertyGet>(vsn.ptr())) {
- Ref<VisualScriptPropertyGet> vsp = vsn;
-
- VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
- if (tg.type == Variant::OBJECT) {
- vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE);
- vsp->set_base_type(String(""));
- if (tg.gdclass != StringName()) {
- vsp->set_base_type(tg.gdclass);
+ if (Object::cast_to<VisualScriptPropertyGet>(vsn.ptr())) {
+ Ref<VisualScriptPropertyGet> vsp = vsn;
- } else if (script->get_node(edited_func, port_action_node).is_valid()) {
- PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint;
- String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
- if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
- vsp->set_base_type(base_type);
+ VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
+ if (tg.type == Variant::OBJECT) {
+ vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE);
+ vsp->set_base_type(String(""));
+ if (tg.gdclass != StringName()) {
+ vsp->set_base_type(tg.gdclass);
+
+ } else if (script->get_node(edited_func, port_action_node).is_valid()) {
+ PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint;
+ String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+ if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
+ vsp->set_base_type(base_type);
+ }
}
+ if (tg.script.is_valid()) {
+ vsp->set_base_script(tg.script->get_path());
+ }
+ } else if (tg.type == Variant::NIL) {
+ vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE);
+ vsp->set_base_type(String(""));
+ } else {
+ vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_BASIC_TYPE);
+ vsp->set_basic_type(tg.type);
}
- if (tg.script.is_valid()) {
- vsp->set_base_script(tg.script->get_path());
- }
- } else if (tg.type == Variant::NIL) {
- vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE);
- vsp->set_base_type(String(""));
- } else {
- vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_BASIC_TYPE);
- vsp->set_basic_type(tg.type);
}
}
Ref<VisualScriptNode> vnode_old = script->get_node(edited_func, port_action_node);
@@ -3614,7 +3622,6 @@ VisualScriptEditor::VisualScriptEditor() {
edit_signal_dialog = memnew(AcceptDialog);
edit_signal_dialog->get_ok()->set_text(TTR("Close"));
add_child(edit_signal_dialog);
- edit_signal_dialog->set_title(TTR("Edit Signal Arguments:"));
signal_editor = memnew(VisualScriptEditorSignalEdit);
edit_signal_edit = memnew(EditorInspector);
@@ -3625,7 +3632,6 @@ VisualScriptEditor::VisualScriptEditor() {
edit_variable_dialog = memnew(AcceptDialog);
edit_variable_dialog->get_ok()->set_text(TTR("Close"));
add_child(edit_variable_dialog);
- edit_variable_dialog->set_title(TTR("Edit Variable:"));
variable_editor = memnew(VisualScriptEditorVariableEdit);
edit_variable_edit = memnew(EditorInspector);
@@ -3636,7 +3642,6 @@ VisualScriptEditor::VisualScriptEditor() {
select_base_type = memnew(CreateDialog);
select_base_type->set_base_type("Object"); //anything goes
select_base_type->connect("create", this, "_change_base_type_callback");
- select_base_type->get_ok()->set_text(TTR("Change"));
add_child(select_base_type);
undo_redo = EditorNode::get_singleton()->get_undo_redo();
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 3d3a49f672..6072e77342 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -266,6 +266,7 @@ public:
virtual void set_executing_line(int p_line);
virtual void clear_executing_line();
virtual void trim_trailing_whitespace();
+ virtual void insert_final_newline();
virtual void convert_indent_to_spaces();
virtual void convert_indent_to_tabs();
virtual void ensure_focus();
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp
index 692705e411..e652abbe6a 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp
@@ -143,8 +143,7 @@ int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_buffer, int p_frames) {
bool ok = ov_time_seek(&vf, loop_restart_time) == 0;
if (!ok) {
playing = false;
- //ERR_EXPLAIN("loop restart time rejected");
- ERR_PRINT("loop restart time rejected")
+ ERR_PRINT("Loop restart time rejected");
}
frames_mixed = stream_srate * loop_restart_time;
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index 6485c95360..3670edc9ea 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -413,10 +413,11 @@ void VideoStreamPlaybackWebm::delete_pointers() {
if (audio_frame)
memdelete(audio_frame);
- for (int i = 0; i < video_frames_capacity; ++i)
- memdelete(video_frames[i]);
- if (video_frames)
+ if (video_frames) {
+ for (int i = 0; i < video_frames_capacity; ++i)
+ memdelete(video_frames[i]);
memfree(video_frames);
+ }
if (video)
memdelete(video);