Browse Source

-variables with export in script are now IMMEDIATELY AND ALWAYS visible in properties (#718)
-WorldEnvironment cleanup issues fixed (#563)
-Text Editor improvement to shift-mouse selection (#648)
-(Hopefully) fixed rare (but horrible) indexing bug in GDScript compiler (#652)
-Some changes to PhysicsBody API, renamed property "active" to "sleeping", which makes more sense
-Added add_collision_exception() API in PhysicsBody (more accessible)
-ability to select and copy in the output messages panel

Juan Linietsky 11 years ago
parent
commit
048fdc8aea

+ 3 - 1
core/script_language.cpp

@@ -283,8 +283,10 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties,co
 		to_remove.pop_front();
 	}
 
-	if (owner && owner->get_script_instance()==this)
+	if (owner && owner->get_script_instance()==this) {
+
 		owner->_change_notify();
+	}
 	//change notify
 }
 

+ 2 - 0
core/script_language.h

@@ -92,6 +92,8 @@ public:
 
 	virtual ScriptLanguage *get_language() const=0;
 
+	virtual void update_exports() {} //editor tool
+
 	
 	Script() {}
 };

+ 17 - 4
modules/gdscript/gd_compiler.cpp

@@ -724,6 +724,8 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
 							return prev_pos;
 						int retval=prev_pos;
 
+						//print_line("retval: "+itos(retval));
+
 						if (retval&GDFunction::ADDR_TYPE_STACK<<GDFunction::ADDR_BITS) {
 							slevel++;
 							codegen.alloc_stack(slevel);
@@ -732,6 +734,8 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
 
 						Vector<int> setchain;
 
+						int prev_key_idx=-1;
+
 						for(List<GDParser::OperatorNode*>::Element *E=chain.back();E;E=E->prev()) {
 
 
@@ -743,16 +747,23 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
 
 							if (named) {
 
-								key_idx = codegen.get_name_map_pos(static_cast<const GDParser::IdentifierNode*>(E->get()->arguments[1])->name);
+								key_idx = codegen.get_name_map_pos(static_cast<const GDParser::IdentifierNode*>(E->get()->arguments[1])->name);								
+								//printf("named key %x\n",key_idx);
+
 							} else {
 
-								GDParser::Node *key = E->get()->arguments[1];
-								key_idx = _parse_expression(codegen,key,slevel);
-								if (retval&GDFunction::ADDR_TYPE_STACK<<GDFunction::ADDR_BITS) {
+								if (prev_pos&(GDFunction::ADDR_TYPE_STACK<<GDFunction::ADDR_BITS)) {
 									slevel++;
 									codegen.alloc_stack(slevel);
 								}
 
+								GDParser::Node *key = E->get()->arguments[1];
+								key_idx = _parse_expression(codegen,key,slevel);
+								//printf("expr key %x\n",key_idx);
+
+
+								//stack was raised here if retval was stack but..
+
 							}
 
 							if (key_idx<0)
@@ -764,6 +775,7 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
 							slevel++;
 							codegen.alloc_stack(slevel);
 							int dst_pos = (GDFunction::ADDR_TYPE_STACK<<GDFunction::ADDR_BITS)|slevel;
+
 							codegen.opcodes.push_back(dst_pos);
 
 							//add in reverse order, since it will be reverted
@@ -773,6 +785,7 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
 							setchain.push_back(named ? GDFunction::OPCODE_SET_NAMED : GDFunction::OPCODE_SET);
 
 							prev_pos=dst_pos;
+							prev_key_idx=key_idx;
 
 						}
 

+ 46 - 1
modules/gdscript/gd_script.cpp

@@ -1492,7 +1492,9 @@ Variant GDScript::_new(const Variant** p_args,int p_argcount,Variant::CallError&
 
 bool GDScript::can_instance() const {
 
-	return valid; //any script in GDscript can instance
+	//return valid; //any script in GDscript can instance
+	return valid || (!tool && !ScriptServer::is_scripting_enabled());
+
 }
 
 StringName GDScript::get_instance_base_type() const {
@@ -1565,8 +1567,10 @@ void GDScript::_update_placeholder(PlaceHolderScriptInstance *p_placeholder) {
 #endif
 ScriptInstance* GDScript::instance_create(Object *p_this) {
 
+
 	if (!tool && !ScriptServer::is_scripting_enabled()) {
 
+
 #ifdef TOOLS_ENABLED
 
 		//instance a fake script for editing the values
@@ -1620,7 +1624,48 @@ String GDScript::get_source_code() const {
 void GDScript::set_source_code(const String& p_code) {
 
 	source=p_code;
+}
+
+void GDScript::update_exports() {
+
+#ifdef TOOLS_ENABLED
+	String basedir=path;
+
+	if (basedir=="")
+		basedir=get_path();
+
+	if (basedir!="")
+		basedir=basedir.get_base_dir();
+
+	GDParser parser;
+	Error err = parser.parse(source,basedir,true);
+	if (err)
+		return; //do none
 
+	const GDParser::Node* root = parser.get_parse_tree();
+	ERR_FAIL_COND(root->type!=GDParser::Node::TYPE_CLASS);
+
+	const GDParser::ClassNode *c = static_cast<const GDParser::ClassNode*>(root);
+
+	List<PropertyInfo> plist;
+
+	Map<StringName,Variant> default_values;
+
+	for(int i=0;i<c->variables.size();i++) {
+		if (c->variables[i]._export.type==Variant::NIL)
+			continue;
+
+		plist.push_back(c->variables[i]._export);
+		default_values[c->variables[i].identifier]=c->variables[i].default_value;
+	}
+
+
+	for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) {
+
+		E->get()->update(plist,default_values);
+	}
+
+#endif
 }
 
 void GDScript::_set_subclass_path(Ref<GDScript>& p_sc,const String& p_path) {

+ 2 - 0
modules/gdscript/gd_script.h

@@ -299,6 +299,8 @@ public:
 	virtual bool has_source_code() const;
 	virtual String get_source_code() const;
 	virtual void set_source_code(const String& p_code);
+	virtual void update_exports();
+
 	virtual Error reload();
 
 	virtual String get_node_type() const;

+ 49 - 20
platform/windows/os_windows.cpp

@@ -211,45 +211,32 @@ bool OS_Windows::can_draw() const {
 #define IsPenEvent(dw) (((dw) & SIGNATURE_MASK) == MI_WP_SIGNATURE)
 
 
-void OS_Windows::_touch_event(int idx, UINT uMsg, WPARAM	wParam,	LPARAM	lParam) {
+void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) {
 
 	InputEvent event;
 	event.type = InputEvent::SCREEN_TOUCH;
 	event.ID=++last_id;
 	event.screen_touch.index = idx;
 
-	switch (uMsg) {
-		case WM_LBUTTONDOWN:
-		case WM_MBUTTONDOWN:
-		case WM_RBUTTONDOWN: {
+	event.screen_touch.pressed = p_pressed;
 
-			event.screen_touch.pressed = true;
-		} break;
-
-		case WM_LBUTTONUP:
-		case WM_MBUTTONUP:
-		case WM_RBUTTONUP: {
-			event.screen_touch.pressed = false;
-		} break;
-	};
-
-	event.screen_touch.x=GET_X_LPARAM(lParam);
-	event.screen_touch.y=GET_Y_LPARAM(lParam);
+	event.screen_touch.x=p_x;
+	event.screen_touch.y=p_y;
 
 	if (main_loop) {
 		input->parse_input_event(event);
 	}
 };
 
-void OS_Windows::_drag_event(int idx,UINT uMsg, WPARAM	wParam,	LPARAM	lParam) {
+void OS_Windows::_drag_event(int p_x, int p_y, int idx) {
 
 	InputEvent event;
 	event.type = InputEvent::SCREEN_DRAG;
 	event.ID=++last_id;
 	event.screen_drag.index = idx;
 
-	event.screen_drag.x=GET_X_LPARAM(lParam);
-	event.screen_drag.y=GET_Y_LPARAM(lParam);
+	event.screen_drag.x=p_x;
+	event.screen_drag.y=p_y;
 
 	if (main_loop)
 		input->parse_input_event(event);
@@ -341,6 +328,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM	wParam,	LPARAM	lParam) {
 
 			}
 
+			/*
 			LPARAM extra = GetMessageExtraInfo();
 			if (IsPenEvent(extra)) {
 
@@ -351,6 +339,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM	wParam,	LPARAM	lParam) {
 				};
 				// fallthrough for mouse event
 			};
+			*/
 
 
 			InputEvent event;
@@ -421,6 +410,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM	wParam,	LPARAM	lParam) {
 		/*case WM_XBUTTONDOWN:
 		case WM_XBUTTONUP: */{
 
+			/*
 			LPARAM extra = GetMessageExtraInfo();
 			if (IsPenEvent(extra)) {
 
@@ -431,6 +421,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM	wParam,	LPARAM	lParam) {
 				};
 				// fallthrough for mouse event
 			};
+			*/
 
 			InputEvent event;
 			event.type=InputEvent::MOUSE_BUTTON;
@@ -621,6 +612,43 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM	wParam,	LPARAM	lParam) {
 
 			print_line("input lang change");
 		} break;
+
+		#if WINVER >= 0x0700 // for windows 7
+		case WM_TOUCH: {
+
+			BOOL bHandled = FALSE;
+			UINT cInputs = LOWORD(wParam);
+			PTOUCHINPUT pInputs = memnew_arr(TOUCHINPUT, cInputs);
+			if (pInputs){
+				if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))){
+					for (UINT i=0; i < cInputs; i++){
+						TOUCHINPUT ti = pInputs[i];
+						//do something with each touch input entry
+						if (ti.dwFlags & TOUCHEVENTF_MOVE) {
+
+							_drag_event(ti.x / 100, ti.y / 100, ti.dwID);
+						} else if (ti.dwFlags & (TOUCHEVENTF_UP | TOUCHEVENTF_DOWN)) {
+
+							_touch_event(ti.dwFlags & TOUCHEVENTF_DOWN != 0, ti.x / 100, ti.y / 100, ti.dwID);
+						};
+					}
+					bHandled = TRUE;
+				}else{
+					 /* handle the error here */
+				}
+				memdelete_arr(pInputs);
+			}else{
+				/* handle the error here, probably out of memory */
+			}
+			if (bHandled) {
+				CloseTouchInputHandle((HTOUCHINPUT)lParam);
+				return 0;
+			};
+
+		} break;
+
+		#endif
+
 		default: {
 
 			if (user_proc) {
@@ -1106,6 +1134,7 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_
 	tme.dwHoverTime=HOVER_DEFAULT;
 	TrackMouseEvent(&tme);
 
+	//RegisterTouchWindow(hWnd, 0); // Windows 7
 
 	_ensure_data_dir();
 

+ 2 - 3
platform/windows/os_windows.h

@@ -160,9 +160,8 @@ class OS_Windows : public OS {
 
 	void _post_dpad(DWORD p_dpad, int p_device, bool p_pressed);
 
-	void _drag_event(int idx,UINT uMsg, WPARAM	wParam,	LPARAM	lParam);
-	void _touch_event(int idx, UINT uMsg, WPARAM	wParam,	LPARAM	lParam);
-
+	void _drag_event(int p_x, int p_y, int idx);
+	void _touch_event(bool p_pressed, int p_x, int p_y, int idx);
 
 	// functions used by main to initialize/deintialize the OS
 protected:	

+ 3 - 0
scene/2d/collision_shape_2d.cpp

@@ -72,6 +72,9 @@ void CollisionShape2D::_notification(int p_what) {
 
 	switch(p_what) {
 
+		case NOTIFICATION_ENTER_SCENE: {
+			unparenting=false;
+		} break;
 		case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
 
 			if (!is_inside_scene())

+ 35 - 10
scene/2d/physics_body_2d.cpp

@@ -47,6 +47,8 @@ void PhysicsBody2D::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask);
 	ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask);
+	ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with);
+	ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with);
 	ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
 }
 
@@ -67,6 +69,29 @@ PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject
 
 }
 
+void PhysicsBody2D::add_collision_exception_with(Node* p_node) {
+
+	ERR_FAIL_NULL(p_node);
+	PhysicsBody2D *physics_body = p_node->cast_to<PhysicsBody2D>();
+	if (!physics_body) {
+		ERR_EXPLAIN("Collision exception only works between two objects of PhysicsBody type");
+	}
+	ERR_FAIL_COND(!physics_body);
+	Physics2DServer::get_singleton()->body_add_collision_exception(get_rid(),physics_body->get_rid());
+
+}
+
+void PhysicsBody2D::remove_collision_exception_with(Node* p_node) {
+
+	ERR_FAIL_NULL(p_node);
+	PhysicsBody2D *physics_body = p_node->cast_to<PhysicsBody2D>();
+	if (!physics_body) {
+		ERR_EXPLAIN("Collision exception only works between two objects of PhysicsBody type");
+	}
+	ERR_FAIL_COND(!physics_body);
+	Physics2DServer::get_singleton()->body_remove_collision_exception(get_rid(),physics_body->get_rid());
+}
+
 void StaticBody2D::set_constant_linear_velocity(const Vector2& p_vel) {
 
 	constant_linear_velocity=p_vel;
@@ -375,7 +400,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
 		set_global_transform(state->get_transform());
 	linear_velocity=state->get_linear_velocity();
 	angular_velocity=state->get_angular_velocity();
-	active=!state->is_sleeping();
+	sleeping=state->is_sleeping();
 	if (get_script_instance())
 		get_script_instance()->call("_integrate_forces",state);
 	set_block_transform_notify(false); // want it back
@@ -525,10 +550,10 @@ bool RigidBody2D::is_using_custom_integrator(){
 	return custom_integrator;
 }
 
-void RigidBody2D::set_active(bool p_active) {
+void RigidBody2D::set_sleeping(bool p_sleeping) {
 
-	active=p_active;
-	Physics2DServer::get_singleton()->body_set_state(get_rid(),Physics2DServer::BODY_STATE_SLEEPING,!active);
+	sleeping=p_sleeping;
+	Physics2DServer::get_singleton()->body_set_state(get_rid(),Physics2DServer::BODY_STATE_SLEEPING,sleeping);
 
 }
 
@@ -543,9 +568,9 @@ bool RigidBody2D::is_able_to_sleep() const {
 	return can_sleep;
 }
 
-bool RigidBody2D::is_active() const {
+bool RigidBody2D::is_sleeping() const {
 
-	return active;
+	return sleeping;
 }
 
 void RigidBody2D::set_max_contacts_reported(int p_amount) {
@@ -657,8 +682,8 @@ void RigidBody2D::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_applied_force","force"),&RigidBody2D::set_applied_force);
 	ObjectTypeDB::bind_method(_MD("get_applied_force"),&RigidBody2D::get_applied_force);
 
-	ObjectTypeDB::bind_method(_MD("set_active","active"),&RigidBody2D::set_active);
-	ObjectTypeDB::bind_method(_MD("is_active"),&RigidBody2D::is_active);
+	ObjectTypeDB::bind_method(_MD("set_sleeping","sleeping"),&RigidBody2D::set_sleeping);
+	ObjectTypeDB::bind_method(_MD("is_sleeping"),&RigidBody2D::is_sleeping);
 
 	ObjectTypeDB::bind_method(_MD("set_can_sleep","able_to_sleep"),&RigidBody2D::set_can_sleep);
 	ObjectTypeDB::bind_method(_MD("is_able_to_sleep"),&RigidBody2D::is_able_to_sleep);
@@ -678,7 +703,7 @@ void RigidBody2D::_bind_methods() {
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"continuous_cd",PROPERTY_HINT_ENUM,"Disabled,Cast Ray,Cast Shape"),_SCS("set_continuous_collision_detection_mode"),_SCS("get_continuous_collision_detection_mode"));
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"contacts_reported"),_SCS("set_max_contacts_reported"),_SCS("get_max_contacts_reported"));
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"contact_monitor"),_SCS("set_contact_monitor"),_SCS("is_contact_monitor_enabled"));
-	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"active"),_SCS("set_active"),_SCS("is_active"));
+	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"sleeping"),_SCS("set_sleeping"),_SCS("is_sleeping"));
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"can_sleep"),_SCS("set_can_sleep"),_SCS("is_able_to_sleep"));
 	ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"velocity/linear"),_SCS("set_linear_velocity"),_SCS("get_linear_velocity"));
 	ADD_PROPERTY( PropertyInfo(Variant::REAL,"velocity/angular"),_SCS("set_angular_velocity"),_SCS("get_angular_velocity"));
