diff options
Diffstat (limited to 'modules')
27 files changed, 432 insertions, 229 deletions
diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp index e5439fd132..f2f51d9dd3 100644 --- a/modules/assimp/editor_scene_importer_assimp.cpp +++ b/modules/assimp/editor_scene_importer_assimp.cpp @@ -529,7 +529,7 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim } // -// Mesh Generation from indicies ? why do we need so much mesh code +// Mesh Generation from indices ? why do we need so much mesh code // [debt needs looked into] Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( ImportState &state, @@ -541,6 +541,25 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( mesh.instance(); bool has_uvs = false; + Map<String, uint32_t> morph_mesh_string_lookup; + + for (int i = 0; i < p_surface_indices.size(); i++) { + const unsigned int mesh_idx = p_surface_indices[0]; + const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_idx]; + for (size_t j = 0; j < ai_mesh->mNumAnimMeshes; j++) { + + String ai_anim_mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mAnimMeshes[j]->mName); + if (!morph_mesh_string_lookup.has(ai_anim_mesh_name)) { + morph_mesh_string_lookup.insert(ai_anim_mesh_name, j); + mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED); + if (ai_anim_mesh_name.empty()) { + ai_anim_mesh_name = String("morph_") + itos(j); + } + mesh->add_blend_shape(ai_anim_mesh_name); + } + } + } + // // Process Vertex Weights // @@ -680,6 +699,25 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( mat->set_cull_mode(SpatialMaterial::CULL_BACK); // Now process materials + aiTextureType base_color = aiTextureType_BASE_COLOR; + { + String filename, path; + AssimpImageData image_data; + + if (AssimpUtils::GetAssimpTexture(state, ai_material, base_color, filename, path, image_data)) { + AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); + + // anything transparent must be culled + if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) { + mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); + mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); + mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode + } + + mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture); + } + } + aiTextureType tex_diffuse = aiTextureType_DIFFUSE; { String filename, path; @@ -731,6 +769,60 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( } } + aiTextureType tex_normal_camera = aiTextureType_NORMAL_CAMERA; + { + String filename, path; + Ref<ImageTexture> texture; + AssimpImageData image_data; + + // Process texture normal map + if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal_camera, filename, path, image_data)) { + AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); + mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true); + mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture); + } + } + + aiTextureType tex_emission_color = aiTextureType_EMISSION_COLOR; + { + String filename, path; + Ref<ImageTexture> texture; + AssimpImageData image_data; + + // Process texture normal map + if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emission_color, filename, path, image_data)) { + AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); + mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true); + mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture); + } + } + + aiTextureType tex_metalness = aiTextureType_METALNESS; + { + String filename, path; + Ref<ImageTexture> texture; + AssimpImageData image_data; + + // Process texture normal map + if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_metalness, filename, path, image_data)) { + AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); + mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, image_data.texture); + } + } + + aiTextureType tex_roughness = aiTextureType_DIFFUSE_ROUGHNESS; + { + String filename, path; + Ref<ImageTexture> texture; + AssimpImageData image_data; + + // Process texture normal map + if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_roughness, filename, path, image_data)) { + AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); + mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, image_data.texture); + } + } + aiTextureType tex_emissive = aiTextureType_EMISSIVE; { String filename = ""; @@ -772,16 +864,17 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( } } - aiTextureType tex_roughness = aiTextureType_SHININESS; + aiTextureType tex_ao_map = aiTextureType_AMBIENT_OCCLUSION; { String filename, path; Ref<ImageTexture> texture; AssimpImageData image_data; // Process texture normal map - if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_roughness, filename, path, image_data)) { + if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_ao_map, filename, path, image_data)) { AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, image_data.texture); + mat->set_feature(SpatialMaterial::FEATURE_AMBIENT_OCCLUSION, true); + mat->set_texture(SpatialMaterial::TEXTURE_AMBIENT_OCCLUSION, image_data.texture); } } @@ -789,16 +882,15 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( Array morphs; morphs.resize(ai_mesh->mNumAnimMeshes); Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES; - Map<uint32_t, String> morph_mesh_idx_names; + for (size_t j = 0; j < ai_mesh->mNumAnimMeshes; j++) { String ai_anim_mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mAnimMeshes[j]->mName); - mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED); + if (ai_anim_mesh_name.empty()) { ai_anim_mesh_name = String("morph_") + itos(j); } - mesh->add_blend_shape(ai_anim_mesh_name); - morph_mesh_idx_names.insert(j, ai_anim_mesh_name); + Array array_copy; array_copy.resize(VisualServer::ARRAY_MAX); @@ -1188,7 +1280,6 @@ void EditorSceneImporterAssimp::create_bone(ImportState &state, RecursiveState & // this transform is a bone recursive_state.skeleton->add_bone(recursive_state.node_name); - ERR_FAIL_COND(recursive_state.skeleton == NULL); // serious bug we must now exit. //ERR_FAIL_COND(recursive_state.skeleton->get_name() == ""); print_verbose("Bone added to lookup: " + AssimpUtils::get_assimp_string(recursive_state.bone->mName)); print_verbose("Skeleton attached to: " + recursive_state.skeleton->get_name()); diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index 5a32fa1c2c..8708430257 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -63,139 +63,137 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image, ERR_FAIL_V(ERR_UNAVAILABLE); } - if (err == OK) { - // Image data (might be indexed) - PoolVector<uint8_t> data; - int data_len = 0; + // Image data (might be indexed) + PoolVector<uint8_t> data; + int data_len = 0; - if (bits_per_pixel <= 8) { // indexed - data_len = width * height; - } else { // color - data_len = width * height * 4; - } - ERR_FAIL_COND_V(data_len == 0, ERR_BUG); - err = data.resize(data_len); - - PoolVector<uint8_t>::Write data_w = data.write(); - uint8_t *write_buffer = data_w.ptr(); - - const uint32_t width_bytes = width * bits_per_pixel / 8; - const uint32_t line_width = (width_bytes + 3) & ~3; - - // The actual data traversal is determined by - // the data width in case of 8/4/1 bit images - const uint32_t w = bits_per_pixel >= 24 ? width : width_bytes; - const uint8_t *line = p_buffer + (line_width * (height - 1)); - - for (unsigned int i = 0; i < height; i++) { - const uint8_t *line_ptr = line; - - for (unsigned int j = 0; j < w; j++) { - switch (bits_per_pixel) { - case 1: { - uint8_t color_index = *line_ptr; - - write_buffer[index + 0] = (color_index >> 7) & 1; - write_buffer[index + 1] = (color_index >> 6) & 1; - write_buffer[index + 2] = (color_index >> 5) & 1; - write_buffer[index + 3] = (color_index >> 4) & 1; - write_buffer[index + 4] = (color_index >> 3) & 1; - write_buffer[index + 5] = (color_index >> 2) & 1; - write_buffer[index + 6] = (color_index >> 1) & 1; - write_buffer[index + 7] = (color_index >> 0) & 1; - - index += 8; - line_ptr += 1; - } break; - case 4: { - uint8_t color_index = *line_ptr; - - write_buffer[index + 0] = (color_index >> 4) & 0x0f; - write_buffer[index + 1] = color_index & 0x0f; - - index += 2; - line_ptr += 1; - } break; - case 8: { - uint8_t color_index = *line_ptr; - - write_buffer[index] = color_index; - - index += 1; - line_ptr += 1; - } break; - case 24: { - uint32_t color = *((uint32_t *)line_ptr); - - write_buffer[index + 2] = color & 0xff; - write_buffer[index + 1] = (color >> 8) & 0xff; - write_buffer[index + 0] = (color >> 16) & 0xff; - write_buffer[index + 3] = 0xff; - - index += 4; - line_ptr += 3; - } break; - case 32: { - uint32_t color = *((uint32_t *)line_ptr); - - write_buffer[index + 2] = color & 0xff; - write_buffer[index + 1] = (color >> 8) & 0xff; - write_buffer[index + 0] = (color >> 16) & 0xff; - write_buffer[index + 3] = color >> 24; - - index += 4; - line_ptr += 4; - } break; - } + if (bits_per_pixel <= 8) { // indexed + data_len = width * height; + } else { // color + data_len = width * height * 4; + } + ERR_FAIL_COND_V(data_len == 0, ERR_BUG); + err = data.resize(data_len); + + PoolVector<uint8_t>::Write data_w = data.write(); + uint8_t *write_buffer = data_w.ptr(); + + const uint32_t width_bytes = width * bits_per_pixel / 8; + const uint32_t line_width = (width_bytes + 3) & ~3; + + // The actual data traversal is determined by + // the data width in case of 8/4/1 bit images + const uint32_t w = bits_per_pixel >= 24 ? width : width_bytes; + const uint8_t *line = p_buffer + (line_width * (height - 1)); + + for (uint64_t i = 0; i < height; i++) { + const uint8_t *line_ptr = line; + + for (unsigned int j = 0; j < w; j++) { + switch (bits_per_pixel) { + case 1: { + uint8_t color_index = *line_ptr; + + write_buffer[index + 0] = (color_index >> 7) & 1; + write_buffer[index + 1] = (color_index >> 6) & 1; + write_buffer[index + 2] = (color_index >> 5) & 1; + write_buffer[index + 3] = (color_index >> 4) & 1; + write_buffer[index + 4] = (color_index >> 3) & 1; + write_buffer[index + 5] = (color_index >> 2) & 1; + write_buffer[index + 6] = (color_index >> 1) & 1; + write_buffer[index + 7] = (color_index >> 0) & 1; + + index += 8; + line_ptr += 1; + } break; + case 4: { + uint8_t color_index = *line_ptr; + + write_buffer[index + 0] = (color_index >> 4) & 0x0f; + write_buffer[index + 1] = color_index & 0x0f; + + index += 2; + line_ptr += 1; + } break; + case 8: { + uint8_t color_index = *line_ptr; + + write_buffer[index] = color_index; + + index += 1; + line_ptr += 1; + } break; + case 24: { + uint32_t color = *((uint32_t *)line_ptr); + + write_buffer[index + 2] = color & 0xff; + write_buffer[index + 1] = (color >> 8) & 0xff; + write_buffer[index + 0] = (color >> 16) & 0xff; + write_buffer[index + 3] = 0xff; + + index += 4; + line_ptr += 3; + } break; + case 32: { + uint32_t color = *((uint32_t *)line_ptr); + + write_buffer[index + 2] = color & 0xff; + write_buffer[index + 1] = (color >> 8) & 0xff; + write_buffer[index + 0] = (color >> 16) & 0xff; + write_buffer[index + 3] = color >> 24; + + index += 4; + line_ptr += 4; + } break; } - line -= line_width; } + line -= line_width; + } - if (p_color_buffer == NULL || color_table_size == 0) { // regular pixels + if (p_color_buffer == NULL || color_table_size == 0) { // regular pixels - p_image->create(width, height, 0, Image::FORMAT_RGBA8, data); + p_image->create(width, height, 0, Image::FORMAT_RGBA8, data); - } else { // data is in indexed format, extend it + } else { // data is in indexed format, extend it - // Palette data - PoolVector<uint8_t> palette_data; - palette_data.resize(color_table_size * 4); + // Palette data + PoolVector<uint8_t> palette_data; + palette_data.resize(color_table_size * 4); - PoolVector<uint8_t>::Write palette_data_w = palette_data.write(); - uint8_t *pal = palette_data_w.ptr(); + PoolVector<uint8_t>::Write palette_data_w = palette_data.write(); + uint8_t *pal = palette_data_w.ptr(); - const uint8_t *cb = p_color_buffer; + const uint8_t *cb = p_color_buffer; - for (unsigned int i = 0; i < color_table_size; ++i) { - uint32_t color = *((uint32_t *)cb); + for (unsigned int i = 0; i < color_table_size; ++i) { + uint32_t color = *((uint32_t *)cb); - pal[i * 4 + 0] = (color >> 16) & 0xff; - pal[i * 4 + 1] = (color >> 8) & 0xff; - pal[i * 4 + 2] = (color)&0xff; - pal[i * 4 + 3] = 0xff; + pal[i * 4 + 0] = (color >> 16) & 0xff; + pal[i * 4 + 1] = (color >> 8) & 0xff; + pal[i * 4 + 2] = (color)&0xff; + pal[i * 4 + 3] = 0xff; - cb += 4; - } - // Extend palette to image - PoolVector<uint8_t> extended_data; - extended_data.resize(data.size() * 4); + cb += 4; + } + // Extend palette to image + PoolVector<uint8_t> extended_data; + extended_data.resize(data.size() * 4); - PoolVector<uint8_t>::Write ex_w = extended_data.write(); - uint8_t *dest = ex_w.ptr(); + PoolVector<uint8_t>::Write ex_w = extended_data.write(); + uint8_t *dest = ex_w.ptr(); - const int num_pixels = width * height; + const int num_pixels = width * height; - for (int i = 0; i < num_pixels; i++) { - dest[0] = pal[write_buffer[i] * 4 + 0]; - dest[1] = pal[write_buffer[i] * 4 + 1]; - dest[2] = pal[write_buffer[i] * 4 + 2]; - dest[3] = pal[write_buffer[i] * 4 + 3]; + for (int i = 0; i < num_pixels; i++) { + dest[0] = pal[write_buffer[i] * 4 + 0]; + dest[1] = pal[write_buffer[i] * 4 + 1]; + dest[2] = pal[write_buffer[i] * 4 + 2]; + dest[3] = pal[write_buffer[i] * 4 + 3]; - dest += 4; - } - p_image->create(width, height, 0, Image::FORMAT_RGBA8, extended_data); + dest += 4; } + p_image->create(width, height, 0, Image::FORMAT_RGBA8, extended_data); } } return err; diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index f1b3fa2ac6..5a76f32977 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -114,7 +114,7 @@ void CSGBrush::_regen_face_aabbs() { faces.write[i].aabb.position = faces[i].vertices[0]; faces.write[i].aabb.expand_to(faces[i].vertices[1]); faces.write[i].aabb.expand_to(faces[i].vertices[2]); - faces.write[i].aabb.grow_by(faces[i].aabb.get_longest_axis_size() * 0.001); //make it a tad bigger to avoid num precision erros + faces.write[i].aabb.grow_by(faces[i].aabb.get_longest_axis_size() * 0.001); //make it a tad bigger to avoid num precision errors } } diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index e6bfa5525d..0d26943af6 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -377,7 +377,7 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { break; } - p_gizmo->add_mesh(mesh, false, RID(), solid_material); + p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), solid_material); } if (Object::cast_to<CSGSphere>(cs)) { diff --git a/modules/cvtt/SCsub b/modules/cvtt/SCsub index 142af0c800..746b23ca28 100644 --- a/modules/cvtt/SCsub +++ b/modules/cvtt/SCsub @@ -6,19 +6,18 @@ Import('env_modules') env_cvtt = env_modules.Clone() # Thirdparty source files -if env['builtin_squish']: - thirdparty_dir = "#thirdparty/cvtt/" - thirdparty_sources = [ - "ConvectionKernels.cpp" - ] +thirdparty_dir = "#thirdparty/cvtt/" +thirdparty_sources = [ + "ConvectionKernels.cpp" +] - thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] +thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_cvtt.Prepend(CPPPATH=[thirdparty_dir]) +env_cvtt.Prepend(CPPPATH=[thirdparty_dir]) - env_thirdparty = env_cvtt.Clone() - env_thirdparty.disable_warnings() - env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources) +env_thirdparty = env_cvtt.Clone() +env_thirdparty.disable_warnings() +env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources) # Godot source files env_cvtt.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index 7f52f5736c..8a05b6cfa3 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -64,9 +64,9 @@ typedef enum { GODOT_PROPERTY_HINT_LAYERS_3D_RENDER, GODOT_PROPERTY_HINT_LAYERS_3D_PHYSICS, GODOT_PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," - GODOT_PROPERTY_HINT_DIR, ///< a directort path must be passed + GODOT_PROPERTY_HINT_DIR, ///< a directory path must be passed GODOT_PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," - GODOT_PROPERTY_HINT_GLOBAL_DIR, ///< a directort path must be passed + GODOT_PROPERTY_HINT_GLOBAL_DIR, ///< a directory path must be passed GODOT_PROPERTY_HINT_RESOURCE_TYPE, ///< a resource object type GODOT_PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines GODOT_PROPERTY_HINT_PLACEHOLDER_TEXT, ///< used to set a placeholder text for string properties diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index 9de073fc8e..22898a73ce 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -200,7 +200,7 @@ void PluginScriptLanguage::get_recognized_extensions(List<String> *p_extensions) } void PluginScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const { - // TODO: provid this statically in `godot_pluginscript_language_desc` ? + // TODO: provide this statically in `godot_pluginscript_language_desc` ? if (_desc.get_public_functions) { Array functions; _desc.get_public_functions(_data, (godot_array *)&functions); @@ -212,7 +212,7 @@ void PluginScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) c } void PluginScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const { - // TODO: provid this statically in `godot_pluginscript_language_desc` ? + // TODO: provide this statically in `godot_pluginscript_language_desc` ? if (_desc.get_public_constants) { Dictionary constants; _desc.get_public_constants(_data, (godot_dictionary *)&constants); diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index be131c5402..212ff51b80 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -149,7 +149,7 @@ void VideoStreamPlaybackGDNative::update(float p_delta) { if (mix_callback) { if (pcm_write_idx >= 0) { // Previous remains - int mixed = mix_callback(mix_udata, pcm, samples_decoded); + int mixed = mix_callback(mix_udata, pcm + pcm_write_idx * num_channels, samples_decoded); if (mixed == samples_decoded) { pcm_write_idx = -1; } else { diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 5dab063061..c8ec80c101 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -99,7 +99,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco #endif instance->owner->set_script_instance(instance); - /* STEP 2, INITIALIZE AND CONSRTUCT */ + /* STEP 2, INITIALIZE AND CONSTRUCT */ #ifndef NO_THREADS GDScriptLanguage::singleton->lock->lock(); diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 7166189416..dea2225e91 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1520,8 +1520,16 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo if (ret2 < 0) return ERR_PARSE_ERROR; + int message_ret = 0; + if (as->message) { + message_ret = _parse_expression(codegen, as->message, p_stack_level + 1, false); + if (message_ret < 0) + return ERR_PARSE_ERROR; + } + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSERT); codegen.opcodes.push_back(ret2); + codegen.opcodes.push_back(message_ret); #endif } break; case GDScriptParser::Node::TYPE_BREAKPOINT: { @@ -2064,7 +2072,7 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa } instance->owner->set_script_instance(instance); - /* STEP 2, INITIALIZE AND CONSRTUCT */ + /* STEP 2, INITIALIZE AND CONSTRUCT */ Variant::CallError ce; p_script->initializer->call(instance, NULL, 0, ce); diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 68f2a9473e..bdeea9cef3 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -1475,20 +1475,25 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_ASSERT) { - CHECK_SPACE(2); + CHECK_SPACE(3); #ifdef DEBUG_ENABLED GET_VARIANT_PTR(test, 1); + GET_VARIANT_PTR(message, 2); bool result = test->booleanize(); if (!result) { - - err_text = "Assertion failed."; + const String &message_str = *message; + if (message_str.empty()) { + err_text = "Assertion failed."; + } else { + err_text = "Assertion failed: " + message_str; + } OPCODE_BREAK; } #endif - ip += 2; + ip += 3; } DISPATCH_OPCODE; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index e96bf0238a..967b0c83ae 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -1207,7 +1207,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s if (_get_completable_identifier(COMPLETION_INDEX, identifier)) { if (identifier == StringName()) { - identifier = "@temp"; //so it parses allright + identifier = "@temp"; //so it parses alright } completion_node = op; @@ -1399,9 +1399,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s unary = true; break; case OperatorNode::OP_NEG: - priority = 1; - unary = true; - break; case OperatorNode::OP_POS: priority = 1; unary = true; @@ -2846,15 +2843,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { assigned = subexpr; } else { - ConstantNode *c = alloc_node<ConstantNode>(); - if (lv->datatype.has_type && lv->datatype.kind == DataType::BUILTIN) { - Variant::CallError err; - c->value = Variant::construct(lv->datatype.builtin_type, NULL, 0, err); - } else { - c->value = Variant(); - } - c->line = var_line; - assigned = c; + assigned = _get_default_value_for_type(lv->datatype, var_line); } lv->assign = assigned; //must be added later, to avoid self-referencing. @@ -3280,15 +3269,36 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { case GDScriptTokenizer::TK_PR_ASSERT: { tokenizer->advance(); - Node *condition = _parse_and_reduce_expression(p_block, p_static); - if (!condition) { - if (_recover_from_completion()) { - break; - } + + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) { + _set_error("Expected '(' after assert"); + return; + } + + tokenizer->advance(); + + Vector<Node *> args; + const bool result = _parse_arguments(p_block, args, p_static); + if (!result) { + return; + } + + if (args.empty() || args.size() > 2) { + _set_error("Wrong number of arguments, expected 1 or 2"); return; } + AssertNode *an = alloc_node<AssertNode>(); - an->condition = condition; + an->condition = _reduce_expression(args[0], p_static); + + if (args.size() == 2) { + an->message = _reduce_expression(args[1], p_static); + } else { + ConstantNode *message_node = alloc_node<ConstantNode>(); + message_node->value = String(); + an->message = message_node; + } + p_block->statements.push_back(an); if (!_end_statement()) { @@ -3533,6 +3543,15 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { return; } + if (p_class->classname_used && ProjectSettings::get_singleton()->has_setting("autoload/" + p_class->name)) { + const String autoload_path = ProjectSettings::get_singleton()->get_setting("autoload/" + p_class->name); + if (autoload_path.begins_with("*")) { + // It's a singleton, and not just a regular AutoLoad script. + _set_error("The class \"" + p_class->name + "\" conflicts with the AutoLoad singleton of the same name, and is therefore redundant. Remove the class_name declaration to fix this error."); + } + return; + } + tokenizer->advance(2); if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { @@ -4839,35 +4858,29 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { return; } - Variant::Type initial_type = member.data_type.has_type ? member.data_type.builtin_type : member._export.type; + Node *expr; - if (initial_type != Variant::NIL && initial_type != Variant::OBJECT) { - IdentifierNode *id = alloc_node<IdentifierNode>(); - id->name = member.identifier; - - Node *expr; + if (member.data_type.has_type) { + expr = _get_default_value_for_type(member.data_type); + } else { + DataType exported_type; + exported_type.has_type = true; + exported_type.kind = DataType::BUILTIN; + exported_type.builtin_type = member._export.type; + expr = _get_default_value_for_type(exported_type); + } - // Make sure arrays and dictionaries are not shared - if (initial_type == Variant::ARRAY) { - expr = alloc_node<ArrayNode>(); - } else if (initial_type == Variant::DICTIONARY) { - expr = alloc_node<DictionaryNode>(); - } else { - ConstantNode *cn = alloc_node<ConstantNode>(); - Variant::CallError ce2; - cn->value = Variant::construct(initial_type, NULL, 0, ce2); - expr = cn; - } + IdentifierNode *id = alloc_node<IdentifierNode>(); + id->name = member.identifier; - OperatorNode *op = alloc_node<OperatorNode>(); - op->op = OperatorNode::OP_INIT_ASSIGN; - op->arguments.push_back(id); - op->arguments.push_back(expr); + OperatorNode *op = alloc_node<OperatorNode>(); + op->op = OperatorNode::OP_INIT_ASSIGN; + op->arguments.push_back(id); + op->arguments.push_back(expr); - p_class->initializer->statements.push_back(op); + p_class->initializer->statements.push_back(op); - member.initial_assignment = op; - } + member.initial_assignment = op; } if (autoexport && member.data_type.has_type) { @@ -5727,28 +5740,35 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source, } } - // Still look for class constants in parent script + // Still look for class constants in parent scripts if (!found && (base_type.kind == DataType::GDSCRIPT || base_type.kind == DataType::SCRIPT)) { Ref<Script> scr = base_type.script_type; ERR_FAIL_COND_V(scr.is_null(), result); - Map<StringName, Variant> constants; - scr->get_constants(&constants); + while (scr.is_valid()) { + Map<StringName, Variant> constants; + scr->get_constants(&constants); - if (constants.has(id)) { - Ref<GDScript> gds = constants[id]; + if (constants.has(id)) { + Ref<GDScript> gds = constants[id]; - if (gds.is_valid()) { - result.kind = DataType::GDSCRIPT; - result.script_type = gds; - found = true; - } else { - Ref<Script> scr2 = constants[id]; - if (scr2.is_valid()) { - result.kind = DataType::SCRIPT; - result.script_type = scr2; + if (gds.is_valid()) { + result.kind = DataType::GDSCRIPT; + result.script_type = gds; found = true; + } else { + Ref<Script> scr2 = constants[id]; + if (scr2.is_valid()) { + result.kind = DataType::SCRIPT; + result.script_type = scr2; + found = true; + } } } + if (found) { + break; + } else { + scr = scr->get_base_script(); + } } } @@ -6140,6 +6160,31 @@ bool GDScriptParser::_is_type_compatible(const DataType &p_container, const Data return false; } +GDScriptParser::Node *GDScriptParser::_get_default_value_for_type(const DataType &p_type, int p_line) { + Node *result; + + if (p_type.has_type && p_type.kind == DataType::BUILTIN && p_type.builtin_type != Variant::NIL && p_type.builtin_type != Variant::OBJECT) { + if (p_type.builtin_type == Variant::ARRAY) { + result = alloc_node<ArrayNode>(); + } else if (p_type.builtin_type == Variant::DICTIONARY) { + result = alloc_node<DictionaryNode>(); + } else { + ConstantNode *c = alloc_node<ConstantNode>(); + Variant::CallError err; + c->value = Variant::construct(p_type.builtin_type, NULL, 0, err); + result = c; + } + } else { + ConstantNode *c = alloc_node<ConstantNode>(); + c->value = Variant(); + result = c; + } + + result->line = p_line; + + return result; +} + 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) { diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 72aa819a8c..04ce9cf4c6 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -481,7 +481,12 @@ public: struct AssertNode : public Node { Node *condition; - AssertNode() { type = TYPE_ASSERT; } + Node *message; + AssertNode() : + condition(0), + message(0) { + type = TYPE_ASSERT; + } }; struct BreakpointNode : public Node { @@ -610,6 +615,7 @@ private: bool _get_function_signature(DataType &p_base_type, const StringName &p_function, DataType &r_return_type, List<DataType> &r_arg_types, int &r_default_arg_count, bool &r_static, bool &r_vararg) const; bool _get_member_type(const DataType &p_base_type, const StringName &p_member, DataType &r_member_type) const; bool _is_type_compatible(const DataType &p_container, const DataType &p_expression, bool p_allow_implicit_conversion = false) const; + Node *_get_default_value_for_type(const DataType &p_type, int p_line = -1); DataType _reduce_node_type(Node *p_node); DataType _reduce_function_call_type(const OperatorNode *p_call); diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index 45f9ec9c6a..9e8727ec58 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -189,6 +189,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p lsp::DocumentSymbol symbol; const GDScriptParser::ClassNode::Constant &c = E->value(); const GDScriptParser::ConstantNode *node = dynamic_cast<const GDScriptParser::ConstantNode *>(c.expression); + ERR_FAIL_COND(!node); symbol.name = E->key(); symbol.kind = lsp::SymbolKind::Constant; symbol.deprecated = false; @@ -674,6 +675,7 @@ Dictionary ExtendGDScriptParser::dump_class_api(const GDScriptParser::ClassNode const GDScriptParser::ClassNode::Constant &c = E->value(); const GDScriptParser::ConstantNode *node = dynamic_cast<const GDScriptParser::ConstantNode *>(c.expression); + ERR_FAIL_COND_V(!node, class_api); Dictionary api; api["name"] = E->key(); diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index afe461b68e..ce3de9bc3b 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -100,9 +100,10 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) { String root_uri = p_params["rootUri"]; String root = p_params["rootPath"]; - bool is_same_workspace = root == workspace->root; + bool is_same_workspace; +#ifndef WINDOWS_ENABLED is_same_workspace = root.to_lower() == workspace->root.to_lower(); -#ifdef WINDOWS_ENABLED +#else is_same_workspace = root.replace("\\", "/").to_lower() == workspace->root.to_lower(); #endif @@ -142,6 +143,7 @@ void GDScriptLanguageProtocol::poll() { Error GDScriptLanguageProtocol::start(int p_port) { if (server == NULL) { server = dynamic_cast<WebSocketServer *>(ClassDB::instance("WebSocketServer")); + ERR_FAIL_COND_V(!server, FAILED); server->set_buffers(8192, 1024, 8192, 1024); // 8mb should be way more than enough server->connect("data_received", this, "on_data_received"); server->connect("client_connected", this, "on_client_connected"); diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp index 9bea4557ac..62c212a2bd 100644 --- a/modules/gdscript/language_server/gdscript_language_server.cpp +++ b/modules/gdscript/language_server/gdscript_language_server.cpp @@ -64,7 +64,7 @@ void GDScriptLanguageServer::thread_main(void *p_userdata) { void GDScriptLanguageServer::start() { int port = (int)_EDITOR_GET("network/language_server/remote_port"); if (protocol.start(port) == OK) { - EditorNode::get_log()->add_message("** GDScript Language Server Started **"); + EditorNode::get_log()->add_message("--- GDScript language server started ---", EditorLog::MSG_TYPE_EDITOR); ERR_FAIL_COND(thread != NULL || thread_exit); thread_exit = false; thread = Thread::create(GDScriptLanguageServer::thread_main, this); @@ -78,7 +78,7 @@ void GDScriptLanguageServer::stop() { memdelete(thread); thread = NULL; protocol.stop(); - EditorNode::get_log()->add_message("** GDScript Language Server Stopped **"); + EditorNode::get_log()->add_message("--- GDScript language server stopped ---", EditorLog::MSG_TYPE_EDITOR); } void register_lsp_types() { diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index f211fae526..7c58c7aa15 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -380,8 +380,8 @@ GDScriptTextDocument::~GDScriptTextDocument() { memdelete(file_checker); } -void GDScriptTextDocument::sync_script_content(const String &p_uri, const String &p_content) { - String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(p_uri); +void GDScriptTextDocument::sync_script_content(const String &p_path, const String &p_content) { + String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(p_path); GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_script(path, p_content); } diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 07b4f7f596..7e2986ca85 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -884,9 +884,15 @@ void GridMapEditor::update_palette() { if (mesh_library.is_null()) { last_mesh_library = NULL; + search_box->set_text(""); + search_box->set_editable(false); + info_message->show(); return; } + search_box->set_editable(true); + info_message->hide(); + Vector<int> ids; ids = mesh_library->get_item_list(); @@ -1069,6 +1075,7 @@ void GridMapEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { + get_tree()->connect("node_removed", this, "_node_removed"); mesh_library_palette->connect("item_selected", this, "_item_selected_cbk"); for (int i = 0; i < 3; i++) { @@ -1085,6 +1092,7 @@ void GridMapEditor::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { + get_tree()->disconnect("node_removed", this, "_node_removed"); _clear_clipboard_data(); for (int i = 0; i < 3; i++) { @@ -1198,6 +1206,7 @@ void GridMapEditor::_bind_methods() { 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("_node_removed", &GridMapEditor::_node_removed); ClassDB::bind_method(D_METHOD("_set_display_mode", "mode"), &GridMapEditor::_set_display_mode); } @@ -1296,6 +1305,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { search_box = memnew(LineEdit); search_box->set_h_size_flags(SIZE_EXPAND_FILL); + search_box->set_placeholder(TTR("Filter meshes")); hb->add_child(search_box); search_box->connect("text_changed", this, "_text_changed"); search_box->connect("gui_input", this, "_sbox_input"); @@ -1331,6 +1341,14 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { add_child(mesh_library_palette); mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL); + info_message = memnew(Label); + info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes.")); + info_message->set_valign(Label::VALIGN_CENTER); + info_message->set_align(Label::ALIGN_CENTER); + info_message->set_autowrap(true); + info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE); + mesh_library_palette->add_child(info_message); + edit_axis = Vector3::AXIS_Y; edit_floor[0] = -1; edit_floor[1] = -1; @@ -1346,7 +1364,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { paste_mesh = VisualServer::get_singleton()->mesh_create(); { - //selection mesh create + // Selection mesh create. PoolVector<Vector3> lines; PoolVector<Vector3> triangles; @@ -1424,7 +1442,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { inner_mat.instance(); inner_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.2)); - //inner_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true); inner_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); inner_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); @@ -1444,7 +1461,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { selection_floor_mat->set_on_top_of_alpha(); selection_floor_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); selection_floor_mat->set_line_width(3.0); - //selection_floor_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); d[VS::ARRAY_VERTEX] = lines; VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, VS::PRIMITIVE_LINES, d); diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index d174ac1035..103913485f 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -197,12 +197,16 @@ class GridMapEditor : public VBoxContainer { RID instance; }; + ItemList *mesh_library_palette; + Label *info_message; + + EditorNode *editor; + void update_grid(); void _configure(); void _menu_option(int); void update_palette(); void _set_display_mode(int p_mode); - ItemList *mesh_library_palette; void _item_selected_cbk(int idx); void _update_cursor_transform(); void _update_cursor_instance(); @@ -227,7 +231,6 @@ class GridMapEditor : public VBoxContainer { void _delete_selection(); void _fill_selection(); - EditorNode *editor; bool do_input_action(Camera *p_camera, const Point2 &p_point, bool p_click); friend class GridMapEditorPlugin; diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index f751719531..4c1ebd8d74 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -18,7 +18,7 @@ android_arch_dirs = { def get_android_out_dir(env): - return os.path.join(Dir('#platform/android/java/libs').abspath, + return os.path.join(Dir('#platform/android/java/lib/libs').abspath, 'release' if env['target'] == 'release' else 'debug', android_arch_dirs[env['android_arch']]) diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 1888bb3cb9..74710db224 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -1785,6 +1785,9 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { output.append("uint32_t get_bindings_version() { return "); output.append(String::num_uint64(BINDINGS_GENERATOR_VERSION) + "; }\n"); + output.append("uint32_t get_cs_glue_version() { return "); + output.append(String::num_uint64(CS_GLUE_VERSION) + "; }\n"); + output.append("\nvoid register_generated_icalls() " OPEN_BLOCK); output.append("\tgodot_register_glue_header_icalls();\n"); diff --git a/modules/mono/glue/Managed/Files/Rect2.cs b/modules/mono/glue/Managed/Files/Rect2.cs index f3dc9d8490..99542d0c0a 100644 --- a/modules/mono/glue/Managed/Files/Rect2.cs +++ b/modules/mono/glue/Managed/Files/Rect2.cs @@ -157,13 +157,13 @@ namespace Godot public bool Intersects(Rect2 b) { - if (_position.x > b._position.x + b._size.x) + if (_position.x >= b._position.x + b._size.x) return false; - if (_position.x + _size.x < b._position.x) + if (_position.x + _size.x <= b._position.x) return false; - if (_position.y > b._position.y + b._size.y) + if (_position.y >= b._position.y + b._size.y) return false; - if (_position.y + _size.y < b._position.y) + if (_position.y + _size.y <= b._position.y) return false; return true; diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index cd111abd4d..915a01af7e 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -44,7 +44,6 @@ #include "core/project_settings.h" #include "../csharp_script.h" -#include "../glue/cs_glue_version.gen.h" #include "../godotsharp_dirs.h" #include "../utils/path_utils.h" #include "gd_mono_class.h" @@ -395,23 +394,24 @@ uint64_t get_core_api_hash(); uint64_t get_editor_api_hash(); #endif uint32_t get_bindings_version(); +uint32_t get_cs_glue_version(); void register_generated_icalls(); #else uint64_t get_core_api_hash() { - CRASH_NOW(); GD_UNREACHABLE(); } #ifdef TOOLS_ENABLED uint64_t get_editor_api_hash() { - CRASH_NOW(); GD_UNREACHABLE(); } #endif uint32_t get_bindings_version() { - CRASH_NOW(); + GD_UNREACHABLE(); +} +uint32_t get_cs_glue_version() { GD_UNREACHABLE(); } @@ -687,7 +687,7 @@ bool GDMono::_load_core_api_assembly() { APIAssembly::Version api_assembly_ver = APIAssembly::Version::get_from_loaded_assembly(core_api_assembly, APIAssembly::API_CORE); core_api_assembly_out_of_sync = GodotSharpBindings::get_core_api_hash() != api_assembly_ver.godot_api_hash || GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || - CS_GLUE_VERSION != api_assembly_ver.cs_glue_version; + GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; if (!core_api_assembly_out_of_sync) { GDMonoUtils::update_godot_api_cache(); @@ -722,7 +722,7 @@ bool GDMono::_load_editor_api_assembly() { APIAssembly::Version api_assembly_ver = APIAssembly::Version::get_from_loaded_assembly(editor_api_assembly, APIAssembly::API_EDITOR); editor_api_assembly_out_of_sync = GodotSharpBindings::get_editor_api_hash() != api_assembly_ver.godot_api_hash || GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || - CS_GLUE_VERSION != api_assembly_ver.cs_glue_version; + GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; } else { editor_api_assembly_out_of_sync = false; } diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 70389b6729..6bed1742eb 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -578,6 +578,10 @@ void VisualScript::get_data_connection_list(const StringName &p_func, List<DataC } } +void VisualScript::set_tool_enabled(bool p_enabled) { + is_tool_script = p_enabled; +} + void VisualScript::add_variable(const StringName &p_name, const Variant &p_default_value, bool p_export) { ERR_FAIL_COND(instances.size()); @@ -894,7 +898,7 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) { #ifdef TOOLS_ENABLED - if (!ScriptServer::is_scripting_enabled()) { + if (!ScriptServer::is_scripting_enabled() && !is_tool_script) { PlaceHolderScriptInstance *sins = memnew(PlaceHolderScriptInstance(VisualScriptLanguage::singleton, Ref<Script>((Script *)this), p_this)); placeholders.insert(sins); @@ -958,7 +962,7 @@ Error VisualScript::reload(bool p_keep_state) { bool VisualScript::is_tool() const { - return false; + return is_tool_script; } bool VisualScript::is_valid() const { @@ -1164,6 +1168,11 @@ void VisualScript::_set_data(const Dictionary &p_data) { data_connect(name, data_connections[j + 0], data_connections[j + 1], data_connections[j + 2], data_connections[j + 3]); } } + + if (d.has("is_tool_script")) + is_tool_script = d["is_tool_script"]; + else + is_tool_script = false; } Dictionary VisualScript::_get_data() const { @@ -1246,6 +1255,8 @@ Dictionary VisualScript::_get_data() const { d["functions"] = funcs; + d["is_tool_script"] = is_tool_script; + return d; } diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 098c28370d..14927c4363 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -247,6 +247,8 @@ private: Map<Object *, VisualScriptInstance *> instances; + bool is_tool_script; + #ifdef TOOLS_ENABLED Set<PlaceHolderScriptInstance *> placeholders; //void _update_placeholder(PlaceHolderScriptInstance *p_placeholder); @@ -273,6 +275,7 @@ public: Vector2 get_function_scroll(const StringName &p_name) const; void get_function_list(List<StringName> *r_functions) const; int get_function_node_id(const StringName &p_name) const; + void set_tool_enabled(bool p_enabled); void add_node(const StringName &p_func, int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos = Point2()); void remove_node(const StringName &p_func, int p_id); diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 8faa342bbe..7262dde359 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -2227,6 +2227,10 @@ void VisualScriptEditor::_change_base_type() { select_base_type->popup_create(true, true); } +void VisualScriptEditor::_toggle_tool_script() { + script->set_tool_enabled(!script->is_tool()); +} + void VisualScriptEditor::clear_edit_menu() { memdelete(edit_menu); memdelete(left_vsplit); @@ -3448,6 +3452,7 @@ void VisualScriptEditor::_bind_methods() { ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members); ClassDB::bind_method("_change_base_type", &VisualScriptEditor::_change_base_type); ClassDB::bind_method("_change_base_type_callback", &VisualScriptEditor::_change_base_type_callback); + ClassDB::bind_method("_toggle_tool_script", &VisualScriptEditor::_toggle_tool_script); ClassDB::bind_method("_node_selected", &VisualScriptEditor::_node_selected); ClassDB::bind_method("_node_moved", &VisualScriptEditor::_node_moved); ClassDB::bind_method("_move_node", &VisualScriptEditor::_move_node); @@ -3533,6 +3538,11 @@ VisualScriptEditor::VisualScriptEditor() { left_vb->set_v_size_flags(SIZE_EXPAND_FILL); //left_vb->set_custom_minimum_size(Size2(230, 1) * EDSCALE); + CheckButton *tool_script_check = memnew(CheckButton); + tool_script_check->set_text(TTR("Make Tool:")); + left_vb->add_child(tool_script_check); + tool_script_check->connect("pressed", this, "_toggle_tool_script"); + base_type_select = memnew(Button); left_vb->add_margin_child(TTR("Base Type:"), base_type_select); base_type_select->connect("pressed", this, "_change_base_type"); diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 4f302d1d72..5df9b1a004 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -186,6 +186,7 @@ class VisualScriptEditor : public ScriptEditorBase { void _node_filter_changed(const String &p_text); void _change_base_type_callback(); void _change_base_type(); + void _toggle_tool_script(); void _member_selected(); void _member_edited(); |