Live edit WORK IN PROGRESS
1) press the heart while the game is running 2) select a scene to live edit from the opened scenes 3) edit/add/remove nodes or resources, change their properties, etc. 4) watch changes reflected in running game, in all places this scene is edited 5) It's not perfect obviously, but the aim of it is to try to reflect your changes as best as possible in the running game.
This commit is contained in:
parent
922356b903
commit
59961c9914
22 changed files with 1347 additions and 244 deletions
|
@ -127,7 +127,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
|
|||
ERR_CONTINUE( cmd[0].get_type()!=Variant::STRING );
|
||||
|
||||
String command = cmd[0];
|
||||
cmd.remove(0);
|
||||
|
||||
|
||||
|
||||
if (command=="get_stack_dump") {
|
||||
|
@ -150,7 +150,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
|
|||
|
||||
} else if (command=="get_stack_frame_vars") {
|
||||
|
||||
|
||||
cmd.remove(0);
|
||||
ERR_CONTINUE( cmd.size()!=1 );
|
||||
int lv = cmd[0];
|
||||
|
||||
|
@ -243,6 +243,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
|
|||
|
||||
if (request_scene_tree)
|
||||
request_scene_tree(request_scene_tree_ud);
|
||||
} else {
|
||||
_parse_live_edit(cmd);
|
||||
}
|
||||
|
||||
|
||||
|
@ -301,6 +303,105 @@ void ScriptDebuggerRemote::line_poll() {
|
|||
}
|
||||
|
||||
|
||||
bool ScriptDebuggerRemote::_parse_live_edit(const Array& cmd) {
|
||||
|
||||
String cmdstr = cmd[0];
|
||||
if (!live_edit_funcs || !cmdstr.begins_with("live_"))
|
||||
return false;
|
||||
|
||||
|
||||
print_line(Variant(cmd).get_construct_string());
|
||||
if (cmdstr=="live_set_root") {
|
||||
|
||||
if (!live_edit_funcs->root_func)
|
||||
return true;
|
||||
print_line("root: "+Variant(cmd).get_construct_string());
|
||||
live_edit_funcs->root_func(live_edit_funcs->udata,cmd[1],cmd[2]);
|
||||
|
||||
} else if (cmdstr=="live_node_path") {
|
||||
|
||||
if (!live_edit_funcs->node_path_func)
|
||||
return true;
|
||||
print_line("path: "+Variant(cmd).get_construct_string());
|
||||
|
||||
live_edit_funcs->node_path_func(live_edit_funcs->udata,cmd[1],cmd[2]);
|
||||
|
||||
} else if (cmdstr=="live_res_path") {
|
||||
|
||||
if (!live_edit_funcs->res_path_func)
|
||||
return true;
|
||||
live_edit_funcs->res_path_func(live_edit_funcs->udata,cmd[1],cmd[2]);
|
||||
|
||||
} else if (cmdstr=="live_node_prop_res") {
|
||||
if (!live_edit_funcs->node_set_res_func)
|
||||
return true;
|
||||
|
||||
live_edit_funcs->node_set_res_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_node_prop") {
|
||||
|
||||
if (!live_edit_funcs->node_set_func)
|
||||
return true;
|
||||
live_edit_funcs->node_set_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_res_prop_res") {
|
||||
|
||||
if (!live_edit_funcs->res_set_res_func)
|
||||
return true;
|
||||
live_edit_funcs->res_set_res_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_res_prop") {
|
||||
|
||||
if (!live_edit_funcs->res_set_func)
|
||||
return true;
|
||||
live_edit_funcs->res_set_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_node_call") {
|
||||
|
||||
if (!live_edit_funcs->node_call_func)
|
||||
return true;
|
||||
live_edit_funcs->node_call_func(live_edit_funcs->udata,cmd[1],cmd[2], cmd[3],cmd[4],cmd[5],cmd[6],cmd[7]);
|
||||
|
||||
} else if (cmdstr=="live_res_call") {
|
||||
|
||||
if (!live_edit_funcs->res_call_func)
|
||||
return true;
|
||||
live_edit_funcs->res_call_func(live_edit_funcs->udata,cmd[1],cmd[2], cmd[3],cmd[4],cmd[5],cmd[6],cmd[7]);
|
||||
|
||||
} else if (cmdstr=="live_create_node") {
|
||||
|
||||
live_edit_funcs->tree_create_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_instance_node") {
|
||||
|
||||
live_edit_funcs->tree_instance_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_remove_node") {
|
||||
|
||||
live_edit_funcs->tree_remove_node_func(live_edit_funcs->udata,cmd[1]);
|
||||
|
||||
} else if (cmdstr=="live_remove_and_keep_node") {
|
||||
|
||||
live_edit_funcs->tree_remove_and_keep_node_func(live_edit_funcs->udata,cmd[1],cmd[2]);
|
||||
} else if (cmdstr=="live_restore_node") {
|
||||
|
||||
live_edit_funcs->tree_restore_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_duplicate_node") {
|
||||
|
||||
live_edit_funcs->tree_duplicate_node_func(live_edit_funcs->udata,cmd[1],cmd[2]);
|
||||
} else if (cmdstr=="live_reparent_node") {
|
||||
|
||||
live_edit_funcs->tree_reparent_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptDebuggerRemote::_poll_events() {
|
||||
|
||||
while(packet_peer_stream->get_available_packet_count()>0) {
|
||||
|
@ -321,7 +422,7 @@ void ScriptDebuggerRemote::_poll_events() {
|
|||
ERR_CONTINUE( cmd[0].get_type()!=Variant::STRING );
|
||||
|
||||
String command = cmd[0];
|
||||
cmd.remove(0);
|
||||
//cmd.remove(0);
|
||||
|
||||
if (command=="break") {
|
||||
|
||||
|
@ -331,6 +432,8 @@ void ScriptDebuggerRemote::_poll_events() {
|
|||
|
||||
if (request_scene_tree)
|
||||
request_scene_tree(request_scene_tree_ud);
|
||||
} else {
|
||||
_parse_live_edit(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -413,6 +516,11 @@ void ScriptDebuggerRemote::set_request_scene_tree_message_func(RequestSceneTreeM
|
|||
request_scene_tree_ud=p_udata;
|
||||
}
|
||||
|
||||
void ScriptDebuggerRemote::set_live_edit_funcs(LiveEditFuncs *p_funcs) {
|
||||
|
||||
live_edit_funcs=p_funcs;
|
||||
}
|
||||
|
||||
ScriptDebuggerRemote::ScriptDebuggerRemote() {
|
||||
|
||||
tcp_client = StreamPeerTCP::create_ref();
|
||||
|
@ -429,6 +537,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() {
|
|||
last_perf_time=0;
|
||||
poll_every=0;
|
||||
request_scene_tree=NULL;
|
||||
live_edit_funcs=NULL;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -62,9 +62,12 @@ class ScriptDebuggerRemote : public ScriptDebugger {
|
|||
uint32_t poll_every;
|
||||
|
||||
|
||||
bool _parse_live_edit(const Array &p_command);
|
||||
|
||||
RequestSceneTreeMessageFunc request_scene_tree;
|
||||
void *request_scene_tree_ud;
|
||||
|
||||
LiveEditFuncs *live_edit_funcs;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -79,6 +82,7 @@ public:
|
|||
virtual void send_message(const String& p_message, const Array& p_args);
|
||||
|
||||
virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata);
|
||||
virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs);
|
||||
|
||||
ScriptDebuggerRemote();
|
||||
~ScriptDebuggerRemote();
|
||||
|
|
|
@ -238,6 +238,32 @@ public:
|
|||
|
||||
typedef void (*RequestSceneTreeMessageFunc)(void *);
|
||||
|
||||
struct LiveEditFuncs {
|
||||
|
||||
void *udata;
|
||||
void (*node_path_func)(void *,const NodePath &p_path,int p_id);
|
||||
void (*res_path_func)(void *,const String &p_path,int p_id);
|
||||
|
||||
void (*node_set_func)(void *,int p_id,const StringName& p_prop,const Variant& p_value);
|
||||
void (*node_set_res_func)(void *,int p_id,const StringName& p_prop,const String& p_value);
|
||||
void (*node_call_func)(void *,int p_id,const StringName& p_method,VARIANT_ARG_DECLARE);
|
||||
void (*res_set_func)(void *,int p_id,const StringName& p_prop,const Variant& p_value);
|
||||
void (*res_set_res_func)(void *,int p_id,const StringName& p_prop,const String& p_value);
|
||||
void (*res_call_func)(void *,int p_id,const StringName& p_method,VARIANT_ARG_DECLARE);
|
||||
void (*root_func)(void*, const NodePath& p_scene_path,const String& p_scene_from);
|
||||
|
||||
void (*tree_create_node_func)(void*,const NodePath& p_parent,const String& p_type,const String& p_name);
|
||||
void (*tree_instance_node_func)(void*,const NodePath& p_parent,const String& p_path,const String& p_name);
|
||||
void (*tree_remove_node_func)(void*,const NodePath& p_at);
|
||||
void (*tree_remove_and_keep_node_func)(void*,const NodePath& p_at,ObjectID p_keep_id);
|
||||
void (*tree_restore_node_func)(void*,ObjectID p_id,const NodePath& p_at,int p_at_pos);
|
||||
void (*tree_duplicate_node_func)(void*,const NodePath& p_at,const String& p_new_name);
|
||||
void (*tree_reparent_node_func)(void*,const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
_FORCE_INLINE_ static ScriptDebugger * get_singleton() { return singleton; }
|
||||
void set_lines_left(int p_left);
|
||||
int get_lines_left() const;
|
||||
|
@ -252,10 +278,12 @@ public:
|
|||
bool is_breakpoint_line(int p_line) const;
|
||||
void clear_breakpoints();
|
||||
|
||||
|
||||
virtual void debug(ScriptLanguage *p_script,bool p_can_continue=true)=0;
|
||||
virtual void idle_poll();
|
||||
virtual void line_poll();
|
||||
|
||||
|
||||
void set_break_language(ScriptLanguage *p_lang);
|
||||
ScriptLanguage* get_break_language() const;
|
||||
|
||||
|
@ -265,6 +293,7 @@ public:
|
|||
virtual void request_quit() {}
|
||||
|
||||
virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata) {}
|
||||
virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs) {}
|
||||
|
||||
ScriptDebugger();
|
||||
virtual ~ScriptDebugger() {singleton=NULL;}
|
||||
|
|
|
@ -244,7 +244,12 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
|
|||
Resource* res = obj->cast_to<Resource>();
|
||||
if (res)
|
||||
res->set_edited(true);
|
||||
|
||||
#endif
|
||||
|
||||
if (method_callback) {
|
||||
method_callback(method_callbck_ud,obj,op.name,VARIANT_ARGS_FROM_ARRAY(op.args));
|
||||
}
|
||||
} break;
|
||||
case Operation::TYPE_PROPERTY: {
|
||||
|
||||
|
@ -254,6 +259,9 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
|
|||
if (res)
|
||||
res->set_edited(true);
|
||||
#endif
|
||||
if (property_callback) {
|
||||
property_callback(prop_callback_ud,obj,op.name,op.args[0]);
|
||||
}
|
||||
} break;
|
||||
case Operation::TYPE_REFERENCE: {
|
||||
//do nothing
|
||||
|
@ -325,6 +333,19 @@ void UndoRedo::set_commit_notify_callback(CommitNotifyCallback p_callback,void*
|
|||
callback_ud=p_ud;
|
||||
}
|
||||
|
||||
void UndoRedo::set_method_notify_callback(MethodNotifyCallback p_method_callback,void* p_ud) {
|
||||
|
||||
method_callback=p_method_callback;
|
||||
method_callbck_ud=p_ud;
|
||||
}
|
||||
|
||||
void UndoRedo::set_property_notify_callback(PropertyNotifyCallback p_property_callback,void* p_ud){
|
||||
|
||||
property_callback=p_property_callback;
|
||||
prop_callback_ud=p_ud;
|
||||
}
|
||||
|
||||
|
||||
UndoRedo::UndoRedo() {
|
||||
|
||||
version=1;
|
||||
|
@ -334,6 +355,12 @@ UndoRedo::UndoRedo() {
|
|||
merging=true;
|
||||
callback=NULL;
|
||||
callback_ud=NULL;
|
||||
|
||||
method_callbck_ud=NULL;
|
||||
prop_callback_ud=NULL;
|
||||
method_callback=NULL;
|
||||
property_callback=NULL;
|
||||
|
||||
}
|
||||
|
||||
UndoRedo::~UndoRedo() {
|
||||
|
|
|
@ -45,6 +45,9 @@ public:
|
|||
Variant _add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
|
||||
Variant _add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
|
||||
|
||||
typedef void (*MethodNotifyCallback)(void *p_ud,Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE);
|
||||
typedef void (*PropertyNotifyCallback)(void *p_ud,Object*p_base,const StringName& p_property,const Variant& p_value);
|
||||
|
||||
private:
|
||||
struct Operation {
|
||||
|
||||
|
@ -83,6 +86,11 @@ private:
|
|||
|
||||
CommitNotifyCallback callback;
|
||||
void* callback_ud;
|
||||
void* method_callbck_ud;
|
||||
void* prop_callback_ud;
|
||||
|
||||
MethodNotifyCallback method_callback;
|
||||
PropertyNotifyCallback property_callback;
|
||||
|
||||
|
||||
protected:
|
||||
|
@ -113,6 +121,9 @@ public:
|
|||
|
||||
void set_commit_notify_callback(CommitNotifyCallback p_callback,void* p_ud);
|
||||
|
||||
void set_method_notify_callback(MethodNotifyCallback p_method_callback,void* p_ud);
|
||||
void set_property_notify_callback(PropertyNotifyCallback p_property_callback,void* p_ud);
|
||||
|
||||
UndoRedo();
|
||||
~UndoRedo();
|
||||
};
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<resource_file type="PackedScene" subresource_count="24" version="1.0" version_name="Godot Engine v1.0.rc2.custom_build">
|
||||
<ext_resource path="res://osb_jump.png" type="Texture"></ext_resource>
|
||||
<resource_file type="PackedScene" subresource_count="25" version="1.1" version_name="Godot Engine v1.1.stable.custom_build">
|
||||
<ext_resource path="res://player.gd" type="Script"></ext_resource>
|
||||
<ext_resource path="res://robot_demo.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://bullet.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_right.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://sound_coin.wav" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://osb_fire.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://sound_jump.wav" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://sound_shoot.wav" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://osb_left.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://robot_demo.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://player.gd" type="Script"></ext_resource>
|
||||
<ext_resource path="res://sound_jump.wav" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://osb_right.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_jump.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_fire.png" type="Texture"></ext_resource>
|
||||
<resource type="RayShape2D" path="local://1">
|
||||
<real name="custom_solver_bias"> 0.5 </real>
|
||||
<real name="length"> 20 </real>
|
||||
|
@ -19,6 +19,11 @@
|
|||
<real name="custom_solver_bias"> 0 </real>
|
||||
<vector2_array name="points" len="3"> -19.902, -24.8691, 19.3625, -24.6056, -0.138023, 16.5036 </vector2_array>
|
||||
|
||||
</resource>
|
||||
<resource type="ColorRamp" path="local://14">
|
||||
<real_array name="offsets" len="2"> 0, 1 </real_array>
|
||||
<color_array name="colors" len="2"> 1, 1, 1, 1, 0, 0, 0, 0.0442478 </color_array>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://3">
|
||||
<string name="resource/name"> "idle" </string>
|
||||
|
@ -31,6 +36,8 @@
|
|||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="8"> 0, 1.25, 1.5, 2, 4.5, 4.75, 5, 5.25 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="8"> 1, 1, 1, 1, 1, 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
|
@ -44,8 +51,6 @@
|
|||
<int> 19 </int>
|
||||
<int> 16 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="8"> 0, 1.25, 1.5, 2, 4.5, 4.75, 5, 5.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
|
@ -60,6 +65,8 @@
|
|||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="3"> 0, 0.25, 0.5 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="3"> 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
|
@ -68,8 +75,6 @@
|
|||
<int> 24 </int>
|
||||
<int> 23 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="3"> 0, 0.25, 0.5 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
|
@ -84,14 +89,14 @@
|
|||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 25 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
|
@ -105,6 +110,8 @@
|
|||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
|
@ -116,56 +123,10 @@
|
|||
<int> 4 </int>
|
||||
<int> 0 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://7">
|
||||
<string name="resource/name"> "crouch" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 22 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://8">
|
||||
<string name="resource/name"> "falling" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 21 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://9">
|
||||
<resource type="Animation" path="local://11">
|
||||
<real name="length"> 1.25 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
|
@ -175,19 +136,19 @@
|
|||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="6" shared="false">
|
||||
<int> 10 </int>
|
||||
<int> 11 </int>
|
||||
<int> 12 </int>
|
||||
<int> 13 </int>
|
||||
<int> 14 </int>
|
||||
<int> 5 </int>
|
||||
<int> 6 </int>
|
||||
<int> 7 </int>
|
||||
<int> 8 </int>
|
||||
<int> 9 </int>
|
||||
<int> 5 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
|
@ -202,18 +163,62 @@
|
|||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 26 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://11">
|
||||
<resource type="Animation" path="local://7">
|
||||
<string name="resource/name"> "crouch" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 22 </int>
|
||||
</array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://8">
|
||||
<string name="resource/name"> "falling" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 21 </int>
|
||||
</array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://9">
|
||||
<real name="length"> 1.25 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
|
@ -223,19 +228,19 @@
|
|||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="6" shared="false">
|
||||
<int> 5 </int>
|
||||
<int> 6 </int>
|
||||
<int> 7 </int>
|
||||
<int> 8 </int>
|
||||
<int> 9 </int>
|
||||
<int> 10 </int>
|
||||
<int> 11 </int>
|
||||
<int> 12 </int>
|
||||
<int> 13 </int>
|
||||
<int> 14 </int>
|
||||
<int> 5 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
|
@ -249,14 +254,14 @@
|
|||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 26 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
|
@ -289,30 +294,28 @@
|
|||
</resource>
|
||||
<main_resource>
|
||||
<dictionary name="_bundled" shared="false">
|
||||
<string> "conn_count" </string>
|
||||
<int> 0 </int>
|
||||
<string> "conns" </string>
|
||||
<int_array len="0"> </int_array>
|
||||
<string> "names" </string>
|
||||
<string_array len="180">
|
||||
<string_array len="142">
|
||||
<string> "player" </string>
|
||||
<string> "RigidBody2D" </string>
|
||||
<string> "_import_path" </string>
|
||||
<string> "visibility/visible" </string>
|
||||
<string> "visibility/opacity" </string>
|
||||
<string> "visibility/self_opacity" </string>
|
||||
<string> "visibility/behind_parent" </string>
|
||||
<string> "transform/pos" </string>
|
||||
<string> "transform/rot" </string>
|
||||
<string> "transform/scale" </string>
|
||||
<string> "shape_count" </string>
|
||||
<string> "input/pickable" </string>
|
||||
<string> "shapes/0/shape" </string>
|
||||
<string> "shapes/0/transform" </string>
|
||||
<string> "shapes/0/trigger" </string>
|
||||
<string> "shapes/1/shape" </string>
|
||||
<string> "shapes/1/transform" </string>
|
||||
<string> "shapes/1/trigger" </string>
|
||||
<string> "layers" </string>
|
||||
<string> "collision/layers" </string>
|
||||
<string> "collision/mask" </string>
|
||||
<string> "mode" </string>
|
||||
<string> "mass" </string>
|
||||
<string> "friction" </string>
|
||||
<string> "bounce" </string>
|
||||
<string> "gravity_scale" </string>
|
||||
<string> "custom_integrator" </string>
|
||||
<string> "continuous_cd" </string>
|
||||
<string> "contacts_reported" </string>
|
||||
|
@ -321,39 +324,28 @@
|
|||
<string> "can_sleep" </string>
|
||||
<string> "velocity/linear" </string>
|
||||
<string> "velocity/angular" </string>
|
||||
<string> "damp_override/linear" </string>
|
||||
<string> "damp_override/angular" </string>
|
||||
<string> "script/script" </string>
|
||||
<string> "__meta__" </string>
|
||||
<string> "sprite" </string>
|
||||
<string> "Sprite" </string>
|
||||
<string> "texture" </string>
|
||||
<string> "centered" </string>
|
||||
<string> "offset" </string>
|
||||
<string> "flip_h" </string>
|
||||
<string> "flip_v" </string>
|
||||
<string> "vframes" </string>
|
||||
<string> "hframes" </string>
|
||||
<string> "frame" </string>
|
||||
<string> "modulate" </string>
|
||||
<string> "region" </string>
|
||||
<string> "region_rect" </string>
|
||||
<string> "smoke" </string>
|
||||
<string> "Particles2D" </string>
|
||||
<string> "visibility/self_opacity" </string>
|
||||
<string> "visibility/blend_mode" </string>
|
||||
<string> "transform/pos" </string>
|
||||
<string> "transform/rot" </string>
|
||||
<string> "config/amount" </string>
|
||||
<string> "config/lifetime" </string>
|
||||
<string> "config/time_scale" </string>
|
||||
<string> "config/preprocess" </string>
|
||||
<string> "config/emit_timeout" </string>
|
||||
<string> "config/emitting" </string>
|
||||
<string> "config/offset" </string>
|
||||
<string> "config/half_extents" </string>
|
||||
<string> "config/local_space" </string>
|
||||
<string> "config/explosiveness" </string>
|
||||
<string> "config/flip_h" </string>
|
||||
<string> "config/flip_v" </string>
|
||||
<string> "config/texture" </string>
|
||||
<string> "config/h_frames" </string>
|
||||
<string> "config/v_frames" </string>
|
||||
<string> "params/direction" </string>
|
||||
<string> "params/spread" </string>
|
||||
<string> "params/linear_velocity" </string>
|
||||
|
@ -370,32 +362,8 @@
|
|||
<string> "params/hue_variation" </string>
|
||||
<string> "params/anim_speed_scale" </string>
|
||||
<string> "params/anim_initial_pos" </string>
|
||||
<string> "randomness/direction" </string>
|
||||
<string> "randomness/spread" </string>
|
||||
<string> "randomness/linear_velocity" </string>
|
||||
<string> "randomness/spin_velocity" </string>
|
||||
<string> "randomness/orbit_velocity" </string>
|
||||
<string> "randomness/gravity_direction" </string>
|
||||
<string> "randomness/gravity_strength" </string>
|
||||
<string> "randomness/radial_accel" </string>
|
||||
<string> "randomness/tangential_accel" </string>
|
||||
<string> "randomness/damping" </string>
|
||||
<string> "randomness/initial_angle" </string>
|
||||
<string> "randomness/initial_size" </string>
|
||||
<string> "randomness/final_size" </string>
|
||||
<string> "randomness/hue_variation" </string>
|
||||
<string> "randomness/anim_speed_scale" </string>
|
||||
<string> "randomness/anim_initial_pos" </string>
|
||||
<string> "color_phases/count" </string>
|
||||
<string> "phase_0/pos" </string>
|
||||
<string> "phase_0/color" </string>
|
||||
<string> "phase_1/pos" </string>
|
||||
<string> "phase_1/color" </string>
|
||||
<string> "phase_2/pos" </string>
|
||||
<string> "phase_2/color" </string>
|
||||
<string> "phase_3/pos" </string>
|
||||
<string> "phase_3/color" </string>
|
||||
<string> "emission_points" </string>
|
||||
<string> "color/color_ramp" </string>
|
||||
<string> "anim" </string>
|
||||
<string> "AnimationPlayer" </string>
|
||||
<string> "playback/process_mode" </string>
|
||||
|
@ -405,11 +373,11 @@
|
|||
<string> "anims/jumping" </string>
|
||||
<string> "anims/idle_weapon" </string>
|
||||
<string> "anims/run" </string>
|
||||
<string> "anims/run_weapon" </string>
|
||||
<string> "anims/falling_weapon" </string>
|
||||
<string> "anims/crouch" </string>
|
||||
<string> "anims/falling" </string>
|
||||
<string> "anims/standing_weapon_ready" </string>
|
||||
<string> "anims/falling_weapon" </string>
|
||||
<string> "anims/run_weapon" </string>
|
||||
<string> "anims/jumping_weapon" </string>
|
||||
<string> "playback/active" </string>
|
||||
<string> "playback/speed" </string>
|
||||
|
@ -417,6 +385,7 @@
|
|||
<string> "autoplay" </string>
|
||||
<string> "camera" </string>
|
||||
<string> "Camera2D" </string>
|
||||
<string> "anchor_mode" </string>
|
||||
<string> "rotating" </string>
|
||||
<string> "current" </string>
|
||||
<string> "smoothing" </string>
|
||||
|
@ -434,6 +403,7 @@
|
|||
<string> "bullet_shoot" </string>
|
||||
<string> "Position2D" </string>
|
||||
<string> "CollisionShape2D" </string>
|
||||
<string> "transform/scale" </string>
|
||||
<string> "shape" </string>
|
||||
<string> "trigger" </string>
|
||||
<string> "sound" </string>
|
||||
|
@ -458,6 +428,7 @@
|
|||
<string> "ui" </string>
|
||||
<string> "CanvasLayer" </string>
|
||||
<string> "layer" </string>
|
||||
<string> "offset" </string>
|
||||
<string> "rotation" </string>
|
||||
<string> "scale" </string>
|
||||
<string> "left" </string>
|
||||
|
@ -472,147 +443,149 @@
|
|||
<string> "jump" </string>
|
||||
<string> "fire" </string>
|
||||
</string_array>
|
||||
<string> "version" </string>
|
||||
<int> 1 </int>
|
||||
<string> "conn_count" </string>
|
||||
<int> 0 </int>
|
||||
<string> "node_count" </string>
|
||||
<int> 14 </int>
|
||||
<string> "nodes" </string>
|
||||
<int_array len="394"> -1, -1, 1, 0, -1, 26, 2, 0, 3, 1, 4, 2, 5, 0, 6, 3, 7, 4, 8, 0, 9, 5, 10, 5, 11, 6, 12, 7, 13, 8, 14, 8, 15, 9, 16, 10, 17, 11, 18, 12, 19, 0, 20, 0, 21, 10, 22, 13, 23, 8, 24, 14, 25, 14, 26, 15, 27, 16, 0, 0, 0, 29, 28, -1, 3, 30, 17, 31, 6, 32, 18, 0, 1, 0, 34, 33, -1, 29, 35, 19, 36, 5, 37, 20, 38, 21, 39, 22, 40, 23, 41, 23, 42, 0, 43, 0, 44, 24, 45, 25, 46, 8, 47, 26, 48, 27, 49, 9, 50, 8, 51, 8, 52, 28, 53, 8, 54, 8, 55, 8, 56, 8, 57, 29, 58, 29, 59, 8, 60, 9, 61, 8, 62, 29, 63, 30, 0, 0, 0, 65, 64, -1, 17, 66, 5, 67, 8, 68, 31, 69, 32, 70, 33, 71, 34, 72, 35, 73, 36, 74, 37, 75, 38, 76, 39, 77, 40, 78, 41, 79, 10, 80, 29, 81, 42, 82, 43, 0, 0, 0, 84, 83, -1, 15, 85, 5, 86, 0, 87, 10, 88, 8, 89, 44, 90, 11, 91, 11, 92, 45, 93, 45, 94, 10, 95, 10, 96, 46, 97, 46, 98, 46, 99, 46, 0, 0, 0, 101, 100, -1, 1, 37, 47, 0, 0, 0, 102, 102, -1, 4, 37, 48, 103, 49, 104, 1, 105, 0, 0, 0, 0, 107, 106, -1, 14, 108, 12, 109, 50, 110, 8, 111, 9, 112, 8, 113, 8, 114, 8, 115, 51, 116, 51, 117, 51, 118, 51, 119, 6, 120, 8, 121, 8, 0, 0, 0, 122, 122, -1, 3, 123, 11, 124, 52, 105, 0, 0, 0, 0, 126, 125, -1, 4, 127, 11, 128, 13, 129, 8, 130, 44, 0, 9, 0, 132, 131, -1, 8, 37, 53, 103, 54, 133, 55, 134, 56, 135, 56, 136, 10, 137, 57, 138, 5, 0, 9, 0, 132, 139, -1, 8, 37, 58, 103, 54, 133, 59, 134, 56, 135, 56, 136, 10, 137, 60, 138, 5, 0, 9, 0, 132, 140, -1, 8, 37, 61, 103, 54, 133, 62, 134, 56, 135, 56, 136, 0, 137, 63, 138, 5, 0, 9, 0, 132, 141, -1, 8, 37, 64, 103, 54, 133, 65, 134, 56, 135, 56, 136, 0, 137, 66, 138, 5, 0 </int_array>
|
||||
<string> "variants" </string>
|
||||
<array len="72" shared="false">
|
||||
<node_path> "" </node_path>
|
||||
<bool> True </bool>
|
||||
<real> 1 </real>
|
||||
<array len="67" shared="false">
|
||||
<bool> False </bool>
|
||||
<vector2> 0, 0 </vector2>
|
||||
<real> 0 </real>
|
||||
<vector2> 1, 1 </vector2>
|
||||
<int> 2 </int>
|
||||
<resource resource_type="Shape2D" path="local://1"> </resource>
|
||||
<matrix32> 1, -0, 0, 1.76469, 0.291992, -12.1587 </matrix32>
|
||||
<resource resource_type="Shape2D" path="local://2"> </resource>
|
||||
<matrix32> 1, -0, 0, 1, 0, 0 </matrix32>
|
||||
<int> 1 </int>
|
||||
<int> 2 </int>
|
||||
<real> 3 </real>
|
||||
<real> 0 </real>
|
||||
<real> 1 </real>
|
||||
<bool> True </bool>
|
||||
<int> 0 </int>
|
||||
<int> 3 </int>
|
||||
<vector2> 0, 0 </vector2>
|
||||
<real> -1 </real>
|
||||
<resource resource_type="Script" path="res://player.gd"> </resource>
|
||||
<dictionary shared="false">
|
||||
<string> "__editor_plugin_screen__" </string>
|
||||
<string> "2D" </string>
|
||||
<string> "__editor_plugin_states__" </string>
|
||||
<dictionary shared="false">
|
||||
<string> "Script" </string>
|
||||
<dictionary shared="false">
|
||||
<string> "current" </string>
|
||||
<int> 0 </int>
|
||||
<string> "sources" </string>
|
||||
<array len="1" shared="false">
|
||||
<string> "res://player.gd" </string>
|
||||
</array>
|
||||
</dictionary>
|
||||
<string> "2D" </string>
|
||||
<dictionary shared="false">
|
||||
<string> "pixel_snap" </string>
|
||||
<bool> False </bool>
|
||||
<string> "zoom" </string>
|
||||
<real> 2.272073 </real>
|
||||
<string> "use_snap" </string>
|
||||
<bool> False </bool>
|
||||
<string> "ofs" </string>
|
||||
<vector2> -181.946, -86.2812 </vector2>
|
||||
<string> "snap" </string>
|
||||
<int> 10 </int>
|
||||
<vector2> -110.795, -101.2 </vector2>
|
||||
<string> "snap_grid" </string>
|
||||
<bool> False </bool>
|
||||
<string> "snap_offset" </string>
|
||||
<vector2> 0, 0 </vector2>
|
||||
<string> "snap_pixel" </string>
|
||||
<bool> False </bool>
|
||||
<string> "snap_relative" </string>
|
||||
<bool> False </bool>
|
||||
<string> "snap_rotation" </string>
|
||||
<bool> False </bool>
|
||||
<string> "snap_rotation_offset" </string>
|
||||
<real> 0 </real>
|
||||
<string> "snap_rotation_step" </string>
|
||||
<real> 0.261799 </real>
|
||||
<string> "snap_show_grid" </string>
|
||||
<bool> False </bool>
|
||||
<string> "snap_step" </string>
|
||||
<vector2> 10, 10 </vector2>
|
||||
<string> "zoom" </string>
|
||||
<real> 2.050546 </real>
|
||||
</dictionary>
|
||||
<string> "3D" </string>
|
||||
<dictionary shared="false">
|
||||
<string> "ambient_light_color" </string>
|
||||
<color> 0.15, 0.15, 0.15, 1 </color>
|
||||
<string> "default_light" </string>
|
||||
<bool> True </bool>
|
||||
<string> "default_srgb" </string>
|
||||
<bool> False </bool>
|
||||
<string> "deflight_rot_x" </string>
|
||||
<real> 0.942478 </real>
|
||||
<string> "deflight_rot_y" </string>
|
||||
<real> 0.628319 </real>
|
||||
<string> "zfar" </string>
|
||||
<real> 500 </real>
|
||||
<string> "fov" </string>
|
||||
<real> 45 </real>
|
||||
<string> "show_grid" </string>
|
||||
<bool> True </bool>
|
||||
<string> "show_origin" </string>
|
||||
<bool> True </bool>
|
||||
<string> "viewport_mode" </string>
|
||||
<int> 1 </int>
|
||||
<string> "viewports" </string>
|
||||
<array len="4" shared="false">
|
||||
<dictionary shared="false">
|
||||
<string> "distance" </string>
|
||||
<real> 4 </real>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "listener" </string>
|
||||
<bool> True </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
<string> "use_environment" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_orthogonal" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
</dictionary>
|
||||
<dictionary shared="false">
|
||||
<string> "distance" </string>
|
||||
<real> 4 </real>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "listener" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_environment" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_orthogonal" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
</dictionary>
|
||||
<dictionary shared="false">
|
||||
<string> "distance" </string>
|
||||
<real> 4 </real>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "listener" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
<string> "use_environment" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_orthogonal" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
</dictionary>
|
||||
<dictionary shared="false">
|
||||
<string> "distance" </string>
|
||||
<real> 4 </real>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "listener" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
<string> "use_environment" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_orthogonal" </string>
|
||||
<bool> False </bool>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
</dictionary>
|
||||
<dictionary shared="false">
|
||||
<string> "distance" </string>
|
||||
<real> 4 </real>
|
||||
<string> "listener" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
<string> "use_environment" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_orthogonal" </string>
|
||||
<bool> False </bool>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
</dictionary>
|
||||
</array>
|
||||
<string> "viewport_mode" </string>
|
||||
<int> 1 </int>
|
||||
<string> "default_light" </string>
|
||||
<bool> True </bool>
|
||||
<string> "ambient_light_color" </string>
|
||||
<color> 0.15, 0.15, 0.15, 1 </color>
|
||||
<string> "show_grid" </string>
|
||||
<bool> True </bool>
|
||||
<string> "show_origin" </string>
|
||||
<bool> True </bool>
|
||||
<string> "zfar" </string>
|
||||
<real> 500 </real>
|
||||
<string> "znear" </string>
|
||||
<real> 0.1 </real>
|
||||
<string> "default_srgb" </string>
|
||||
<bool> False </bool>
|
||||
<string> "deflight_rot_x" </string>
|
||||
<real> 0.942478 </real>
|
||||
</dictionary>
|
||||
</dictionary>
|
||||
<string> "__editor_run_settings__" </string>
|
||||
|
@ -622,13 +595,9 @@
|
|||
<string> "run_mode" </string>
|
||||
<int> 0 </int>
|
||||
</dictionary>
|
||||
<string> "__editor_plugin_screen__" </string>
|
||||
<string> "Script" </string>
|
||||
</dictionary>
|
||||
<resource resource_type="Texture" path="res://robot_demo.png"> </resource>
|
||||
<int> 16 </int>
|
||||
<color> 1, 1, 1, 1 </color>
|
||||
<rect2> 0, 0, 0, 0 </rect2>
|
||||
<real> 0.363636 </real>
|
||||
<vector2> 20.7312, 3.21187 </vector2>
|
||||
<real> 83.450417 </real>
|
||||
|
@ -640,24 +609,22 @@
|
|||
<real> 20 </real>
|
||||
<real> 9.8 </real>
|
||||
<real> 2 </real>
|
||||
<color> 0, 0, 0, 0.0442478 </color>
|
||||
<color> 1, 0, 0, 1 </color>
|
||||
<color> 0, 0, 0, 1 </color>
|
||||
<vector2_array len="0"> </vector2_array>
|
||||
<resource resource_type="ColorRamp" path="local://14"> </resource>
|
||||
<node_path> ".." </node_path>
|
||||
<resource resource_type="Animation" path="local://3"> </resource>
|
||||
<resource resource_type="Animation" path="local://4"> </resource>
|
||||
<resource resource_type="Animation" path="local://5"> </resource>
|
||||
<resource resource_type="Animation" path="local://6"> </resource>
|
||||
<resource resource_type="Animation" path="local://11"> </resource>
|
||||
<resource resource_type="Animation" path="local://10"> </resource>
|
||||
<resource resource_type="Animation" path="local://7"> </resource>
|
||||
<resource resource_type="Animation" path="local://8"> </resource>
|
||||
<resource resource_type="Animation" path="local://9"> </resource>
|
||||
<resource resource_type="Animation" path="local://10"> </resource>
|
||||
<resource resource_type="Animation" path="local://11"> </resource>
|
||||
<resource resource_type="Animation" path="local://12"> </resource>
|
||||
<array len="0" shared="false">
|
||||
</array>
|
||||
<string> "" </string>
|
||||
<vector2> 1, 1 </vector2>
|
||||
<int> 10000000 </int>
|
||||
<real> 0.2 </real>
|
||||
<vector2> 31.2428, 4.08784 </vector2>
|
||||
|
@ -680,10 +647,8 @@
|
|||
<resource resource_type="Texture" path="res://osb_fire.png"> </resource>
|
||||
<string> "shoot" </string>
|
||||
</array>
|
||||
<string> "nodes" </string>
|
||||
<int_array len="618"> -1, -1, 1, 0, -1, 30, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 7, 11, 8, 12, 9, 13, 3, 14, 10, 15, 11, 16, 3, 17, 12, 18, 7, 19, 13, 20, 5, 21, 5, 22, 1, 23, 14, 24, 15, 25, 3, 26, 3, 27, 1, 28, 4, 29, 5, 30, 16, 31, 17, 0, 0, 0, 33, 32, -1, 19, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 34, 18, 35, 1, 36, 4, 37, 3, 38, 3, 39, 7, 40, 19, 41, 14, 42, 20, 43, 3, 44, 21, 0, 1, 0, 46, 45, -1, 66, 2, 0, 3, 1, 4, 2, 5, 22, 6, 3, 47, 12, 7, 23, 8, 24, 9, 6, 48, 25, 49, 26, 50, 2, 51, 5, 52, 26, 53, 3, 54, 4, 55, 4, 56, 3, 57, 27, 58, 3, 59, 3, 60, 28, 61, 12, 62, 12, 63, 5, 64, 29, 65, 30, 66, 2, 67, 5, 68, 5, 69, 31, 70, 5, 71, 5, 72, 5, 73, 5, 74, 32, 75, 32, 76, 5, 77, 2, 78, 5, 79, 5, 80, 5, 81, 5, 82, 32, 83, 5, 84, 5, 85, 5, 86, 5, 87, 5, 88, 5, 89, 5, 90, 5, 91, 5, 92, 5, 93, 5, 94, 5, 95, 7, 96, 5, 97, 20, 98, 2, 99, 33, 100, 2, 101, 34, 102, 2, 103, 35, 104, 36, 0, 0, 0, 106, 105, -1, 18, 2, 0, 107, 12, 108, 5, 109, 37, 110, 38, 111, 39, 112, 40, 113, 41, 114, 42, 115, 43, 116, 44, 117, 45, 118, 46, 119, 47, 120, 1, 121, 32, 122, 48, 123, 49, 0, 0, 0, 125, 124, -1, 23, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 35, 1, 126, 3, 127, 1, 128, 5, 129, 6, 130, 14, 131, 14, 132, 50, 133, 50, 134, 1, 135, 1, 136, 51, 137, 51, 138, 51, 139, 51, 0, 0, 0, 141, 140, -1, 8, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 52, 8, 5, 9, 6, 0, 0, 0, 142, 142, -1, 10, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 53, 8, 5, 9, 54, 143, 8, 144, 3, 0, 0, 0, 146, 145, -1, 15, 2, 0, 147, 15, 148, 55, 149, 5, 150, 2, 151, 5, 152, 5, 153, 5, 154, 56, 155, 56, 156, 56, 157, 56, 158, 7, 159, 5, 160, 5, 0, 0, 0, 161, 161, -1, 10, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 162, 14, 163, 57, 0, 0, 0, 165, 164, -1, 5, 2, 0, 166, 14, 36, 4, 167, 5, 168, 6, 0, 9, 0, 170, 169, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 58, 8, 5, 9, 59, 171, 60, 172, 61, 173, 61, 174, 1, 175, 62, 176, 12, 0, 9, 0, 170, 177, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 63, 8, 5, 9, 59, 171, 64, 172, 61, 173, 61, 174, 1, 175, 65, 176, 12, 0, 9, 0, 170, 178, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 66, 8, 5, 9, 59, 171, 67, 172, 61, 173, 61, 174, 3, 175, 68, 176, 12, 0, 9, 0, 170, 179, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 69, 8, 5, 9, 59, 171, 70, 172, 61, 173, 61, 174, 3, 175, 71, 176, 12, 0 </int_array>
|
||||
<string> "conns" </string>
|
||||
<int_array len="0"> </int_array>
|
||||
<string> "version" </string>
|
||||
<int> 1 </int>
|
||||
</dictionary>
|
||||
|
||||
</main_resource>
|
||||
|
|
|
@ -579,6 +579,10 @@ void TileMap::_make_quadrant_dirty(Map<PosKey,Quadrant>::Element *Q) {
|
|||
call_deferred("_update_dirty_quadrants");
|
||||
}
|
||||
|
||||
void TileMap::set_cellv(const Vector2& p_pos,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) {
|
||||
|
||||
set_cell(p_pos.x,p_pos.y,p_tile,p_flip_x,p_flip_y,p_transpose);
|
||||
}
|
||||
|
||||
void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) {
|
||||
|
||||
|
@ -1106,6 +1110,7 @@ void TileMap::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("get_collision_bounce"),&TileMap::get_collision_bounce);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y","transpose"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("set_cellv","pos","tile","flip_x","flip_y","transpose"),&TileMap::set_cellv,DEFVAL(false),DEFVAL(false),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell);
|
||||
ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped);
|
||||
ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped);
|
||||
|
|
|
@ -207,6 +207,8 @@ public:
|
|||
bool is_cell_y_flipped(int p_x,int p_y) const;
|
||||
bool is_cell_transposed(int p_x,int p_y) const;
|
||||
|
||||
void set_cellv(const Vector2& p_pos,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false);
|
||||
|
||||
Rect2 get_item_rect() const;
|
||||
|
||||
void set_collision_layer(uint32_t p_layer);
|
||||
|
|
|
@ -196,6 +196,14 @@ void Node::_propagate_enter_tree() {
|
|||
}
|
||||
|
||||
data.blocked--;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
if (ScriptDebugger::get_singleton() && data.filename!=String()) {
|
||||
//used for live edit
|
||||
data.tree->live_scene_edit_cache[data.filename].insert(this);
|
||||
}
|
||||
#endif
|
||||
// enter groups
|
||||
}
|
||||
|
||||
|
@ -205,6 +213,19 @@ void Node::_propagate_exit_tree() {
|
|||
|
||||
//block while removing children
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
if (ScriptDebugger::get_singleton() && data.filename!=String()) {
|
||||
//used for live edit
|
||||
Map<String,Set<Node*> >::Element *E=data.tree->live_scene_edit_cache.find(data.filename);
|
||||
if (E) {
|
||||
E->get().erase(this);
|
||||
if (E->get().size()==0) {
|
||||
data.tree->live_scene_edit_cache.erase(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
data.blocked++;
|
||||
|
||||
for (int i=data.children.size()-1;i>=0;i--) {
|
||||
|
@ -552,6 +573,52 @@ void Node::set_human_readable_collision_renaming(bool p_enabled) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
String Node::validate_child_name(const String& p_name) const {
|
||||
|
||||
//this approach to autoset node names is human readable but very slow
|
||||
//it's turned on while running in the editor
|
||||
|
||||
String basename = p_name;
|
||||
|
||||
if (basename==String()) {
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
int val=1;
|
||||
|
||||
for(;;) {
|
||||
|
||||
String attempted = val > 1 ? (basename + " " +itos(val) ) : basename;
|
||||
|
||||
bool found=false;
|
||||
|
||||
for (int i=0;i<data.children.size();i++) {
|
||||
|
||||
//if (data.children[i]==p_child)
|
||||
// continue;
|
||||
if (data.children[i]->get_name() == attempted) {
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (found) {
|
||||
|
||||
val++;
|
||||
continue;
|
||||
}
|
||||
|
||||
return attempted;
|
||||
break;
|
||||
}
|
||||
|
||||
return basename;
|
||||
|
||||
}
|
||||
|
||||
void Node::_validate_child_name(Node *p_child) {
|
||||
|
||||
/* Make sure the name is unique */
|
||||
|
@ -1323,18 +1390,31 @@ int Node::get_position_in_parent() const {
|
|||
|
||||
|
||||
|
||||
Node *Node::duplicate() const {
|
||||
Node *Node::duplicate(bool p_use_instancing) const {
|
||||
|
||||
|
||||
Node *node=NULL;
|
||||
|
||||
bool instanced=false;
|
||||
|
||||
if (p_use_instancing && get_filename()!=String()) {
|
||||
|
||||
Ref<PackedScene> res = ResourceLoader::load(get_filename());
|
||||
ERR_FAIL_COND_V(res.is_null(),NULL);
|
||||
node=res->instance();
|
||||
ERR_FAIL_COND_V(!node,NULL);
|
||||
|
||||
instanced=true;
|
||||
|
||||
} else {
|
||||
|
||||
Object *obj = ObjectTypeDB::instance(get_type());
|
||||
ERR_FAIL_COND_V(!obj,NULL);
|
||||
node = obj->cast_to<Node>();
|
||||
if (!node)
|
||||
memdelete(obj);
|
||||
ERR_FAIL_COND_V(!node,NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (get_filename()!="") { //an instance
|
||||
|
@ -1360,7 +1440,10 @@ Node *Node::duplicate() const {
|
|||
|
||||
if (get_child(i)->data.parent_owned)
|
||||
continue;
|
||||
Node *dup = get_child(i)->duplicate();
|
||||
if (instanced && get_child(i)->data.owner==this)
|
||||
continue; //part of instance
|
||||
|
||||
Node *dup = get_child(i)->duplicate(p_use_instancing);
|
||||
if (!dup) {
|
||||
|
||||
memdelete(node);
|
||||
|
@ -1882,7 +1965,7 @@ void Node::_bind_methods() {
|
|||
|
||||
ObjectTypeDB::bind_method(_MD("get_tree:SceneTree"),&Node::get_tree);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("duplicate:Node"),&Node::duplicate);
|
||||
ObjectTypeDB::bind_method(_MD("duplicate:Node","use_instancing"),&Node::duplicate,DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("replace_by","node:Node","keep_data"),&Node::replace_by,DEFVAL(false));
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_viewport"),&Node::get_viewport);
|
||||
|
|
|
@ -255,8 +255,9 @@ public:
|
|||
|
||||
int get_position_in_parent() const;
|
||||
|
||||
Node *duplicate() const;
|
||||
Node *duplicate(bool p_use_instancing=false) const;
|
||||
Node *duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const;
|
||||
|
||||
//Node *clone_tree() const;
|
||||
|
||||
// used by editors, to save what has changed only
|
||||
|
@ -275,6 +276,8 @@ public:
|
|||
|
||||
static void print_stray_nodes();
|
||||
|
||||
String validate_child_name(const String& p_name) const;
|
||||
|
||||
void queue_delete();
|
||||
|
||||
//shitty hacks for speed
|
||||
|
|
|
@ -1044,7 +1044,300 @@ void SceneTree::add_current_scene(Node * p_current) {
|
|||
current_scene=p_current;
|
||||
root->add_child(p_current);
|
||||
}
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
void SceneTree::_live_edit_node_path_func(const NodePath &p_path,int p_id) {
|
||||
|
||||
live_edit_node_path_cache[p_id]=p_path;
|
||||
}
|
||||
|
||||
void SceneTree::_live_edit_res_path_func(const String &p_path,int p_id) {
|
||||
|
||||
live_edit_resource_cache[p_id]=p_path;
|
||||
}
|
||||
|
||||
void SceneTree::_live_edit_node_set_func(int p_id,const StringName& p_prop,const Variant& p_value) {
|
||||
|
||||
if (!live_edit_node_path_cache.has(p_id))
|
||||
return;
|
||||
|
||||
NodePath np = live_edit_node_path_cache[p_id];
|
||||
Node *base = NULL;
|
||||
if (root->has_node(live_edit_root))
|
||||
base = root->get_node(live_edit_root);
|
||||
|
||||
Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
|
||||
if (!E)
|
||||
return; //scene not editable
|
||||
|
||||
for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
|
||||
|
||||
Node *n=F->get();
|
||||
|
||||
if (base && !base->is_a_parent_of(n))
|
||||
continue;
|
||||
|
||||
if (!n->has_node(np))
|
||||
continue;
|
||||
Node *n2 = n->get_node(np);
|
||||
|
||||
n2->set(p_prop,p_value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SceneTree::_live_edit_node_set_res_func(int p_id,const StringName& p_prop,const String& p_value) {
|
||||
|
||||
RES r = ResourceLoader::load(p_value);
|
||||
if (!r.is_valid())
|
||||
return;
|
||||
_live_edit_node_set_func(p_id,p_prop,r);
|
||||
|
||||
}
|
||||
void SceneTree::_live_edit_node_call_func(int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) {
|
||||
|
||||
if (!live_edit_node_path_cache.has(p_id))
|
||||
return;
|
||||
|
||||
NodePath np = live_edit_node_path_cache[p_id];
|
||||
Node *base = NULL;
|
||||
if (root->has_node(live_edit_root))
|
||||
base = root->get_node(live_edit_root);
|
||||
|
||||
Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
|
||||
if (!E)
|
||||
return; //scene not editable
|
||||
|
||||
for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
|
||||
|
||||
Node *n=F->get();
|
||||
|
||||
if (base && !base->is_a_parent_of(n))
|
||||
continue;
|
||||
|
||||
if (!n->has_node(np))
|
||||
continue;
|
||||
Node *n2 = n->get_node(np);
|
||||
|
||||
n2->call(p_method,VARIANT_ARG_PASS);
|
||||
}
|
||||
}
|
||||
void SceneTree::_live_edit_res_set_func(int p_id,const StringName& p_prop,const Variant& p_value) {
|
||||
|
||||
if (!live_edit_resource_cache.has(p_id))
|
||||
return;
|
||||
|
||||
String resp = live_edit_resource_cache[p_id];
|
||||
|
||||
if (!ResourceCache::has(resp))
|
||||
return;
|
||||
|
||||
RES r = ResourceCache::get(resp);
|
||||
if (!r.is_valid())
|
||||
return;
|
||||
|
||||
r->set(p_prop,p_value);
|
||||
}
|
||||
void SceneTree::_live_edit_res_set_res_func(int p_id,const StringName& p_prop,const String& p_value) {
|
||||
|
||||
RES r = ResourceLoader::load(p_value);
|
||||
if (!r.is_valid())
|
||||
return;
|
||||
_live_edit_res_set_func(p_id,p_prop,r);
|
||||
|
||||
}
|
||||
void SceneTree::_live_edit_res_call_func(int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) {
|
||||
|
||||
if (!live_edit_resource_cache.has(p_id))
|
||||
return;
|
||||
|
||||
String resp = live_edit_resource_cache[p_id];
|
||||
|
||||
if (!ResourceCache::has(resp))
|
||||
return;
|
||||
|
||||
RES r = ResourceCache::get(resp);
|
||||
if (!r.is_valid())
|
||||
return;
|
||||
|
||||
r->call(p_method,VARIANT_ARG_PASS);
|
||||
}
|
||||
|
||||
void SceneTree::_live_edit_root_func(const NodePath& p_scene_path,const String& p_scene_from) {
|
||||
|
||||
live_edit_root=p_scene_path;
|
||||
live_edit_scene=p_scene_from;
|
||||
}
|
||||
|
||||
void SceneTree::_live_edit_create_node_func(const NodePath& p_parent,const String& p_type,const String& p_name) {
|
||||
|
||||
|
||||
Node *base = NULL;
|
||||
if (root->has_node(live_edit_root))
|
||||
base = root->get_node(live_edit_root);
|
||||
|
||||
Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
|
||||
if (!E)
|
||||
return; //scene not editable
|
||||
|
||||
for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
|
||||
|
||||
Node *n=F->get();
|
||||
|
||||
if (base && !base->is_a_parent_of(n))
|
||||
continue;
|
||||
|
||||
if (!n->has_node(p_parent))
|
||||
continue;
|
||||
Node *n2 = n->get_node(p_parent);
|
||||
|
||||
Object *o = ObjectTypeDB::instance(p_type);
|
||||
if (!o)
|
||||
continue;
|
||||
Node *no=o->cast_to<Node>();
|
||||
no->set_name(p_name);
|
||||
|
||||
n2->add_child(no);
|
||||
}
|
||||
}
|
||||
void SceneTree::_live_edit_instance_node_func(const NodePath& p_parent,const String& p_path,const String& p_name){
|
||||
|
||||
Ref<PackedScene> ps = ResourceLoader::load(p_path);
|
||||
print_line("instance node?");
|
||||
if (!ps.is_valid())
|
||||
return;
|
||||
|
||||
Node *base = NULL;
|
||||
if (root->has_node(live_edit_root))
|
||||
base = root->get_node(live_edit_root);
|
||||
|
||||
Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
|
||||
if (!E)
|
||||
return; //scene not editable
|
||||
|
||||
for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
|
||||
|
||||
Node *n=F->get();
|
||||
|
||||
if (base && !base->is_a_parent_of(n))
|
||||
continue;
|
||||
|
||||
if (!n->has_node(p_parent))
|
||||
continue;
|
||||
Node *n2 = n->get_node(p_parent);
|
||||
|
||||
|
||||
|
||||
Node *no=ps->instance();
|
||||
no->set_name(p_name);
|
||||
|
||||
n2->add_child(no);
|
||||
}
|
||||
}
|
||||
void SceneTree::_live_edit_remove_node_func(const NodePath& p_at){
|
||||
|
||||
Node *base = NULL;
|
||||
if (root->has_node(live_edit_root))
|
||||
base = root->get_node(live_edit_root);
|
||||
|
||||
Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
|
||||
if (!E)
|
||||
return; //scene not editable
|
||||
|
||||
for(Set<Node*>::Element *F=E->get().front();F;) {
|
||||
|
||||
Set<Node*>::Element *N=F->next();
|
||||
|
||||
Node *n=F->get();
|
||||
|
||||
if (base && !base->is_a_parent_of(n))
|
||||
continue;
|
||||
|
||||
if (!n->has_node(p_at))
|
||||
continue;
|
||||
Node *n2 = n->get_node(p_at);
|
||||
|
||||
memdelete(n2);
|
||||
|
||||
F=N;
|
||||
|
||||
}
|
||||
}
|
||||
void SceneTree::_live_edit_remove_and_keep_node_func(const NodePath& p_at,ObjectID p_keep_id){
|
||||
|
||||
|
||||
}
|
||||
void SceneTree::_live_edit_restore_node_func(ObjectID p_id,const NodePath& p_at,int p_at_pos){
|
||||
|
||||
|
||||
}
|
||||
void SceneTree::_live_edit_duplicate_node_func(const NodePath& p_at,const String& p_new_name){
|
||||
|
||||
Node *base = NULL;
|
||||
if (root->has_node(live_edit_root))
|
||||
base = root->get_node(live_edit_root);
|
||||
|
||||
Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
|
||||
if (!E)
|
||||
return; //scene not editable
|
||||
|
||||
for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
|
||||
|
||||
Node *n=F->get();
|
||||
|
||||
if (base && !base->is_a_parent_of(n))
|
||||
continue;
|
||||
|
||||
if (!n->has_node(p_at))
|
||||
continue;
|
||||
Node *n2 = n->get_node(p_at);
|
||||
|
||||
Node *dup = n2->duplicate(true);
|
||||
|
||||
if (!dup)
|
||||
continue;
|
||||
|
||||
dup->set_name(p_new_name);
|
||||
|
||||
n2->get_parent()->add_child(dup);
|
||||
|
||||
}
|
||||
}
|
||||
void SceneTree::_live_edit_reparent_node_func(const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name){
|
||||
|
||||
Node *base = NULL;
|
||||
if (root->has_node(live_edit_root))
|
||||
base = root->get_node(live_edit_root);
|
||||
|
||||
Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
|
||||
if (!E)
|
||||
return; //scene not editable
|
||||
|
||||
for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
|
||||
|
||||
Node *n=F->get();
|
||||
|
||||
if (base && !base->is_a_parent_of(n))
|
||||
continue;
|
||||
|
||||
if (!n->has_node(p_at))
|
||||
continue;
|
||||
Node *nfrom = n->get_node(p_at);
|
||||
|
||||
if (!n->has_node(p_new_place))
|
||||
continue;
|
||||
Node *nto = n->get_node(p_new_place);
|
||||
|
||||
nfrom->get_parent()->remove_child(nfrom);
|
||||
nfrom->set_name(p_new_name);
|
||||
|
||||
nto->add_child(nfrom);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
void SceneTree::_bind_methods() {
|
||||
|
||||
|
||||
|
@ -1169,6 +1462,35 @@ SceneTree::SceneTree() {
|
|||
edited_scene_root=NULL;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
|
||||
live_edit_funcs.udata=this;
|
||||
live_edit_funcs.node_path_func=_live_edit_node_path_funcs;
|
||||
live_edit_funcs.res_path_func=_live_edit_res_path_funcs;
|
||||
live_edit_funcs.node_set_func=_live_edit_node_set_funcs;
|
||||
live_edit_funcs.node_set_res_func=_live_edit_node_set_res_funcs;
|
||||
live_edit_funcs.node_call_func=_live_edit_node_call_funcs;
|
||||
live_edit_funcs.res_set_func=_live_edit_res_set_funcs;
|
||||
live_edit_funcs.res_set_res_func=_live_edit_res_set_res_funcs;
|
||||
live_edit_funcs.res_call_func=_live_edit_res_call_funcs;
|
||||
live_edit_funcs.root_func=_live_edit_root_funcs;
|
||||
|
||||
live_edit_funcs.tree_create_node_func=_live_edit_create_node_funcs;
|
||||
live_edit_funcs.tree_instance_node_func=_live_edit_instance_node_funcs;
|
||||
live_edit_funcs.tree_remove_node_func=_live_edit_remove_node_funcs;
|
||||
live_edit_funcs.tree_remove_and_keep_node_func=_live_edit_remove_and_keep_node_funcs;
|
||||
live_edit_funcs.tree_restore_node_func=_live_edit_restore_node_funcs;
|
||||
live_edit_funcs.tree_duplicate_node_func=_live_edit_duplicate_node_funcs;
|
||||
live_edit_funcs.tree_reparent_node_func=_live_edit_reparent_node_funcs;
|
||||
|
||||
if (ScriptDebugger::get_singleton()) {
|
||||
ScriptDebugger::get_singleton()->set_live_edit_funcs(&live_edit_funcs);
|
||||
}
|
||||
|
||||
live_edit_root=NodePath("/root");
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -164,6 +164,57 @@ friend class Viewport;
|
|||
|
||||
SelfList<Node>::List xform_change_list;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
Map<int,NodePath> live_edit_node_path_cache;
|
||||
Map<int,String> live_edit_resource_cache;
|
||||
|
||||
NodePath live_edit_root;
|
||||
String live_edit_scene;
|
||||
|
||||
Map<String,Set<Node*> > live_scene_edit_cache;
|
||||
|
||||
ScriptDebugger::LiveEditFuncs live_edit_funcs;
|
||||
|
||||
void _live_edit_node_path_func(const NodePath &p_path,int p_id) ;
|
||||
void _live_edit_res_path_func(const String &p_path,int p_id) ;
|
||||
|
||||
void _live_edit_node_set_func(int p_id,const StringName& p_prop,const Variant& p_value) ;
|
||||
void _live_edit_node_set_res_func(int p_id,const StringName& p_prop,const String& p_value) ;
|
||||
void _live_edit_node_call_func(int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) ;
|
||||
void _live_edit_res_set_func(int p_id,const StringName& p_prop,const Variant& p_value) ;
|
||||
void _live_edit_res_set_res_func(int p_id,const StringName& p_prop,const String& p_value) ;
|
||||
void _live_edit_res_call_func(int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) ;
|
||||
void _live_edit_root_func(const NodePath& p_scene_path,const String& p_scene_from) ;
|
||||
|
||||
void _live_edit_create_node_func(const NodePath& p_parent,const String& p_type,const String& p_name);
|
||||
void _live_edit_instance_node_func(const NodePath& p_parent,const String& p_path,const String& p_name);
|
||||
void _live_edit_remove_node_func(const NodePath& p_at);
|
||||
void _live_edit_remove_and_keep_node_func(const NodePath& p_at,ObjectID p_keep_id);
|
||||
void _live_edit_restore_node_func(ObjectID p_id,const NodePath& p_at,int p_at_pos);
|
||||
void _live_edit_duplicate_node_func(const NodePath& p_at,const String& p_new_name);
|
||||
void _live_edit_reparent_node_func(const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name);
|
||||
|
||||
static void _live_edit_node_path_funcs(void *self,const NodePath &p_path,int p_id) { reinterpret_cast<SceneTree*>(self)->_live_edit_node_path_func(p_path,p_id); }
|
||||
static void _live_edit_res_path_funcs(void *self,const String &p_path,int p_id) { reinterpret_cast<SceneTree*>(self)->_live_edit_res_path_func(p_path,p_id); }
|
||||
|
||||
static void _live_edit_node_set_funcs(void *self,int p_id,const StringName& p_prop,const Variant& p_value) { reinterpret_cast<SceneTree*>(self)->_live_edit_node_set_func(p_id,p_prop,p_value); }
|
||||
static void _live_edit_node_set_res_funcs(void *self,int p_id,const StringName& p_prop,const String& p_value) { reinterpret_cast<SceneTree*>(self)->_live_edit_node_set_res_func(p_id,p_prop,p_value); }
|
||||
static void _live_edit_node_call_funcs(void *self,int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) { reinterpret_cast<SceneTree*>(self)->_live_edit_node_call_func(p_id,p_method,VARIANT_ARG_PASS); }
|
||||
static void _live_edit_res_set_funcs(void *self,int p_id,const StringName& p_prop,const Variant& p_value) { reinterpret_cast<SceneTree*>(self)->_live_edit_res_set_func(p_id,p_prop,p_value); }
|
||||
static void _live_edit_res_set_res_funcs(void *self,int p_id,const StringName& p_prop,const String& p_value) { reinterpret_cast<SceneTree*>(self)->_live_edit_res_set_res_func(p_id,p_prop,p_value); }
|
||||
static void _live_edit_res_call_funcs(void *self,int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) { reinterpret_cast<SceneTree*>(self)->_live_edit_res_call_func(p_id,p_method,VARIANT_ARG_PASS); }
|
||||
static void _live_edit_root_funcs(void *self, const NodePath& p_scene_path,const String& p_scene_from) { reinterpret_cast<SceneTree*>(self)->_live_edit_root_func(p_scene_path,p_scene_from); }
|
||||
|
||||
static void _live_edit_create_node_funcs(void* self,const NodePath& p_parent,const String& p_type,const String& p_name) { reinterpret_cast<SceneTree*>(self)->_live_edit_create_node_func(p_parent,p_type,p_name); }
|
||||
static void _live_edit_instance_node_funcs(void* self,const NodePath& p_parent,const String& p_path,const String& p_name) { reinterpret_cast<SceneTree*>(self)->_live_edit_instance_node_func(p_parent,p_path,p_name); }
|
||||
static void _live_edit_remove_node_funcs(void* self,const NodePath& p_at) { reinterpret_cast<SceneTree*>(self)->_live_edit_remove_node_func(p_at); }
|
||||
static void _live_edit_remove_and_keep_node_funcs(void* self,const NodePath& p_at,ObjectID p_keep_id) { reinterpret_cast<SceneTree*>(self)->_live_edit_remove_and_keep_node_func(p_at,p_keep_id); }
|
||||
static void _live_edit_restore_node_funcs(void* self,ObjectID p_id,const NodePath& p_at,int p_at_pos) { reinterpret_cast<SceneTree*>(self)->_live_edit_restore_node_func(p_id,p_at,p_at_pos); }
|
||||
static void _live_edit_duplicate_node_funcs(void* self,const NodePath& p_at,const String& p_new_name) { reinterpret_cast<SceneTree*>(self)->_live_edit_duplicate_node_func(p_at,p_new_name); }
|
||||
static void _live_edit_reparent_node_funcs(void* self,const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name) { reinterpret_cast<SceneTree*>(self)->_live_edit_reparent_node_func(p_at,p_new_place,p_new_name); }
|
||||
|
||||
#endif
|
||||
protected:
|
||||
|
||||
void _notification(int p_notification);
|
||||
|
|
|
@ -432,6 +432,7 @@ int EditorData::add_edited_scene(int p_at_pos) {
|
|||
es.root=NULL;
|
||||
es.history_current=-1;
|
||||
es.version=0;
|
||||
es.live_edit_root=NodePath(String("/root"));
|
||||
|
||||
if (p_at_pos==edited_scene.size())
|
||||
edited_scene.push_back(es);
|
||||
|
@ -552,6 +553,23 @@ String EditorData::get_scene_path(int p_idx) const {
|
|||
|
||||
}
|
||||
|
||||
void EditorData::set_edited_scene_live_edit_root(const NodePath& p_root) {
|
||||
ERR_FAIL_INDEX(current_edited_scene,edited_scene.size());
|
||||
|
||||
edited_scene[current_edited_scene].live_edit_root=p_root;
|
||||
|
||||
}
|
||||
NodePath EditorData::get_edited_scene_live_edit_root() {
|
||||
|
||||
ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),String());
|
||||
|
||||
return edited_scene[current_edited_scene].live_edit_root;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history, const Dictionary& p_custom) {
|
||||
|
||||
ERR_FAIL_INDEX(current_edited_scene,edited_scene.size());
|
||||
|
|
|
@ -129,6 +129,7 @@ private:
|
|||
int history_current;
|
||||
Dictionary custom_state;
|
||||
uint64_t version;
|
||||
NodePath live_edit_root;
|
||||
|
||||
|
||||
};
|
||||
|
@ -183,6 +184,8 @@ public:
|
|||
uint64_t get_edited_scene_version() const;
|
||||
uint64_t get_scene_version(int p_idx) const;
|
||||
void clear_edited_scenes();
|
||||
void set_edited_scene_live_edit_root(const NodePath& p_root);
|
||||
NodePath get_edited_scene_live_edit_root();
|
||||
|
||||
|
||||
void set_plugin_window_layout(Ref<ConfigFile> p_layout);
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
#include "plugins/light_occluder_2d_editor_plugin.h"
|
||||
#include "plugins/color_ramp_editor_plugin.h"
|
||||
#include "plugins/collision_shape_2d_editor_plugin.h"
|
||||
|
||||
// end
|
||||
#include "tools/editor/io_plugins/editor_texture_import_plugin.h"
|
||||
#include "tools/editor/io_plugins/editor_scene_import_plugin.h"
|
||||
|
@ -103,6 +104,7 @@
|
|||
|
||||
#include "plugins/editor_preview_plugins.h"
|
||||
|
||||
#include "script_editor_debugger.h"
|
||||
|
||||
EditorNode *EditorNode::singleton=NULL;
|
||||
|
||||
|
@ -2410,6 +2412,11 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
|||
fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER),!ischecked);
|
||||
|
||||
} break;
|
||||
case RUN_LIVE_DEBUG: {
|
||||
|
||||
ScriptEditor::get_singleton()->get_debugger()->set_live_debugging(live_debug_button->is_pressed());
|
||||
} break;
|
||||
|
||||
case RUN_DEPLOY_DUMB_CLIENTS: {
|
||||
|
||||
bool ischecked = fileserver_menu->get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS));
|
||||
|
@ -3018,6 +3025,7 @@ void EditorNode::set_current_scene(int p_idx) {
|
|||
call_deferred("_set_main_scene_state",state); //do after everything else is done setting up
|
||||
//print_line("set current 6 ");
|
||||
changing_scene=false;
|
||||
ScriptEditor::get_singleton()->get_debugger()->update_live_edit_root();
|
||||
|
||||
|
||||
}
|
||||
|
@ -3155,6 +3163,8 @@ Error EditorNode::load_scene(const String& p_scene) {
|
|||
prev_scene->set_disabled(previous_scenes.size()==0);
|
||||
opening_prev=false;
|
||||
|
||||
ScriptEditor::get_singleton()->get_debugger()->update_live_edit_root();
|
||||
|
||||
//top_pallete->set_current_tab(0); //always go to scene
|
||||
|
||||
push_item(new_scene);
|
||||
|
@ -4614,6 +4624,14 @@ EditorNode::EditorNode() {
|
|||
play_custom_scene_button->connect("pressed", this,"_menu_option",make_binds(RUN_PLAY_CUSTOM_SCENE));
|
||||
play_custom_scene_button->set_tooltip("Play custom scene ("+keycode_get_string(KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_F5)+").");
|
||||
|
||||
live_debug_button = memnew( ToolButton );
|
||||
play_hb->add_child(live_debug_button);
|
||||
live_debug_button->set_toggle_mode(true);
|
||||
live_debug_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
live_debug_button->set_icon(gui_base->get_icon("LiveDebug","EditorIcons"));
|
||||
live_debug_button->connect("pressed", this,"_menu_option",make_binds(RUN_LIVE_DEBUG));
|
||||
live_debug_button->set_tooltip("Toggle Live Debugging On/Off");
|
||||
|
||||
fileserver_menu = memnew( MenuButton );
|
||||
play_hb->add_child(fileserver_menu);
|
||||
fileserver_menu->set_flat(true);
|
||||
|
|
|
@ -152,6 +152,7 @@ class EditorNode : public Node {
|
|||
RUN_PROJECT_MANAGER,
|
||||
RUN_FILE_SERVER,
|
||||
RUN_DEPLOY_DUMB_CLIENTS,
|
||||
RUN_LIVE_DEBUG,
|
||||
SETTINGS_UPDATE_ALWAYS,
|
||||
SETTINGS_UPDATE_CHANGES,
|
||||
SETTINGS_IMPORT,
|
||||
|
@ -239,6 +240,7 @@ class EditorNode : public Node {
|
|||
ToolButton *animation_menu;
|
||||
ToolButton *play_scene_button;
|
||||
ToolButton *play_custom_scene_button;
|
||||
ToolButton *live_debug_button;
|
||||
TextureProgress *audio_vu;
|
||||
MenuButton *fileserver_menu;
|
||||
|
||||
|
|
BIN
tools/editor/icons/icon_live_debug.png
Normal file
BIN
tools/editor/icons/icon_live_debug.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 583 B |
|
@ -250,6 +250,8 @@ public:
|
|||
void set_window_layout(Ref<ConfigFile> p_layout);
|
||||
void get_window_layout(Ref<ConfigFile> p_layout);
|
||||
|
||||
ScriptEditorDebugger *get_debugger() { return debugger; }
|
||||
|
||||
ScriptEditor(EditorNode *p_editor);
|
||||
~ScriptEditor();
|
||||
};
|
||||
|
|
|
@ -107,8 +107,8 @@ void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bo
|
|||
|
||||
|
||||
if (p_with_undo) {
|
||||
undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose);
|
||||
undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose);
|
||||
undo_redo->add_do_method(node,"set_cellv",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose);
|
||||
undo_redo->add_undo_method(node,"set_cellv",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose);
|
||||
} else {
|
||||
|
||||
node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose);
|
||||
|
@ -314,8 +314,8 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
for(Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {
|
||||
|
||||
Point2i p=E->key();
|
||||
undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p),node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y));
|
||||
undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr);
|
||||
undo_redo->add_do_method(node,"set_cellv",Point2(p),node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y));
|
||||
undo_redo->add_undo_method(node,"set_cellv",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr);
|
||||
}
|
||||
|
||||
undo_redo->commit_action();
|
||||
|
@ -344,7 +344,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
//return true;
|
||||
_set_cell(local,TileMap::INVALID_CELL);
|
||||
return true;
|
||||
} else {
|
||||
} else if (!mb.pressed) {
|
||||
|
||||
if (tool==TOOL_ERASING) {
|
||||
|
||||
|
@ -353,9 +353,10 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
for(Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {
|
||||
|
||||
Point2i p=E->key();
|
||||
//undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y));
|
||||
_set_cell(p,TileMap::INVALID_CELL,false,false,false,true);
|
||||
undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr);
|
||||
//undo_redo->add_do_method(node,"set_cell",p,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y));
|
||||
//_set_cell(p,TileMap::INVALID_CELL,false,false,false,true);
|
||||
undo_redo->add_do_method(node,"set_cellv",Point2(p),TileMap::INVALID_CELL,false,false,false);
|
||||
undo_redo->add_undo_method(node,"set_cellv",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr);
|
||||
}
|
||||
|
||||
undo_redo->commit_action();
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
#include "scene/resources/packed_scene.h"
|
||||
#include "editor_settings.h"
|
||||
#include "tools/editor/plugins/canvas_item_editor_plugin.h"
|
||||
|
||||
#include "script_editor_debugger.h"
|
||||
#include "tools/editor/plugins/script_editor_plugin.h"
|
||||
|
||||
void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
|
||||
|
||||
|
@ -105,6 +106,13 @@ Node* SceneTreeDock::instance(const String& p_file) {
|
|||
editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",instanced_scene);
|
||||
editor_data->get_undo_redo().add_do_reference(instanced_scene);
|
||||
editor_data->get_undo_redo().add_undo_method(parent,"remove_child",instanced_scene);
|
||||
|
||||
|
||||
String new_name = parent->validate_child_name(instanced_scene->get_name());
|
||||
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
|
||||
editor_data->get_undo_redo().add_do_method(sed,"live_debug_instance_node",edited_scene->get_path_to(parent),p_file,new_name);
|
||||
editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name));
|
||||
|
||||
editor_data->get_undo_redo().commit_action();
|
||||
|
||||
|
||||
|
@ -392,6 +400,11 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||
editor_data->get_undo_redo().add_undo_method(parent,"remove_child",dup);
|
||||
editor_data->get_undo_redo().add_do_reference(dup);
|
||||
|
||||
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
|
||||
|
||||
editor_data->get_undo_redo().add_do_method(sed,"live_debug_duplicate_node",edited_scene->get_path_to(node),edited_scene->get_path_to(parent),attempt);
|
||||
editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+attempt));
|
||||
|
||||
//parent->add_child(dup);
|
||||
//reselect.push_back(dup);
|
||||
}
|
||||
|
@ -903,6 +916,13 @@ void SceneTreeDock::_node_reparent(NodePath p_path,bool p_node_only) {
|
|||
|
||||
editor_data->get_undo_redo().add_do_method(node->get_parent(),"remove_child",node);
|
||||
editor_data->get_undo_redo().add_do_method(new_parent,"add_child",node);
|
||||
|
||||
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
|
||||
String new_name = new_parent->validate_child_name(node->get_name());
|
||||
editor_data->get_undo_redo().add_do_method(sed,"live_debug_reparent_node",edited_scene->get_path_to(node),edited_scene->get_path_to(new_parent),new_name);
|
||||
editor_data->get_undo_redo().add_undo_method(sed,"live_debug_reparent_node",NodePath(String(edited_scene->get_path_to(new_parent))+"/"+new_name),node->get_parent(),node->get_name());
|
||||
|
||||
|
||||
editor_data->get_undo_redo().add_do_method(this,"_set_owners",edited_scene,owners);
|
||||
|
||||
if (editor->get_animation_editor()->get_root()==node)
|
||||
|
@ -1025,6 +1045,11 @@ void SceneTreeDock::_delete_confirm() {
|
|||
editor_data->get_undo_redo().add_undo_method(this,"_set_owners",edited_scene,owners);
|
||||
//editor_data->get_undo_redo().add_undo_method(n,"set_owner",n->get_owner());
|
||||
editor_data->get_undo_redo().add_undo_reference(n);
|
||||
|
||||
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
|
||||
editor_data->get_undo_redo().add_do_method(sed,"live_debug_remove_and_keep_node",edited_scene->get_path_to(n),n->get_instance_ID());
|
||||
editor_data->get_undo_redo().add_undo_method(sed,"live_debug_restore_node",n->get_instance_ID(),edited_scene->get_path_to(n->get_parent()),n->get_index());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1082,12 +1107,20 @@ void SceneTreeDock::_create() {
|
|||
editor_data->get_undo_redo().create_action("Create Node");
|
||||
|
||||
if (edited_scene) {
|
||||
|
||||
editor_data->get_undo_redo().add_do_method(parent,"add_child",child);
|
||||
editor_data->get_undo_redo().add_do_method(child,"set_owner",edited_scene);
|
||||
editor_data->get_undo_redo().add_do_method(editor_selection,"clear");
|
||||
editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",child);
|
||||
editor_data->get_undo_redo().add_do_reference(child);
|
||||
editor_data->get_undo_redo().add_undo_method(parent,"remove_child",child);
|
||||
|
||||
|
||||
String new_name = parent->validate_child_name(child->get_type());
|
||||
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
|
||||
editor_data->get_undo_redo().add_do_method(sed,"live_debug_create_node",edited_scene->get_path_to(parent),child->get_type(),new_name);
|
||||
editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name));
|
||||
|
||||
} else {
|
||||
|
||||
editor_data->get_undo_redo().add_do_method(editor,"set_edited_scene",child);
|
||||
|
|
|
@ -241,6 +241,8 @@ void ScriptEditorDebugger::_parse_message(const String& p_msg,const Array& p_dat
|
|||
lv[level]=it;
|
||||
}
|
||||
|
||||
le_clear->set_disabled(false);
|
||||
le_set->set_disabled(false);
|
||||
|
||||
} else if (p_msg=="stack_dump") {
|
||||
|
||||
|
@ -443,6 +445,8 @@ void ScriptEditorDebugger::_notification(int p_what) {
|
|||
tb->set_hover_texture( get_icon("CloseHover","EditorIcons"));
|
||||
tb->set_pressed_texture( get_icon("Close","EditorIcons"));
|
||||
scene_tree_refresh->set_icon( get_icon("Reload","EditorIcons"));
|
||||
le_set->connect("pressed",this,"_live_edit_set");
|
||||
le_clear->connect("pressed",this,"_live_edit_clear");
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_PROCESS: {
|
||||
|
@ -468,6 +472,12 @@ void ScriptEditorDebugger::_notification(int p_what) {
|
|||
emit_signal("show_debugger",true);
|
||||
reason->set_text("Child Process Connected");
|
||||
reason->set_tooltip("Child Process Connected");
|
||||
scene_tree->clear();
|
||||
le_set->set_disabled(true);
|
||||
le_clear->set_disabled(false);
|
||||
//live_edit_root->set_text("/root");
|
||||
|
||||
update_live_edit_root();
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -613,6 +623,10 @@ void ScriptEditorDebugger::stop(){
|
|||
log_forced_visible=false;
|
||||
}
|
||||
|
||||
node_path_cache.clear();
|
||||
res_path_cache.clear();
|
||||
le_clear->set_disabled(false);
|
||||
le_set->set_disabled(true);
|
||||
|
||||
|
||||
hide();
|
||||
|
@ -664,6 +678,335 @@ String ScriptEditorDebugger::get_var_value(const String& p_var) const {
|
|||
return variables->get_var_value(p_var);
|
||||
}
|
||||
|
||||
int ScriptEditorDebugger::_get_node_path_cache(const NodePath& p_path) {
|
||||
|
||||
const int *r = node_path_cache.getptr(p_path);
|
||||
if (r)
|
||||
return *r;
|
||||
|
||||
last_path_id++;
|
||||
|
||||
node_path_cache[p_path]=last_path_id;
|
||||
Array msg;
|
||||
msg.push_back("live_node_path");
|
||||
msg.push_back(p_path);
|
||||
msg.push_back(last_path_id);
|
||||
ppeer->put_var(msg);
|
||||
|
||||
|
||||
return last_path_id;
|
||||
}
|
||||
|
||||
int ScriptEditorDebugger::_get_res_path_cache(const String& p_path) {
|
||||
|
||||
Map<String,int>::Element *E=res_path_cache.find(p_path);
|
||||
|
||||
if (E)
|
||||
return E->get();
|
||||
|
||||
last_path_id++;
|
||||
|
||||
res_path_cache[p_path]=last_path_id;
|
||||
Array msg;
|
||||
msg.push_back("live_res_path");
|
||||
msg.push_back(p_path);
|
||||
msg.push_back(last_path_id);
|
||||
ppeer->put_var(msg);
|
||||
|
||||
|
||||
return last_path_id;
|
||||
}
|
||||
|
||||
void ScriptEditorDebugger::_method_changed(Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE) {
|
||||
|
||||
if (!p_base || !live_debug || !connection.is_valid() || !editor->get_edited_scene())
|
||||
return;
|
||||
|
||||
Node *node = p_base->cast_to<Node>();
|
||||
|
||||
VARIANT_ARGPTRS
|
||||
|
||||
for(int i=0;i<VARIANT_ARG_MAX;i++) {
|
||||
//no pointers, sorry
|
||||
if (argptr[i] && (argptr[i]->get_type()==Variant::OBJECT || argptr[i]->get_type()==Variant::_RID))
|
||||
return;
|
||||
}
|
||||
|
||||
if (node) {
|
||||
|
||||
NodePath path = editor->get_edited_scene()->get_path_to(node);
|
||||
int pathid = _get_node_path_cache(path);
|
||||
|
||||
|
||||
|
||||
Array msg;
|
||||
msg.push_back("live_node_call");
|
||||
msg.push_back(pathid);
|
||||
msg.push_back(p_name);
|
||||
for(int i=0;i<VARIANT_ARG_MAX;i++) {
|
||||
//no pointers, sorry
|
||||
msg.push_back(*argptr[i]);
|
||||
}
|
||||
ppeer->put_var(msg);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
Resource *res = p_base->cast_to<Resource>();
|
||||
|
||||
if (res && res->get_path()!=String()) {
|
||||
|
||||
String respath = res->get_path();
|
||||
int pathid = _get_res_path_cache(respath);
|
||||
|
||||
Array msg;
|
||||
msg.push_back("live_res_call");
|
||||
msg.push_back(pathid);
|
||||
msg.push_back(p_name);
|
||||
for(int i=0;i<VARIANT_ARG_MAX;i++) {
|
||||
//no pointers, sorry
|
||||
msg.push_back(*argptr[i]);
|
||||
}
|
||||
ppeer->put_var(msg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//print_line("method");
|
||||
}
|
||||
|
||||
void ScriptEditorDebugger::_property_changed(Object*p_base,const StringName& p_property,const Variant& p_value){
|
||||
|
||||
if (!p_base || !live_debug || !connection.is_valid() || !editor->get_edited_scene())
|
||||
return;
|
||||
|
||||
Node *node = p_base->cast_to<Node>();
|
||||
|
||||
if (node) {
|
||||
|
||||
NodePath path = editor->get_edited_scene()->get_path_to(node);
|
||||
int pathid = _get_node_path_cache(path);
|
||||
|
||||
|
||||
if (p_value.is_ref()) {
|
||||
Ref<Resource> res = p_value;
|
||||
if (res.is_valid() && res->get_path()!=String()) {
|
||||
|
||||
Array msg;
|
||||
msg.push_back("live_node_prop_res");
|
||||
msg.push_back(pathid);
|
||||
msg.push_back(p_property);
|
||||
msg.push_back(res->get_path());
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
} else {
|
||||
|
||||
Array msg;
|
||||
msg.push_back("live_node_prop");
|
||||
msg.push_back(pathid);
|
||||
msg.push_back(p_property);
|
||||
msg.push_back(p_value);
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
Resource *res = p_base->cast_to<Resource>();
|
||||
|
||||
if (res && res->get_path()!=String()) {
|
||||
|
||||
String respath = res->get_path();
|
||||
int pathid = _get_res_path_cache(respath);
|
||||
|
||||
|
||||
if (p_value.is_ref()) {
|
||||
Ref<Resource> res = p_value;
|
||||
if (res.is_valid() && res->get_path()!=String()) {
|
||||
|
||||
Array msg;
|
||||
msg.push_back("live_res_prop_res");
|
||||
msg.push_back(pathid);
|
||||
msg.push_back(p_property);
|
||||
msg.push_back(res->get_path());
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
} else {
|
||||
|
||||
Array msg;
|
||||
msg.push_back("live_res_prop");
|
||||
msg.push_back(pathid);
|
||||
msg.push_back(p_property);
|
||||
msg.push_back(p_value);
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//print_line("prop");
|
||||
}
|
||||
|
||||
void ScriptEditorDebugger::_method_changeds(void *p_ud,Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE) {
|
||||
|
||||
ScriptEditorDebugger *sed = (ScriptEditorDebugger*)p_ud;
|
||||
sed->_method_changed(p_base,p_name,VARIANT_ARG_PASS);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditorDebugger::_property_changeds(void *p_ud,Object*p_base,const StringName& p_property,const Variant& p_value){
|
||||
|
||||
ScriptEditorDebugger *sed = (ScriptEditorDebugger*)p_ud;
|
||||
sed->_property_changed(p_base,p_property,p_value);
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditorDebugger::set_live_debugging(bool p_enable) {
|
||||
|
||||
live_debug=p_enable;
|
||||
}
|
||||
|
||||
void ScriptEditorDebugger::_live_edit_set() {
|
||||
|
||||
if (!connection.is_valid())
|
||||
return;
|
||||
|
||||
TreeItem* ti = scene_tree->get_selected();
|
||||
if (!ti)
|
||||
return;
|
||||
String path;
|
||||
|
||||
while(ti) {
|
||||
String lp=ti->get_text(0);
|
||||
path="/"+lp+path;
|
||||
ti=ti->get_parent();
|
||||
|
||||
}
|
||||
|
||||
NodePath np = path;
|
||||
|
||||
editor->get_editor_data().set_edited_scene_live_edit_root(np);
|
||||
|
||||
update_live_edit_root();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditorDebugger::_live_edit_clear() {
|
||||
|
||||
NodePath np = NodePath("/root");
|
||||
editor->get_editor_data().set_edited_scene_live_edit_root(np);
|
||||
|
||||
update_live_edit_root();
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditorDebugger::update_live_edit_root() {
|
||||
|
||||
NodePath np = editor->get_editor_data().get_edited_scene_live_edit_root();
|
||||
|
||||
if (connection.is_valid()) {
|
||||
Array msg;
|
||||
msg.push_back("live_set_root");
|
||||
msg.push_back(np);
|
||||
if (editor->get_edited_scene())
|
||||
msg.push_back(editor->get_edited_scene()->get_filename());
|
||||
else
|
||||
msg.push_back("");
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
live_edit_root->set_text(np);
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditorDebugger::live_debug_create_node(const NodePath& p_parent,const String& p_type,const String& p_name) {
|
||||
|
||||
if (connection.is_valid()) {
|
||||
Array msg;
|
||||
msg.push_back("live_create_node");
|
||||
msg.push_back(p_parent);
|
||||
msg.push_back(p_type);
|
||||
msg.push_back(p_name);
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditorDebugger::live_debug_instance_node(const NodePath& p_parent,const String& p_path,const String& p_name){
|
||||
|
||||
if (connection.is_valid()) {
|
||||
Array msg;
|
||||
msg.push_back("live_instance_node");
|
||||
msg.push_back(p_parent);
|
||||
msg.push_back(p_path);
|
||||
msg.push_back(p_name);
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
|
||||
}
|
||||
void ScriptEditorDebugger::live_debug_remove_node(const NodePath& p_at){
|
||||
|
||||
if (connection.is_valid()) {
|
||||
Array msg;
|
||||
msg.push_back("live_remove_node");
|
||||
msg.push_back(p_at);
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
|
||||
}
|
||||
void ScriptEditorDebugger::live_debug_remove_and_keep_node(const NodePath& p_at,ObjectID p_keep_id) {
|
||||
|
||||
if (connection.is_valid()) {
|
||||
Array msg;
|
||||
msg.push_back("live_remove_and_keep_mode");
|
||||
msg.push_back(p_at);
|
||||
msg.push_back(p_keep_id);
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
|
||||
}
|
||||
void ScriptEditorDebugger::live_debug_restore_node(ObjectID p_id, const NodePath& p_at, int p_at_pos){
|
||||
|
||||
if (connection.is_valid()) {
|
||||
Array msg;
|
||||
msg.push_back("live_restore_node");
|
||||
msg.push_back(p_id);
|
||||
msg.push_back(p_at);
|
||||
msg.push_back(p_at_pos);
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
|
||||
}
|
||||
void ScriptEditorDebugger::live_debug_duplicate_node(const NodePath& p_at,const String& p_new_name){
|
||||
|
||||
if (connection.is_valid()) {
|
||||
Array msg;
|
||||
msg.push_back("live_duplicate_node");
|
||||
msg.push_back(p_at);
|
||||
msg.push_back(p_new_name);
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
|
||||
}
|
||||
void ScriptEditorDebugger::live_debug_reparent_node(const NodePath& p_at, const NodePath& p_new_place, const String &p_new_name){
|
||||
|
||||
if (connection.is_valid()) {
|
||||
Array msg;
|
||||
msg.push_back("live_reparent_node");
|
||||
msg.push_back(p_at);
|
||||
msg.push_back(p_new_place);
|
||||
msg.push_back(p_new_name);
|
||||
ppeer->put_var(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ScriptEditorDebugger::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_stack_dump_frame_selected"),&ScriptEditorDebugger::_stack_dump_frame_selected);
|
||||
|
@ -676,6 +1019,16 @@ void ScriptEditorDebugger::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("_performance_draw"),&ScriptEditorDebugger::_performance_draw);
|
||||
ObjectTypeDB::bind_method(_MD("_performance_select"),&ScriptEditorDebugger::_performance_select);
|
||||
ObjectTypeDB::bind_method(_MD("_scene_tree_request"),&ScriptEditorDebugger::_scene_tree_request);
|
||||
ObjectTypeDB::bind_method(_MD("_live_edit_set"),&ScriptEditorDebugger::_live_edit_set);
|
||||
ObjectTypeDB::bind_method(_MD("_live_edit_clear"),&ScriptEditorDebugger::_live_edit_clear);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("live_debug_create_node"),&ScriptEditorDebugger::live_debug_create_node);
|
||||
ObjectTypeDB::bind_method(_MD("live_debug_instance_node"),&ScriptEditorDebugger::live_debug_instance_node);
|
||||
ObjectTypeDB::bind_method(_MD("live_debug_remove_node"),&ScriptEditorDebugger::live_debug_remove_node);
|
||||
ObjectTypeDB::bind_method(_MD("live_debug_remove_and_keep_node"),&ScriptEditorDebugger::live_debug_remove_and_keep_node);
|
||||
ObjectTypeDB::bind_method(_MD("live_debug_restore_node"),&ScriptEditorDebugger::live_debug_restore_node);
|
||||
ObjectTypeDB::bind_method(_MD("live_debug_duplicate_node"),&ScriptEditorDebugger::live_debug_duplicate_node);
|
||||
ObjectTypeDB::bind_method(_MD("live_debug_reparent_node"),&ScriptEditorDebugger::live_debug_reparent_node);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("goto_script_line"));
|
||||
ADD_SIGNAL(MethodInfo("breaked",PropertyInfo(Variant::BOOL,"reallydid")));
|
||||
|
@ -843,6 +1196,26 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor){
|
|||
info_left->add_margin_child("Clicked Control:",clicked_ctrl);
|
||||
clicked_ctrl_type = memnew( LineEdit );
|
||||
info_left->add_margin_child("Clicked Control Type:",clicked_ctrl_type);
|
||||
|
||||
live_edit_root = memnew( LineEdit );
|
||||
|
||||
{
|
||||
HBoxContainer *lehb = memnew( HBoxContainer );
|
||||
Label *l = memnew( Label("Live Edit Root:") );
|
||||
lehb->add_child(l);
|
||||
l->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
le_set = memnew( Button("Set From Tree") );
|
||||
lehb->add_child(le_set);
|
||||
le_clear = memnew( Button("Clear") );
|
||||
lehb->add_child(le_clear);
|
||||
info_left->add_child(lehb);
|
||||
MarginContainer *mc = memnew( MarginContainer );
|
||||
mc->add_child(live_edit_root);
|
||||
info_left->add_child(mc);
|
||||
le_set->set_disabled(true);
|
||||
le_clear->set_disabled(true);
|
||||
}
|
||||
|
||||
VBoxContainer *info_right = memnew(VBoxContainer);
|
||||
info_right->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
info->add_child(info_right);
|
||||
|
@ -868,6 +1241,11 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor){
|
|||
hide();
|
||||
log_forced_visible=false;
|
||||
|
||||
p_editor->get_undo_redo()->set_method_notify_callback(_method_changeds,this);
|
||||
p_editor->get_undo_redo()->set_property_notify_callback(_property_changeds,this);
|
||||
live_debug=false;
|
||||
last_path_id=false;
|
||||
|
||||
}
|
||||
|
||||
ScriptEditorDebugger::~ScriptEditorDebugger() {
|
||||
|
|
|
@ -56,9 +56,13 @@ class ScriptEditorDebugger : public Control {
|
|||
|
||||
LineEdit *clicked_ctrl;
|
||||
LineEdit *clicked_ctrl_type;
|
||||
LineEdit *live_edit_root;
|
||||
Tree *scene_tree;
|
||||
HSplitContainer *info;
|
||||
Button *scene_tree_refresh;
|
||||
Button *le_set;
|
||||
Button *le_clear;
|
||||
|
||||
|
||||
TextureButton *tb;
|
||||
|
||||
|
@ -94,11 +98,17 @@ class ScriptEditorDebugger : public Control {
|
|||
Array message;
|
||||
int pending_in_queue;
|
||||
|
||||
HashMap<NodePath,int> node_path_cache;
|
||||
int last_path_id;
|
||||
Map<String,int> res_path_cache;
|
||||
|
||||
|
||||
EditorNode *editor;
|
||||
|
||||
bool breaked;
|
||||
|
||||
bool live_debug;
|
||||
|
||||
void _performance_draw();
|
||||
void _performance_select(Object *, int, bool);
|
||||
void _stack_dump_frame_selected();
|
||||
|
@ -108,6 +118,20 @@ class ScriptEditorDebugger : public Control {
|
|||
void _scene_tree_request();
|
||||
void _parse_message(const String& p_msg,const Array& p_data);
|
||||
|
||||
|
||||
int _get_node_path_cache(const NodePath& p_path);
|
||||
|
||||
int _get_res_path_cache(const String& p_path);
|
||||
|
||||
void _live_edit_set();
|
||||
void _live_edit_clear();
|
||||
|
||||
void _method_changed(Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE);
|
||||
void _property_changed(Object*p_base,const StringName& p_property,const Variant& p_value);
|
||||
|
||||
static void _method_changeds(void *p_ud,Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE);
|
||||
static void _property_changeds(void *p_ud,Object*p_base,const StringName& p_property,const Variant& p_value);
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
|
@ -127,6 +151,19 @@ public:
|
|||
|
||||
String get_var_value(const String& p_var) const;
|
||||
|
||||
void set_live_debugging(bool p_enable);
|
||||
|
||||
void live_debug_create_node(const NodePath& p_parent,const String& p_type,const String& p_name);
|
||||
void live_debug_instance_node(const NodePath& p_parent,const String& p_path,const String& p_name);
|
||||
void live_debug_remove_node(const NodePath& p_at);
|
||||
void live_debug_remove_and_keep_node(const NodePath& p_at,ObjectID p_keep_id);
|
||||
void live_debug_restore_node(ObjectID p_id,const NodePath& p_at,int p_at_pos);
|
||||
void live_debug_duplicate_node(const NodePath& p_at,const String& p_new_name);
|
||||
void live_debug_reparent_node(const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name);
|
||||
|
||||
void update_live_edit_root();
|
||||
|
||||
|
||||
virtual Size2 get_minimum_size() const;
|
||||
ScriptEditorDebugger(EditorNode *p_editor=NULL);
|
||||
~ScriptEditorDebugger();
|
||||
|
|
Loading…
Reference in a new issue