@@ -710,7 +735,7 @@ RigidBody2D::RigidBody2D() : PhysicsBody2D(Physics2DServer::BODY_MODE_RIGID) {
 	state=NULL;
 
 	angular_velocity=0;
-	active=true;
+	sleeping=false;
 	ccd_mode=CCD_MODE_DISABLED;
 
 	custom_integrator=false;

+ 6 - 3
scene/2d/physics_body_2d.h

@@ -50,6 +50,9 @@ public:
 	void set_layer_mask(uint32_t p_mask);
 	uint32_t get_layer_mask() const;
 
+	void add_collision_exception_with(Node* p_node); //must be physicsbody
+	void remove_collision_exception_with(Node* p_node);
+
 	PhysicsBody2D();
 
 };
@@ -119,7 +122,7 @@ private:
 
 	Vector2 linear_velocity;
 	real_t angular_velocity;
-	bool active;
+	bool sleeping;
 
 
 	int max_contacts_reported;
@@ -206,8 +209,8 @@ public:
 	void set_use_custom_integrator(bool p_enable);
 	bool is_using_custom_integrator();
 
-	void set_active(bool p_active);
-	bool is_active() const;
+	void set_sleeping(bool p_sleeping);
+	bool is_sleeping() const;
 
 	void set_can_sleep(bool p_active);
 	bool is_able_to_sleep() const;

