diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index ba27c2cdd63..570ed33a5ac 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -306,6 +306,16 @@ MainLoop *_OS::get_main_loop() const { return OS::get_singleton()->get_main_loop(); } + +void _OS::set_time_scale(float p_scale) { + OS::get_singleton()->set_time_scale(p_scale); +} + +float _OS::get_time_scale() { + + return OS::get_singleton()->get_time_scale(); +} + /* enum Weekday { DAY_SUNDAY, @@ -613,6 +623,9 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_target_fps","target_fps"),&_OS::set_target_fps); ObjectTypeDB::bind_method(_MD("get_target_fps"),&_OS::get_target_fps); + ObjectTypeDB::bind_method(_MD("set_time_scale","time_scale"),&_OS::set_time_scale); + ObjectTypeDB::bind_method(_MD("get_time_scale"),&_OS::get_time_scale); + ObjectTypeDB::bind_method(_MD("has_touchscreen_ui_hint"),&_OS::has_touchscreen_ui_hint); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index cac2de314d5..0ef70e4b13d 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -201,6 +201,9 @@ public: String get_data_dir() const; + void set_time_scale(float p_scale); + float get_time_scale(); + static _OS *get_singleton() { return singleton; } _OS(); diff --git a/core/object.cpp b/core/object.cpp index 8a844577a8b..b011d1ad3d3 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1505,10 +1505,12 @@ void Object::_bind_methods() { BIND_VMETHOD( miget ); MethodInfo plget("_get_property_list"); + plget.return_val.type=Variant::ARRAY; BIND_VMETHOD( plget ); #endif + BIND_VMETHOD( MethodInfo("_init") ); diff --git a/core/os/os.cpp b/core/os/os.cpp index 819ecd2f229..53ca7c3a49c 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -474,6 +474,16 @@ OS::MouseMode OS::get_mouse_mode() const{ return MOUSE_MODE_VISIBLE; } +void OS::set_time_scale(float p_scale) { + + _time_scale=p_scale; +} + +float OS::get_time_scale() const { + + return _time_scale; +} + OS::OS() { last_error=NULL; @@ -489,6 +499,7 @@ OS::OS() { _fps=1; _target_fps=0; _render_thread_mode=RENDER_THREAD_SAFE; + _time_scale=1.0; Math::seed(1234567); } diff --git a/core/os/os.h b/core/os/os.h index 71f53330c7a..ed7e1e4324b 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -55,6 +55,7 @@ class OS { int _orientation; float _fps; int _target_fps; + float _time_scale; char *last_error; @@ -332,6 +333,10 @@ public: virtual Error dialog_show(String p_title, String p_description, Vector p_buttons, Object* p_obj, String p_callback); virtual Error dialog_input_text(String p_title, String p_description, String p_partial, Object* p_obj, String p_callback); + + void set_time_scale(float p_scale); + float get_time_scale() const; + OS(); virtual ~OS(); diff --git a/core/ustring.cpp b/core/ustring.cpp index cb0540dbb06..cd33c276a80 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -2467,13 +2467,8 @@ int String::findn(String p_str,int p_from) const { }; - CharType src=srcd[read_pos]; - CharType dst=p_str[j]; - - if (src>='a' && src<='z') - src-='a'-'A'; - if (dst>='a' && dst<='z') - dst-='a'-'A'; + CharType src=_find_lower(srcd[read_pos]); + CharType dst=_find_lower(p_str[j]); if (src!=dst) { found=false; @@ -2490,10 +2485,101 @@ int String::findn(String p_str,int p_from) const { int String::rfind(String p_str,int p_from) const { + //stabilish a limit + int limit = length()-p_str.length(); + if (limit<0) + return -1; + + //stabilish a starting point + if (p_from<0) + p_from=limit; + else if (p_from>limit) + p_from=limit; + + int src_len=p_str.length(); + int len=length(); + + if(src_len==0 || len==0) + return -1; //wont find anything! + + + const CharType *src = c_str(); + + for (int i=p_from;i>=0;i--) { + + bool found=true; + for (int j=0;j=len) { + + ERR_PRINT("read_pos>=len"); + return -1; + }; + + + if (src[read_pos]!=p_str[j]) { + found=false; + break; + } + } + + if (found) + return i; + } + return -1; } int String::rfindn(String p_str,int p_from) const { + //stabilish a limit + int limit = length()-p_str.length(); + if (limit<0) + return -1; + + //stabilish a starting point + if (p_from<0) + p_from=limit; + else if (p_from>limit) + p_from=limit; + + int src_len=p_str.length(); + int len=length(); + + if(src_len==0 || len==0) + return -1; //wont find anything! + + + const CharType *src = c_str(); + + for (int i=p_from;i>=0;i--) { + + bool found=true; + for (int j=0;j=len) { + + ERR_PRINT("read_pos>=len"); + return -1; + }; + + CharType srcc=_find_lower(src[read_pos]); + CharType dstc=_find_lower(p_str[j]); + + + if (srcc!=dstc) { + found=false; + break; + } + } + + if (found) + return i; + } + return -1; } diff --git a/demos/3d/kinematic_char/level.scn b/demos/3d/kinematic_char/level.scn index 1d7e5a4a702..a276fe22e1a 100644 Binary files a/demos/3d/kinematic_char/level.scn and b/demos/3d/kinematic_char/level.scn differ diff --git a/demos/misc/autoload/global.gd b/demos/misc/autoload/global.gd index d9fa308a2fa..dca661a31a3 100644 --- a/demos/misc/autoload/global.gd +++ b/demos/misc/autoload/global.gd @@ -9,6 +9,11 @@ func goto_scene(scene): var s = ResourceLoader.load(scene) #queue erasing old (don't use free because that scene is calling this method) current_scene.queue_free() + # Remove the scene before loading the previous one. + # The node is removed when deleted anyway, but this will fix issues that + # might arise if both have a root node with the same name, + # as adding both together will cause the second to be renamed. (not usually a problem, but you might be wanting to look for the node later and not find it) + get_scene().get_root().remove(current_scene) #instance the new scene current_scene = s.instance() #add it to the active scene, as child of root diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 96f6ca3eced..ecf80047bd1 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -5748,7 +5748,7 @@ void RasterizerGLES2::_setup_skeleton(const Skeleton *p_skeleton) { void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Transform& p_view_transform, const Transform& p_view_transform_inverse,const CameraMatrix& p_projection,bool p_reverse_cull,bool p_fragment_light,bool p_alpha_pass) { if (current_rt && current_rt_vflip) { - p_reverse_cull=!p_reverse_cull; + //p_reverse_cull=!p_reverse_cull; glFrontFace(GL_CCW); } @@ -5881,10 +5881,12 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans if (desired_blend) { glEnable(GL_BLEND); - glColorMask(1,1,1,0); + if (!current_rt || !current_rt_transparent) + glColorMask(1,1,1,0); } else { glDisable(GL_BLEND); glColorMask(1,1,1,1); + } prev_blend=desired_blend; @@ -5892,8 +5894,8 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans if (desired_blend && desired_blend_mode!=current_blend_mode) { - switch(desired_blend_mode) { + switch(desired_blend_mode) { case VS::MATERIAL_BLEND_MODE_MIX: { glBlendEquation(GL_FUNC_ADD); diff --git a/main/main.cpp b/main/main.cpp index 5b1782815e1..2d286759d90 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -153,6 +153,7 @@ void Main::print_help(const char* p_binary) { OS::get_singleton()->print("\t-d,-debug : Debug (local stdout debugger).\n"); OS::get_singleton()->print("\t-rdebug ADDRESS : Remote debug (: host address).\n"); OS::get_singleton()->print("\t-fdelay [msec]: Simulate high CPU load (delay each frame by [msec]).\n"); + OS::get_singleton()->print("\t-timescale [msec]: Simulate high CPU load (delay each frame by [msec]).\n"); OS::get_singleton()->print("\t-bp : breakpoint list as source::line comma separated pairs, no spaces (%%20,%%2C,etc instead).\n"); OS::get_singleton()->print("\t-v : Verbose stdout mode\n"); OS::get_singleton()->print("\t-lang [locale]: Use a specific locale\n"); @@ -420,6 +421,17 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas } + } else if (I->get()=="-timescale") { // resolution + + if (I->next()) { + + OS::get_singleton()->set_time_scale(I->next()->get().to_double()); + N=I->next()->next(); + } else { + goto error; + + } + } else if (I->get() == "-pack") { @@ -1292,6 +1304,8 @@ bool Main::iteration() { time_accum+=step; + float time_scale = OS::get_singleton()->get_time_scale(); + bool exit=false; @@ -1307,15 +1321,15 @@ bool Main::iteration() { Physics2DServer::get_singleton()->sync(); Physics2DServer::get_singleton()->flush_queries(); - if (OS::get_singleton()->get_main_loop()->iteration( frame_slice )) { + if (OS::get_singleton()->get_main_loop()->iteration( frame_slice*time_scale )) { exit=true; break; } message_queue->flush(); - PhysicsServer::get_singleton()->step(frame_slice); - Physics2DServer::get_singleton()->step(frame_slice); + PhysicsServer::get_singleton()->step(frame_slice*time_scale); + Physics2DServer::get_singleton()->step(frame_slice*time_scale); time_accum-=frame_slice; message_queue->flush(); @@ -1328,13 +1342,13 @@ bool Main::iteration() { uint64_t idle_begin = OS::get_singleton()->get_ticks_usec(); - OS::get_singleton()->get_main_loop()->idle( step ); + OS::get_singleton()->get_main_loop()->idle( step*time_scale ); message_queue->flush(); if (SpatialSoundServer::get_singleton()) - SpatialSoundServer::get_singleton()->update( step ); + SpatialSoundServer::get_singleton()->update( step*time_scale ); if (SpatialSound2DServer::get_singleton()) - SpatialSound2DServer::get_singleton()->update( step ); + SpatialSound2DServer::get_singleton()->update( step*time_scale ); if (OS::get_singleton()->can_draw()) { diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 143a81d48a1..46eade0b7cf 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2117,9 +2117,15 @@ void GDParser::_parse_class(ClassNode *p_class) { break; } - }; + }; //fallthrough to use the same case Variant::REAL: { + float sign=1.0; + + if (tokenizer->get_token()==GDTokenizer::TK_OP_SUB) { + sign=-1; + tokenizer->advance(); + } if (tokenizer->get_token()!=GDTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { current_export=PropertyInfo(); @@ -2130,7 +2136,7 @@ void GDParser::_parse_class(ClassNode *p_class) { //enumeration current_export.hint=PROPERTY_HINT_RANGE; - current_export.hint_string=tokenizer->get_token_constant().operator String(); + current_export.hint_string=rtos(sign*double(tokenizer->get_token_constant())); tokenizer->advance(); if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) { @@ -2147,6 +2153,12 @@ void GDParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); + sign=1.0; + if (tokenizer->get_token()==GDTokenizer::TK_OP_SUB) { + sign=-1; + tokenizer->advance(); + } + if (tokenizer->get_token()!=GDTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { current_export=PropertyInfo(); @@ -2154,7 +2166,7 @@ void GDParser::_parse_class(ClassNode *p_class) { return; } - current_export.hint_string+=","+tokenizer->get_token_constant().operator String(); + current_export.hint_string+=","+rtos(sign*double(tokenizer->get_token_constant())); tokenizer->advance(); if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) @@ -2168,6 +2180,11 @@ void GDParser::_parse_class(ClassNode *p_class) { } tokenizer->advance(); + sign=1.0; + if (tokenizer->get_token()==GDTokenizer::TK_OP_SUB) { + sign=-1; + tokenizer->advance(); + } if (tokenizer->get_token()!=GDTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { @@ -2176,7 +2193,7 @@ void GDParser::_parse_class(ClassNode *p_class) { return; } - current_export.hint_string+=","+tokenizer->get_token_constant().operator String(); + current_export.hint_string+=","+rtos(sign*double(tokenizer->get_token_constant())); tokenizer->advance(); } break; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 78c40c56d93..d04023e95f8 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1331,7 +1331,7 @@ OS_Windows::MouseMode OS_Windows::get_mouse_mode() const{ void OS_Windows::warp_mouse_pos(const Point2& p_to) { - if (p_mode==MOUSE_MODE_CAPTURED) { + if (mouse_mode==MOUSE_MODE_CAPTURED) { old_x=p_to.x; old_y=p_to.y; diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index 4aa6151df38..ded86702ef2 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -484,7 +484,7 @@ void Particles2D::_notification(int p_what) { Particle *pdata=&particles[0]; int particle_count=particles.size(); - Rect2 r(Point2(),size); + RID texrid; if (texture.is_valid()) @@ -606,9 +606,10 @@ void Particles2D::_notification(int p_what) { if (texrid.is_valid()) { - VisualServer::get_singleton()->canvas_item_add_texture_rect(ci,r,texrid,false,color); + texture->draw(ci,Point2(),color); + //VisualServer::get_singleton()->canvas_item_add_texture_rect(ci,r,texrid,false,color); } else { - VisualServer::get_singleton()->canvas_item_add_rect(ci,r,color); + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2(),size),color); } diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index d32c6df7a46..64034545882 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -329,6 +329,7 @@ Map::Element *TileMap::_create_quadrant(const VisualServer::get_singleton()->canvas_item_set_parent( q.canvas_item, get_canvas_item() ); VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform ); q.static_body=Physics2DServer::get_singleton()->body_create(Physics2DServer::BODY_MODE_STATIC); + Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.static_body,get_instance_ID()); Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer); Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_FRICTION,friction); Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_BOUNCE,bounce); diff --git a/scene/3d/light.h b/scene/3d/light.h index 9fdd7295dc6..8e7395fd84c 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -197,7 +197,7 @@ protected: public: - OmniLight() : Light( VisualServer::LIGHT_OMNI ) {} + OmniLight() : Light( VisualServer::LIGHT_OMNI ) { set_parameter(PARAM_SHADOW_Z_OFFSET,0.001);} }; class SpotLight : public Light { diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 49e593c1f55..334a15e7241 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -399,6 +399,20 @@ void Sprite3D::_draw() { int x_axis = ((axis + 1) % 3); int y_axis = ((axis + 2) % 3); + if (axis!=Vector3::AXIS_Z) { + SWAP(x_axis,y_axis); + + for(int i=0;i<4;i++) { + //uvs[i] = Vector2(1.0,1.0)-uvs[i]; + //SWAP(vertices[i].x,vertices[i].y); + if (axis==Vector3::AXIS_Y) { + vertices[i].y = - vertices[i].y; + } else if (axis==Vector3::AXIS_X) { + vertices[i].x = - vertices[i].x; + } + } + } + AABB aabb; for(int i=0;i<4;i++) { @@ -407,8 +421,8 @@ void Sprite3D::_draw() { VS::get_singleton()->immediate_uv(immediate,uvs[i]); Vector3 vtx; - vtx[x_axis]=vertices[i][x_axis]; - vtx[y_axis]=vertices[i][y_axis]; + vtx[x_axis]=vertices[i][0]; + vtx[y_axis]=vertices[i][1]; VS::get_singleton()->immediate_vertex(immediate,vtx); if (i==0) { aabb.pos=vtx; @@ -661,6 +675,20 @@ void AnimatedSprite3D::_draw() { int x_axis = ((axis + 1) % 3); int y_axis = ((axis + 2) % 3); + if (axis!=Vector3::AXIS_Z) { + SWAP(x_axis,y_axis); + + for(int i=0;i<4;i++) { + //uvs[i] = Vector2(1.0,1.0)-uvs[i]; + //SWAP(vertices[i].x,vertices[i].y); + if (axis==Vector3::AXIS_Y) { + vertices[i].y = - vertices[i].y; + } else if (axis==Vector3::AXIS_X) { + vertices[i].x = - vertices[i].x; + } + } + } + AABB aabb; for(int i=0;i<4;i++) { @@ -669,8 +697,8 @@ void AnimatedSprite3D::_draw() { VS::get_singleton()->immediate_uv(immediate,uvs[i]); Vector3 vtx; - vtx[x_axis]=vertices[i][x_axis]; - vtx[y_axis]=vertices[i][y_axis]; + vtx[x_axis]=vertices[i][0]; + vtx[y_axis]=vertices[i][1]; VS::get_singleton()->immediate_vertex(immediate,vtx); if (i==0) { aabb.pos=vtx; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index e822cfef13a..a77a40327f7 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -212,7 +212,7 @@ void LineEdit::_input_event(InputEvent p_event) { emit_signal( "text_entered",text ); // notify to hide soft keyboard - notification(NOTIFICATION_FOCUS_EXIT); + notification(NOTIFICATION_FOCUS_EXIT); return; } break; @@ -677,6 +677,7 @@ void LineEdit::selection_delete() { undo_text = text; text.erase(selection.begin,selection.end-selection.begin); + cursor_pos-=CLAMP( cursor_pos-selection.begin, 0, selection.end-selection.begin); if (cursor_pos>=text.length()) { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 4095ddeb377..5934aaf1263 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2611,20 +2611,53 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li int line=-1; int pos=-1; + line=p_from_line; + for(int i=0;iget_offset(); pos.y-=_get_title_button_height(); if (pos.y<0) return Control::get_tooltip(p_pos); - pos.x+=h_scroll->get_val(); - pos.y+=v_scroll->get_val(); + if (h_scroll->is_visible()) + pos.x+=h_scroll->get_val(); + if (v_scroll->is_visible()) + pos.y+=v_scroll->get_val(); int col,h; TreeItem *it = _find_item_at_pos(root,pos,col,h); - if (it) { + if (it) { String ret; if (it->get_tooltip(col)=="") diff --git a/scene/main/node.cpp b/scene/main/node.cpp index b90fd489b32..5d89ee80f16 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1107,7 +1107,7 @@ void Node::get_groups(List *p_groups) const { void Node::_print_tree(const Node *p_node) { - printf("%ls\n", String(p_node->get_path_to(this)).c_str()); + print_line(String(p_node->get_path_to(this))); for (int i=0;i_print_tree(p_node); } diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp index 281415e4b73..6de59f184ab 100644 --- a/tools/editor/code_editor.cpp +++ b/tools/editor/code_editor.cpp @@ -246,14 +246,28 @@ bool FindReplaceDialog::_search() { if (is_backwards()) flags|=TextEdit::SEARCH_BACKWARDS; - int line,col; - bool found = text_edit->search(text,flags,text_edit->cursor_get_line(),text_edit->cursor_get_column(),line,col); + int line=text_edit->cursor_get_line(),col=text_edit->cursor_get_column(); + + if (is_backwards()) { + col-=1; + if (col<0) { + line-=1; + if (line<0) { + line=text_edit->get_line_count()-1; + } + col=text_edit->get_line(line).length(); + } + } + bool found = text_edit->search(text,flags,line,col,line,col); if (found) { // print_line("found"); text_edit->cursor_set_line(line); - text_edit->cursor_set_column(col+text.length()); + if (is_backwards()) + text_edit->cursor_set_column(col); + else + text_edit->cursor_set_column(col+text.length()); text_edit->select(line,col,line,col+text.length()); set_error(""); return true; diff --git a/tools/editor/editor_path.cpp b/tools/editor/editor_path.cpp index 6c283d1f09b..83ca04fcab9 100644 --- a/tools/editor/editor_path.cpp +++ b/tools/editor/editor_path.cpp @@ -79,8 +79,14 @@ void EditorPath::_notification(int p_what) { } else if (obj->cast_to()) { name=obj->cast_to()->get_name(); - } else + } else if (obj->cast_to() && obj->cast_to()->get_name()!="") { + name=obj->cast_to()->get_name(); + } else { name=obj->get_type(); + } + + set_tooltip(obj->get_type()); + label_font->draw(ci,Point2i(ofs,(size.height-label_font->get_height())/2+label_font->get_ascent()),name,Color(1,1,1),left); } else { diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index e7f4beb46ee..87336b2f2ef 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -484,6 +484,16 @@ Node *SceneTreeDock::_duplicate(Node *p_node, Map &duplimap) { } + + List group_info; + p_node->get_groups(&group_info); + for (List::Element *E=group_info.front();E;E=E->next()) { + + if (E->get().persistent) + node->add_to_group(E->get().name,true); + } + + node->set_name(p_node->get_name()); duplimap[p_node]=node; diff --git a/tools/editor/scene_tree_editor.cpp b/tools/editor/scene_tree_editor.cpp index 59bc24487ae..9b4ef6cef19 100644 --- a/tools/editor/scene_tree_editor.cpp +++ b/tools/editor/scene_tree_editor.cpp @@ -224,7 +224,9 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) { if (p_node!=get_scene_node() && p_node->get_filename()!="" && can_open_instance) { item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE); - item->set_tooltip(0,"Instance: "+p_node->get_filename()); + item->set_tooltip(0,"Instance: "+p_node->get_filename()+"\nType: "+p_node->get_type()); + } else { + item->set_tooltip(0,String(p_node->get_name())+"\nType: "+p_node->get_type()); } if (can_open_instance) {