Browse Source

Fixed too many little issues, check the issues closed today.

Juan Linietsky 11 years ago
parent
commit
11a5ed508b

+ 13 - 0
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);
 
 

+ 3 - 0
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();

+ 2 - 0
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") );
 
 
 

+ 11 - 0
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);
 }
 

+ 5 - 0
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<String> 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();
 

+ 93 - 7
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<src_len;j++) {
+
+			int read_pos=i+j;
+
+			if (read_pos>=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<src_len;j++) {
+
+			int read_pos=i+j;
+
+			if (read_pos>=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;
 }
 

BIN
demos/3d/kinematic_char/level.scn


+ 5 - 0
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

+ 5 - 3
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);

+ 20 - 6
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 (<ip>:<port> 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()) {

+ 21 - 4
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;

+ 1 - 1
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;

+ 4 - 3
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);
 
 				}
 

+ 1 - 0
scene/2d/tile_map.cpp

@@ -329,6 +329,7 @@ Map<TileMap::PosKey,TileMap::Quadrant>::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);

+ 1 - 1
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 {

+ 32 - 4
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;

+ 2 - 1
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()) {
 			

+ 43 - 5
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;i<text.size()+1;i++) {
 		//backwards is broken...
-		int idx=(p_search_flags&SEARCH_BACKWARDS)?(text.size()-i):i; //do backwards seearch
-		line = (idx+p_from_line)%text.size();
+		//int idx=(p_search_flags&SEARCH_BACKWARDS)?(text.size()-i):i; //do backwards seearch
+
+
+		if (line<0) {
+			line=text.size()-1;
+		}
+		if (line==text.size()) {
+			line=0;
+		}
 
 		String text_line = text[line];
-		int from_column=(idx==0)?p_from_column:0;
-		if (idx==text.size()) {
-			text_line=text_line.substr(0,p_from_column); //wrap around for missing begining.
+		int from_column=0;
+		if (line==p_from_line) {
+
+			if (i==text.size()) {
+				//wrapped
+
+				if (p_search_flags&SEARCH_BACKWARDS) {
+					text_line=text_line.substr(from_column,text_line.length());
+					from_column=text_line.length();
+				} else {
+					text_line=text_line.substr(0,from_column);
+					from_column=0;
+				}
+
+			} else {
+
+				from_column=p_from_column;
+			}
+
+
+		} else {
+			//text_line=text_line.substr(0,p_from_column); //wrap around for missing begining.
+			if (p_search_flags&SEARCH_BACKWARDS)
+				from_column=text_line.length()-1;
+			else
+				from_column=0;
 		}
 
 		pos=-1;
 
 		if (!(p_search_flags&SEARCH_BACKWARDS)) {
+
 			pos = (p_search_flags&SEARCH_MATCH_CASE)?text_line.find(p_key,from_column):text_line.findn(p_key,from_column);
 		} else {
 
@@ -2642,6 +2675,11 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
 		if (pos!=-1)
 			break;
 
+		if (p_search_flags&SEARCH_BACKWARDS)
+			line--;
+		else
+			line++;
+
 	}
 
 	if (pos==-1) {

+ 6 - 3
scene/gui/tree.cpp

@@ -3009,20 +3009,23 @@ TreeItem* Tree::_find_item_at_pos(TreeItem*p_item, const Point2& p_pos,int& r_co
 String Tree::get_tooltip(const Point2& p_pos) const {
 
 	if (root) {
+
 		Point2 pos=p_pos;
 		pos -= cache.bg->get_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)=="")

+ 1 - 1
scene/main/node.cpp

@@ -1107,7 +1107,7 @@ void Node::get_groups(List<GroupInfo> *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<data.children.size();i++)
 		data.children[i]->_print_tree(p_node);
 }

+ 17 - 3
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;

+ 7 - 1
tools/editor/editor_path.cpp

@@ -79,8 +79,14 @@ void EditorPath::_notification(int p_what) {
 					} else if (obj->cast_to<Node>()) {
 
 						name=obj->cast_to<Node>()->get_name();
-					} else
+					} else if (obj->cast_to<Resource>() && obj->cast_to<Resource>()->get_name()!="") {
+						name=obj->cast_to<Resource>()->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 {

+ 10 - 0
tools/editor/scene_tree_dock.cpp

@@ -484,6 +484,16 @@ Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node*,Node*> &duplimap) {
 
 	}
 
+
+	List<Node::GroupInfo> group_info;
+	p_node->get_groups(&group_info);
+	for (List<Node::GroupInfo>::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;
 

+ 3 - 1
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) {