+ 2 - 2
scene/2d/visibility_notifier_2d.cpp

@@ -254,10 +254,10 @@ void VisibilityEnabler2D::_change_node_state(Node* p_node,bool p_enabled) {
 			if (p_enabled) {
 				RigidBody2D::Mode mode = RigidBody2D::Mode(nodes[p_node].operator int());
 				//rb->set_mode(mode);
-				rb->set_active(true);
+				rb->set_sleeping(false);
 			} else {
 				//rb->set_mode(RigidBody2D::MODE_STATIC);
-				rb->set_active(false);
+				rb->set_sleeping(true);
 			}
 		}
 	}

+ 10 - 10
scene/3d/physics_body.cpp

@@ -368,7 +368,7 @@ void RigidBody::_direct_state_changed(Object *p_state) {
 	set_global_transform(state->get_transform());
 	linear_velocity=state->get_linear_velocity();
 	angular_velocity=state->get_angular_velocity();
-	active=!state->is_sleeping();
+	sleeping=state->is_sleeping();
 	if (get_script_instance())
 		get_script_instance()->call("_integrate_forces",state);
 	set_ignore_transform_notification(false);
@@ -519,10 +519,10 @@ bool RigidBody::is_using_custom_integrator(){
 	return custom_integrator;
 }
 
-void RigidBody::set_active(bool p_active) {
+void RigidBody::set_sleeping(bool p_sleeping) {
 
-	active=p_active;
-	PhysicsServer::get_singleton()->body_set_state(get_rid(),PhysicsServer::BODY_STATE_SLEEPING,!active);
+	sleeping=p_sleeping;
+	PhysicsServer::get_singleton()->body_set_state(get_rid(),PhysicsServer::BODY_STATE_SLEEPING,sleeping);
 
 }
 
@@ -537,9 +537,9 @@ bool RigidBody::is_able_to_sleep() const {
 	return can_sleep;
 }
 
-bool RigidBody::is_active() const {
+bool RigidBody::is_sleeping() const {
 
-	return active;
+	return sleeping;
 }
 
 void RigidBody::set_max_contacts_reported(int p_amount) {
@@ -647,8 +647,8 @@ void RigidBody::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_axis_velocity","axis_velocity"),&RigidBody::set_axis_velocity);
 	ObjectTypeDB::bind_method(_MD("apply_impulse","pos","impulse"),&RigidBody::apply_impulse);
 
-	ObjectTypeDB::bind_method(_MD("set_active","active"),&RigidBody::set_active);
-	ObjectTypeDB::bind_method(_MD("is_active"),&RigidBody::is_active);
+	ObjectTypeDB::bind_method(_MD("set_sleeping","sleeping"),&RigidBody::set_sleeping);
+	ObjectTypeDB::bind_method(_MD("is_sleeping"),&RigidBody::is_sleeping);
 
 	ObjectTypeDB::bind_method(_MD("set_can_sleep","able_to_sleep"),&RigidBody::set_can_sleep);
 	ObjectTypeDB::bind_method(_MD("is_able_to_sleep"),&RigidBody::is_able_to_sleep);
@@ -671,7 +671,7 @@ void RigidBody::_bind_methods() {
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"continuous_cd"),_SCS("set_use_continuous_collision_detection"),_SCS("is_using_continuous_collision_detection"));
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"contacts_reported"),_SCS("set_max_contacts_reported"),_SCS("get_max_contacts_reported"));
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"contact_monitor"),_SCS("set_contact_monitor"),_SCS("is_contact_monitor_enabled"));
-	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"active"),_SCS("set_active"),_SCS("is_active"));
+	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"sleeping"),_SCS("set_sleeping"),_SCS("is_sleeping"));
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"can_sleep"),_SCS("set_can_sleep"),_SCS("is_able_to_sleep"));
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"axis_lock",PROPERTY_HINT_ENUM,"Disabled,Lock X,Lock Y,Lock Z"),_SCS("set_axis_lock"),_SCS("get_axis_lock"));
 	ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"velocity/linear"),_SCS("set_linear_velocity"),_SCS("get_linear_velocity"));
@@ -699,7 +699,7 @@ RigidBody::RigidBody() : PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
 	state=NULL;
 
 	//angular_velocity=0;
-	active=true;
+	sleeping=false;
 	ccd=false;
 
 	custom_integrator=false;

+ 3 - 3
scene/3d/physics_body.h

@@ -125,7 +125,7 @@ private:
 
 	Vector3 linear_velocity;
 	Vector3  angular_velocity;
-	bool active;
+	bool sleeping;
 	bool ccd;
 
 	AxisLock axis_lock;
@@ -216,8 +216,8 @@ public:
 	void set_use_custom_integrator(bool p_enable);
 	bool is_using_custom_integrator();
 
-	void set_active(bool p_active);
-	bool is_active() const;
+	void set_sleeping(bool p_sleeping);
+	bool is_sleeping() const;
 
 	void set_can_sleep(bool p_active);
 	bool is_able_to_sleep() const;

+ 19 - 4
scene/3d/scenario_fx.cpp

@@ -35,20 +35,35 @@ void WorldEnvironment::_notification(int p_what) {
 
 	if (p_what==NOTIFICATION_ENTER_WORLD) {
 
-		get_world()->set_environment(environment);
+		if (environment.is_valid()) {
+			if (get_world()->get_environment().is_valid()) {
+				WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
+			}
+			get_world()->set_environment(environment);
+		}
+
 	} else if (p_what==NOTIFICATION_EXIT_WORLD) {
 
-		get_world()->set_environment(Ref<Environment>());
+		if (environment.is_valid() && get_world()->get_environment()==environment)
+			get_world()->set_environment(Ref<Environment>());
 	}
 }
 
 void WorldEnvironment::set_environment(const Ref<Environment>& p_environment) {
 
+	if (is_inside_world() && environment.is_valid() && get_world()->get_environment()==environment) {
+		get_world()->set_environment(Ref<Environment>());
+		//clean up
+	}
+
+
 	environment=p_environment;
-	if (is_inside_world()) {
+	if (is_inside_world() && environment.is_valid()) {
+		if (get_world()->get_environment().is_valid()) {
+			WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
+		}
 		get_world()->set_environment(environment);
 	}
-
 }
 
 Ref<Environment> WorldEnvironment::get_environment() const {

+ 2 - 2
scene/3d/visibility_notifier.cpp

@@ -247,10 +247,10 @@ void VisibilityEnabler::_change_node_state(Node* p_node,bool p_enabled) {
 			if (p_enabled) {
 				RigidBody::Mode mode = RigidBody::Mode(nodes[p_node].operator int());
 				//rb->set_mode(mode);
-				rb->set_active(true);
+				rb->set_sleeping(false);
 			} else {
 				//rb->set_mode(RigidBody::MODE_STATIC);
-				rb->set_active(false);
+				rb->set_sleeping(true);
 			}
 		}
 	}

+ 28 - 4
scene/gui/text_edit.cpp

@@ -935,16 +935,40 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
 					if (!_get_mouse_pos(Point2i(mb.x,mb.y), row,col))
 						return;
 
+					int prev_col=cursor.column;
+					int prev_line=cursor.line;
+
+
+
 					cursor_set_line( row );
 					cursor_set_column( col );
 
+					if (mb.mod.shift && (cursor.column!=prev_col || cursor.line!=prev_line)) {
+
+						selection.active=true;
+						selection.selecting_mode=Selection::MODE_POINTER;
+						selection.from_column=prev_col;
+						selection.from_line=prev_line;
+						selection.to_column=cursor.column;
+						selection.to_line=cursor.line;
+						if (selection.from_column>selection.to_column) {
+							SWAP(selection.from_column,selection.to_column);
+							SWAP(selection.from_line,selection.to_line);
+						}
+						selection.selecting_line=prev_line;
+						selection.selecting_column=prev_col;
+						update();
+
+					} else {
+
 					//if sel active and dblick last time < something
 
 					//else
-					selection.active=false;
-					selection.selecting_mode=Selection::MODE_POINTER;
-					selection.selecting_line=row;
-					selection.selecting_column=col;
+						selection.active=false;
+						selection.selecting_mode=Selection::MODE_POINTER;
+						selection.selecting_line=row;
+						selection.selecting_column=col;
+					}
 
 
 					if (!mb.doubleclick && (OS::get_singleton()->get_ticks_msec()-last_dblclk)<600) {

+ 2 - 0
tools/editor/editor_log.cpp

@@ -216,6 +216,8 @@ EditorLog::EditorLog() {
 
 	log = memnew( RichTextLabel );
 	log->set_scroll_follow(true);
+	log->set_selection_enabled(true);
+	log->set_focus_mode(FOCUS_CLICK);
 	pc->add_child(log);
 	add_message(VERSION_FULL_NAME" (c) 2008-2014 Juan Linietsky, Ariel Manzur.");
 	//log->add_text("Initialization Complete.\n"); //because it looks cool.

+ 4 - 1
tools/editor/plugins/script_editor_plugin.cpp

@@ -188,7 +188,9 @@ void ScriptTextEditor::apply_code() {
 
 	if (script.is_null())
 		return;
+	print_line("applying code");
 	script->set_source_code(get_text_edit()->get_text());
+	script->update_exports();
 }
 
 Ref<Script> ScriptTextEditor::get_edited_script() const {
@@ -362,7 +364,8 @@ void ScriptTextEditor::_validate_script() {
 		line=-1;
 		if (!script->is_tool()) {
 			script->set_source_code(text);
-			script->reload(); //will update all the variables in property editors
+			script->update_exports();
+			//script->reload(); //will update all the variables in property editors
 		}
 
 		functions.clear();