/*************************************************************************/ /* visual_script_nodes.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "visual_script_nodes.h" #include "global_constants.h" #include "global_config.h" #include "scene/main/scene_main_loop.h" #include "os/os.h" #include "scene/main/node.h" #include "os/input.h" ////////////////////////////////////////// ////////////////FUNCTION////////////////// ////////////////////////////////////////// bool VisualScriptFunction::_set(const StringName& p_name, const Variant& p_value) { if (p_name=="argument_count") { int new_argc=p_value; int argc = arguments.size(); if (argc==new_argc) return true; arguments.resize(new_argc); for(int i=argc;i *p_list) const { p_list->push_back(PropertyInfo(Variant::INT,"argument_count",PROPERTY_HINT_RANGE,"0,256")); String argt="Any"; for(int i=1;ipush_back(PropertyInfo(Variant::INT,"argument/"+itos(i+1)+"/type",PROPERTY_HINT_ENUM,argt)); p_list->push_back(PropertyInfo(Variant::STRING,"argument/"+itos(i+1)+"/name")); } if (!stack_less) { p_list->push_back(PropertyInfo(Variant::INT,"stack/size",PROPERTY_HINT_RANGE,"1,100000")); } p_list->push_back(PropertyInfo(Variant::BOOL,"stack/stackless")); p_list->push_back(PropertyInfo(Variant::INT,"rpc/mode",PROPERTY_HINT_ENUM,"Disabled,Remote,Sync,Master,Slave")); } int VisualScriptFunction::get_output_sequence_port_count() const { return 1; } bool VisualScriptFunction::has_input_sequence_port() const{ return false; } int VisualScriptFunction::get_input_value_port_count() const{ return 0; } int VisualScriptFunction::get_output_value_port_count() const{ return arguments.size(); } String VisualScriptFunction::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptFunction::get_input_value_port_info(int p_idx) const{ ERR_FAIL_V(PropertyInfo()); return PropertyInfo(); } PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const{ ERR_FAIL_INDEX_V(p_idx,arguments.size(),PropertyInfo()); PropertyInfo out; out.type=arguments[p_idx].type; out.name=arguments[p_idx].name; return out; } String VisualScriptFunction::get_caption() const { return "Function"; } String VisualScriptFunction::get_text() const { return get_name(); //use name as function name I guess } void VisualScriptFunction::add_argument(Variant::Type p_type,const String& p_name,int p_index){ Argument arg; arg.name=p_name; arg.type=p_type; if (p_index>=0) arguments.insert(p_index,arg); else arguments.push_back(arg); ports_changed_notify(); } void VisualScriptFunction::set_argument_type(int p_argidx,Variant::Type p_type){ ERR_FAIL_INDEX(p_argidx,arguments.size()); arguments[p_argidx].type=p_type; ports_changed_notify(); } Variant::Type VisualScriptFunction::get_argument_type(int p_argidx) const { ERR_FAIL_INDEX_V(p_argidx,arguments.size(),Variant::NIL); return arguments[p_argidx].type; } void VisualScriptFunction::set_argument_name(int p_argidx,const String& p_name) { ERR_FAIL_INDEX(p_argidx,arguments.size()); arguments[p_argidx].name=p_name; ports_changed_notify(); } String VisualScriptFunction::get_argument_name(int p_argidx) const { ERR_FAIL_INDEX_V(p_argidx,arguments.size(),String()); return arguments[p_argidx].name; } void VisualScriptFunction::remove_argument(int p_argidx) { ERR_FAIL_INDEX(p_argidx,arguments.size()); arguments.remove(p_argidx); ports_changed_notify(); } int VisualScriptFunction::get_argument_count() const { return arguments.size(); } void VisualScriptFunction::set_rpc_mode(ScriptInstance::RPCMode p_mode) { rpc_mode=p_mode; } ScriptInstance::RPCMode VisualScriptFunction::get_rpc_mode() const { return rpc_mode; } class VisualScriptNodeInstanceFunction : public VisualScriptNodeInstance { public: VisualScriptFunction *node; VisualScriptInstance *instance; //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { int ac = node->get_argument_count(); for(int i=0;iget_argument_type(i); if (expected!=Variant::NIL) { if (!Variant::can_convert_strict(p_inputs[i]->get_type(),expected)) { r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.expected=expected; r_error.argument=i; return 0; } } #endif *p_outputs[i]=*p_inputs[i]; } return 0; } }; VisualScriptNodeInstance* VisualScriptFunction::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceFunction * instance = memnew(VisualScriptNodeInstanceFunction ); instance->node=this; instance->instance=p_instance; return instance; } VisualScriptFunction::VisualScriptFunction() { stack_size=256; stack_less=false; rpc_mode=ScriptInstance::RPC_MODE_DISABLED; } void VisualScriptFunction::set_stack_less(bool p_enable) { stack_less=p_enable; _change_notify(); } bool VisualScriptFunction::is_stack_less() const { return stack_less; } void VisualScriptFunction::set_stack_size(int p_size) { ERR_FAIL_COND(p_size <1 || p_size>100000); stack_size=p_size; } int VisualScriptFunction::get_stack_size() const { return stack_size; } ////////////////////////////////////////// ////////////////OPERATOR////////////////// ////////////////////////////////////////// int VisualScriptOperator::get_output_sequence_port_count() const { return 0; } bool VisualScriptOperator::has_input_sequence_port() const{ return false; } int VisualScriptOperator::get_input_value_port_count() const{ return (op==Variant::OP_BIT_NEGATE || op==Variant::OP_NOT || op==Variant::OP_NEGATE || op==Variant::OP_POSITIVE) ? 1 : 2; } int VisualScriptOperator::get_output_value_port_count() const{ return 1; } String VisualScriptOperator::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptOperator::get_input_value_port_info(int p_idx) const{ static const Variant::Type port_types[Variant::OP_MAX][2]={ {Variant::NIL,Variant::NIL}, //OP_EQUAL, {Variant::NIL,Variant::NIL}, //OP_NOT_EQUAL, {Variant::NIL,Variant::NIL}, //OP_LESS, {Variant::NIL,Variant::NIL}, //OP_LESS_EQUAL, {Variant::NIL,Variant::NIL}, //OP_GREATER, {Variant::NIL,Variant::NIL}, //OP_GREATER_EQUAL, //mathematic {Variant::NIL,Variant::NIL}, //OP_ADD, {Variant::NIL,Variant::NIL}, //OP_SUBSTRACT, {Variant::NIL,Variant::NIL}, //OP_MULTIPLY, {Variant::NIL,Variant::NIL}, //OP_DIVIDE, {Variant::NIL,Variant::NIL}, //OP_NEGATE, {Variant::NIL,Variant::NIL}, //OP_POSITIVE, {Variant::INT,Variant::INT}, //OP_MODULE, {Variant::STRING,Variant::STRING}, //OP_STRING_CONCAT, //bitwise {Variant::INT,Variant::INT}, //OP_SHIFT_LEFT, {Variant::INT,Variant::INT}, //OP_SHIFT_RIGHT, {Variant::INT,Variant::INT}, //OP_BIT_AND, {Variant::INT,Variant::INT}, //OP_BIT_OR, {Variant::INT,Variant::INT}, //OP_BIT_XOR, {Variant::INT,Variant::INT}, //OP_BIT_NEGATE, //logic {Variant::BOOL,Variant::BOOL}, //OP_AND, {Variant::BOOL,Variant::BOOL}, //OP_OR, {Variant::BOOL,Variant::BOOL}, //OP_XOR, {Variant::BOOL,Variant::BOOL}, //OP_NOT, //containment {Variant::NIL,Variant::NIL} //OP_IN, }; ERR_FAIL_INDEX_V(p_idx,Variant::OP_MAX,PropertyInfo()); PropertyInfo pinfo; pinfo.name=p_idx==0?"A":"B"; pinfo.type=port_types[op][p_idx]; if (pinfo.type==Variant::NIL) pinfo.type=typed; return pinfo; } PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const{ static const Variant::Type port_types[Variant::OP_MAX]={ //comparation Variant::BOOL, //OP_EQUAL, Variant::BOOL, //OP_NOT_EQUAL, Variant::BOOL, //OP_LESS, Variant::BOOL, //OP_LESS_EQUAL, Variant::BOOL, //OP_GREATER, Variant::BOOL, //OP_GREATER_EQUAL, //mathematic Variant::NIL, //OP_ADD, Variant::NIL, //OP_SUBSTRACT, Variant::NIL, //OP_MULTIPLY, Variant::NIL, //OP_DIVIDE, Variant::NIL, //OP_NEGATE, Variant::NIL, //OP_POSITIVE, Variant::INT, //OP_MODULE, Variant::STRING, //OP_STRING_CONCAT, //bitwise Variant::INT, //OP_SHIFT_LEFT, Variant::INT, //OP_SHIFT_RIGHT, Variant::INT, //OP_BIT_AND, Variant::INT, //OP_BIT_OR, Variant::INT, //OP_BIT_XOR, Variant::INT, //OP_BIT_NEGATE, //logic Variant::BOOL, //OP_AND, Variant::BOOL, //OP_OR, Variant::BOOL, //OP_XOR, Variant::BOOL, //OP_NOT, //containment Variant::BOOL //OP_IN, }; PropertyInfo pinfo; pinfo.name=""; pinfo.type=port_types[op]; if (pinfo.type==Variant::NIL) pinfo.type=typed; return pinfo; } static const char* op_names[]={ //comparation "Equal", //OP_EQUAL, "NotEqual", //OP_NOT_EQUAL, "Less", //OP_LESS, "LessEqual", //OP_LESS_EQUAL, "Greater", //OP_GREATER, "GreaterEq", //OP_GREATER_EQUAL, //mathematic "Add", //OP_ADD, "Subtract", //OP_SUBSTRACT, "Multiply", //OP_MULTIPLY, "Divide", //OP_DIVIDE, "Negate", //OP_NEGATE, "Positive", //OP_POSITIVE, "Remainder", //OP_MODULE, "Concat", //OP_STRING_CONCAT, //bitwise "ShiftLeft", //OP_SHIFT_LEFT, "ShiftRight", //OP_SHIFT_RIGHT, "BitAnd", //OP_BIT_AND, "BitOr", //OP_BIT_OR, "BitXor", //OP_BIT_XOR, "BitNeg", //OP_BIT_NEGATE, //logic "And", //OP_AND, "Or", //OP_OR, "Xor", //OP_XOR, "Not", //OP_NOT, //containment "In", //OP_IN, }; String VisualScriptOperator::get_caption() const { return op_names[op]; } String VisualScriptOperator::get_text() const { static const wchar_t* op_names[]={ //comparation L"A = B", //OP_EQUAL, L"A \u2260 B", //OP_NOT_EQUAL, L"A < B", //OP_LESS, L"A \u2264 B", //OP_LESS_EQUAL, L"A > B", //OP_GREATER, L"A \u2265 B", //OP_GREATER_EQUAL, //mathematic L"A + B", //OP_ADD, L"A - B", //OP_SUBSTRACT, L"A x B", //OP_MULTIPLY, L"A \u00F7 B", //OP_DIVIDE, L"\u00AC A", //OP_NEGATE, L"+ A", //OP_POSITIVE, L"A mod B", //OP_MODULE, L"A .. B", //OP_STRING_CONCAT, //bitwise L"A << B", //OP_SHIFT_LEFT, L"A >> B", //OP_SHIFT_RIGHT, L"A & B", //OP_BIT_AND, L"A | B", //OP_BIT_OR, L"A ^ B", //OP_BIT_XOR, L"~A", //OP_BIT_NEGATE, //logic L"A and B", //OP_AND, L"A or B", //OP_OR, L"A xor B", //OP_XOR, L"not A", //OP_NOT, }; return op_names[op]; } void VisualScriptOperator::set_operator(Variant::Operator p_op) { if (op==p_op) return; op=p_op; ports_changed_notify(); } Variant::Operator VisualScriptOperator::get_operator() const{ return op; } void VisualScriptOperator::set_typed(Variant::Type p_op) { if (typed==p_op) return; typed=p_op; ports_changed_notify(); } Variant::Type VisualScriptOperator::get_typed() const { return typed; } void VisualScriptOperator::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator","op"),&VisualScriptOperator::set_operator); ClassDB::bind_method(D_METHOD("get_operator"),&VisualScriptOperator::get_operator); ClassDB::bind_method(D_METHOD("set_typed","type"),&VisualScriptOperator::set_typed); ClassDB::bind_method(D_METHOD("get_typed"),&VisualScriptOperator::get_typed); String types; for(int i=0;i0) types+=","; types+=op_names[i]; } String argt="Any"; for(int i=1;iget_type()==Variant::STRING) { r_error_str=*p_outputs[0]; } else { if (unary) r_error_str=String(op_names[op])+RTR(": Invalid argument of type: ")+Variant::get_type_name(p_inputs[0]->get_type()); else r_error_str=String(op_names[op])+RTR(": Invalid arguments: ")+"A: "+Variant::get_type_name(p_inputs[0]->get_type())+" B: "+Variant::get_type_name(p_inputs[1]->get_type()); } } return 0; } }; VisualScriptNodeInstance* VisualScriptOperator::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceOperator * instance = memnew(VisualScriptNodeInstanceOperator ); instance->unary=get_input_value_port_count()==1; instance->op=op; return instance; } VisualScriptOperator::VisualScriptOperator() { op=Variant::OP_ADD; typed=Variant::NIL; } template static Ref create_op_node(const String& p_name) { Ref node; node.instance(); node->set_operator(OP); return node; } ////////////////////////////////////////// ////////////////VARIABLE GET////////////////// ////////////////////////////////////////// int VisualScriptVariableGet::get_output_sequence_port_count() const { return 0; } bool VisualScriptVariableGet::has_input_sequence_port() const{ return false; } int VisualScriptVariableGet::get_input_value_port_count() const{ return 0; } int VisualScriptVariableGet::get_output_value_port_count() const{ return 1; } String VisualScriptVariableGet::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptVariableGet::get_input_value_port_info(int p_idx) const{ return PropertyInfo(); } PropertyInfo VisualScriptVariableGet::get_output_value_port_info(int p_idx) const{ PropertyInfo pinfo; pinfo.name="value"; if (get_visual_script().is_valid() && get_visual_script()->has_variable(variable)) { PropertyInfo vinfo = get_visual_script()->get_variable_info(variable); pinfo.type=vinfo.type; pinfo.hint=vinfo.hint; pinfo.hint_string=vinfo.hint_string; } return pinfo; } String VisualScriptVariableGet::get_caption() const { return "Variable"; } String VisualScriptVariableGet::get_text() const { return variable; } void VisualScriptVariableGet::set_variable(StringName p_variable) { if (variable==p_variable) return; variable=p_variable; ports_changed_notify(); } StringName VisualScriptVariableGet::get_variable() const{ return variable; } void VisualScriptVariableGet::_validate_property(PropertyInfo& property) const { if (property.name=="variable/name" && get_visual_script().is_valid()) { Ref vs = get_visual_script(); List vars; vs->get_variable_list(&vars); String vhint; for (List::Element *E=vars.front();E;E=E->next()) { if (vhint!=String()) vhint+=","; vhint+=E->get().operator String(); } property.hint=PROPERTY_HINT_ENUM; property.hint_string=vhint; } } void VisualScriptVariableGet::_bind_methods() { ClassDB::bind_method(D_METHOD("set_variable","name"),&VisualScriptVariableGet::set_variable); ClassDB::bind_method(D_METHOD("get_variable"),&VisualScriptVariableGet::get_variable); ADD_PROPERTY(PropertyInfo(Variant::STRING,"variable/name"),"set_variable","get_variable"); } class VisualScriptNodeInstanceVariableGet : public VisualScriptNodeInstance { public: VisualScriptVariableGet *node; VisualScriptInstance *instance; StringName variable; virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { if (instance->get_variable(variable,p_outputs[0])==false) { r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; r_error_str=RTR("VariableGet not found in script: ")+"'"+String(variable)+"'"; return false; } return 0; } }; VisualScriptNodeInstance* VisualScriptVariableGet::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceVariableGet * instance = memnew(VisualScriptNodeInstanceVariableGet ); instance->node=this; instance->instance=p_instance; instance->variable=variable; return instance; } VisualScriptVariableGet::VisualScriptVariableGet() { } ////////////////////////////////////////// ////////////////VARIABLE SET////////////////// ////////////////////////////////////////// int VisualScriptVariableSet::get_output_sequence_port_count() const { return 1; } bool VisualScriptVariableSet::has_input_sequence_port() const{ return true; } int VisualScriptVariableSet::get_input_value_port_count() const{ return 1; } int VisualScriptVariableSet::get_output_value_port_count() const{ return 0; } String VisualScriptVariableSet::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptVariableSet::get_input_value_port_info(int p_idx) const{ PropertyInfo pinfo; pinfo.name="set"; if (get_visual_script().is_valid() && get_visual_script()->has_variable(variable)) { PropertyInfo vinfo = get_visual_script()->get_variable_info(variable); pinfo.type=vinfo.type; pinfo.hint=vinfo.hint; pinfo.hint_string=vinfo.hint_string; } return pinfo; } PropertyInfo VisualScriptVariableSet::get_output_value_port_info(int p_idx) const{ return PropertyInfo(); } String VisualScriptVariableSet::get_caption() const { return "VariableSet"; } String VisualScriptVariableSet::get_text() const { return variable; } void VisualScriptVariableSet::set_variable(StringName p_variable) { if (variable==p_variable) return; variable=p_variable; ports_changed_notify(); } StringName VisualScriptVariableSet::get_variable() const{ return variable; } void VisualScriptVariableSet::_validate_property(PropertyInfo& property) const { if (property.name=="variable/name" && get_visual_script().is_valid()) { Ref vs = get_visual_script(); List vars; vs->get_variable_list(&vars); String vhint; for (List::Element *E=vars.front();E;E=E->next()) { if (vhint!=String()) vhint+=","; vhint+=E->get().operator String(); } property.hint=PROPERTY_HINT_ENUM; property.hint_string=vhint; } } void VisualScriptVariableSet::_bind_methods() { ClassDB::bind_method(D_METHOD("set_variable","name"),&VisualScriptVariableSet::set_variable); ClassDB::bind_method(D_METHOD("get_variable"),&VisualScriptVariableSet::get_variable); ADD_PROPERTY(PropertyInfo(Variant::STRING,"variable/name"),"set_variable","get_variable"); } class VisualScriptNodeInstanceVariableSet : public VisualScriptNodeInstance { public: VisualScriptVariableSet *node; VisualScriptInstance *instance; StringName variable; //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { if (instance->set_variable(variable,*p_inputs[0])==false) { r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; r_error_str=RTR("VariableSet not found in script: ")+"'"+String(variable)+"'"; } return 0; } }; VisualScriptNodeInstance* VisualScriptVariableSet::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceVariableSet * instance = memnew(VisualScriptNodeInstanceVariableSet ); instance->node=this; instance->instance=p_instance; instance->variable=variable; return instance; } VisualScriptVariableSet::VisualScriptVariableSet() { } ////////////////////////////////////////// ////////////////CONSTANT////////////////// ////////////////////////////////////////// int VisualScriptConstant::get_output_sequence_port_count() const { return 0; } bool VisualScriptConstant::has_input_sequence_port() const{ return false; } int VisualScriptConstant::get_input_value_port_count() const{ return 0; } int VisualScriptConstant::get_output_value_port_count() const{ return 1; } String VisualScriptConstant::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptConstant::get_input_value_port_info(int p_idx) const{ return PropertyInfo(); } PropertyInfo VisualScriptConstant::get_output_value_port_info(int p_idx) const{ PropertyInfo pinfo; pinfo.name="get"; pinfo.type=type; return pinfo; } String VisualScriptConstant::get_caption() const { return "Constant"; } String VisualScriptConstant::get_text() const { return String(value); } void VisualScriptConstant::set_constant_type(Variant::Type p_type) { if (type==p_type) return; type=p_type; ports_changed_notify(); Variant::CallError ce; value=Variant::construct(type,NULL,0,ce); _change_notify(); } Variant::Type VisualScriptConstant::get_constant_type() const{ return type; } void VisualScriptConstant::set_constant_value(Variant p_value){ if (value==p_value) return; value=p_value; ports_changed_notify(); } Variant VisualScriptConstant::get_constant_value() const{ return value; } void VisualScriptConstant::_validate_property(PropertyInfo& property) const { if (property.name=="constant/value") { property.type=type; if (type==Variant::NIL) property.usage=0; //do not save if nil } } void VisualScriptConstant::_bind_methods() { ClassDB::bind_method(D_METHOD("set_constant_type","type"),&VisualScriptConstant::set_constant_type); ClassDB::bind_method(D_METHOD("get_constant_type"),&VisualScriptConstant::get_constant_type); ClassDB::bind_method(D_METHOD("set_constant_value","value"),&VisualScriptConstant::set_constant_value); ClassDB::bind_method(D_METHOD("get_constant_value"),&VisualScriptConstant::get_constant_value); String argt="Null"; for(int i=1;iconstant=value; return instance; } VisualScriptConstant::VisualScriptConstant() { type=Variant::NIL; } ////////////////////////////////////////// ////////////////PRELOAD////////////////// ////////////////////////////////////////// int VisualScriptPreload::get_output_sequence_port_count() const { return 0; } bool VisualScriptPreload::has_input_sequence_port() const{ return false; } int VisualScriptPreload::get_input_value_port_count() const{ return 0; } int VisualScriptPreload::get_output_value_port_count() const{ return 1; } String VisualScriptPreload::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptPreload::get_input_value_port_info(int p_idx) const{ return PropertyInfo(); } PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const{ PropertyInfo pinfo=PropertyInfo(Variant::OBJECT,"res"); if (preload.is_valid()) { pinfo.hint=PROPERTY_HINT_RESOURCE_TYPE; pinfo.hint_string=preload->get_class(); } return pinfo; } String VisualScriptPreload::get_caption() const { return "Preload"; } String VisualScriptPreload::get_text() const { if (preload.is_valid()) { if (preload->get_path().is_resource_file()) { return preload->get_path(); } else if (preload->get_name()!=String()) { return preload->get_name(); } else { return preload->get_class(); } } else { return ""; } } void VisualScriptPreload::set_preload(const Ref& p_preload){ if (preload==p_preload) return; preload=p_preload; ports_changed_notify(); } Ref VisualScriptPreload::get_preload() const{ return preload; } void VisualScriptPreload::_bind_methods() { ClassDB::bind_method(D_METHOD("set_preload","resource"),&VisualScriptPreload::set_preload); ClassDB::bind_method(D_METHOD("get_preload"),&VisualScriptPreload::get_preload); ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"resource",PROPERTY_HINT_RESOURCE_TYPE,"Resource"),"set_preload","get_preload"); } class VisualScriptNodeInstancePreload : public VisualScriptNodeInstance { public: Ref preload; //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { *p_outputs[0]=preload; return 0; } }; VisualScriptNodeInstance* VisualScriptPreload::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstancePreload * instance = memnew(VisualScriptNodeInstancePreload ); instance->preload=preload; return instance; } VisualScriptPreload::VisualScriptPreload() { } ////////////////////////////////////////// ////////////////INDEX//////////////////// ////////////////////////////////////////// int VisualScriptIndexGet::get_output_sequence_port_count() const { return 0; } bool VisualScriptIndexGet::has_input_sequence_port() const{ return false; } int VisualScriptIndexGet::get_input_value_port_count() const{ return 2; } int VisualScriptIndexGet::get_output_value_port_count() const{ return 1; } String VisualScriptIndexGet::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptIndexGet::get_input_value_port_info(int p_idx) const{ if (p_idx==0) { return PropertyInfo(Variant::NIL,"base"); } else { return PropertyInfo(Variant::NIL,"index"); } } PropertyInfo VisualScriptIndexGet::get_output_value_port_info(int p_idx) const{ return PropertyInfo(); } String VisualScriptIndexGet::get_caption() const { return "IndexGet"; } String VisualScriptIndexGet::get_text() const { return String("get"); } class VisualScriptNodeInstanceIndexGet : public VisualScriptNodeInstance { public: //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { bool valid; *p_outputs[0] = p_inputs[0]->get(*p_inputs[1],&valid); if (!valid) { r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; r_error_str="Invalid get: "+p_inputs[0]->get_construct_string(); } return 0; } }; VisualScriptNodeInstance* VisualScriptIndexGet::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceIndexGet * instance = memnew(VisualScriptNodeInstanceIndexGet ); return instance; } VisualScriptIndexGet::VisualScriptIndexGet() { } ////////////////////////////////////////// ////////////////INDEXSET////////////////// ////////////////////////////////////////// int VisualScriptIndexSet::get_output_sequence_port_count() const { return 1; } bool VisualScriptIndexSet::has_input_sequence_port() const{ return true; } int VisualScriptIndexSet::get_input_value_port_count() const{ return 3; } int VisualScriptIndexSet::get_output_value_port_count() const{ return 0; } String VisualScriptIndexSet::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptIndexSet::get_input_value_port_info(int p_idx) const{ if (p_idx==0) { return PropertyInfo(Variant::NIL,"base"); } else if (p_idx==1){ return PropertyInfo(Variant::NIL,"index"); } else { return PropertyInfo(Variant::NIL,"value"); } } PropertyInfo VisualScriptIndexSet::get_output_value_port_info(int p_idx) const{ return PropertyInfo(); } String VisualScriptIndexSet::get_caption() const { return "IndexSet"; } String VisualScriptIndexSet::get_text() const { return String("set"); } class VisualScriptNodeInstanceIndexSet : public VisualScriptNodeInstance { public: //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { bool valid; *p_outputs[0]=*p_inputs[0]; p_outputs[0]->set(*p_inputs[1],*p_inputs[2],&valid); if (!valid) { r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; r_error_str="Invalid set: "+p_inputs[1]->get_construct_string(); } return 0; } }; VisualScriptNodeInstance* VisualScriptIndexSet::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceIndexSet * instance = memnew(VisualScriptNodeInstanceIndexSet ); return instance; } VisualScriptIndexSet::VisualScriptIndexSet() { } ////////////////////////////////////////// ////////////////GLOBALCONSTANT/////////// ////////////////////////////////////////// int VisualScriptGlobalConstant::get_output_sequence_port_count() const { return 0; } bool VisualScriptGlobalConstant::has_input_sequence_port() const{ return false; } int VisualScriptGlobalConstant::get_input_value_port_count() const{ return 0; } int VisualScriptGlobalConstant::get_output_value_port_count() const{ return 1; } String VisualScriptGlobalConstant::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptGlobalConstant::get_input_value_port_info(int p_idx) const{ return PropertyInfo(); } PropertyInfo VisualScriptGlobalConstant::get_output_value_port_info(int p_idx) const{ return PropertyInfo(Variant::REAL,"value"); } String VisualScriptGlobalConstant::get_caption() const { return "GlobalConst"; } String VisualScriptGlobalConstant::get_text() const { return GlobalConstants::get_global_constant_name(index); } void VisualScriptGlobalConstant::set_global_constant(int p_which) { index=p_which; _change_notify(); ports_changed_notify(); } int VisualScriptGlobalConstant::get_global_constant() { return index; } class VisualScriptNodeInstanceGlobalConstant : public VisualScriptNodeInstance { public: int index; //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { *p_outputs[0] = GlobalConstants::get_global_constant_value(index); return 0; } }; VisualScriptNodeInstance* VisualScriptGlobalConstant::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceGlobalConstant * instance = memnew(VisualScriptNodeInstanceGlobalConstant ); instance->index=index; return instance; } void VisualScriptGlobalConstant::_bind_methods() { ClassDB::bind_method(D_METHOD("set_global_constant","index"),&VisualScriptGlobalConstant::set_global_constant); ClassDB::bind_method(D_METHOD("get_global_constant"),&VisualScriptGlobalConstant::get_global_constant); String cc; for(int i=0;i0) cc+=","; cc+=GlobalConstants::get_global_constant_name(i); } ADD_PROPERTY(PropertyInfo(Variant::INT,"constant",PROPERTY_HINT_ENUM,cc),"set_global_constant","get_global_constant"); } VisualScriptGlobalConstant::VisualScriptGlobalConstant() { index=0; } ////////////////////////////////////////// ////////////////CLASSCONSTANT/////////// ////////////////////////////////////////// int VisualScriptClassConstant::get_output_sequence_port_count() const { return 0; } bool VisualScriptClassConstant::has_input_sequence_port() const{ return false; } int VisualScriptClassConstant::get_input_value_port_count() const{ return 0; } int VisualScriptClassConstant::get_output_value_port_count() const{ return 1; } String VisualScriptClassConstant::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptClassConstant::get_input_value_port_info(int p_idx) const{ return PropertyInfo(); } PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) const{ return PropertyInfo(Variant::INT,"value"); } String VisualScriptClassConstant::get_caption() const { return "ClassConst"; } String VisualScriptClassConstant::get_text() const { return String(base_type)+"."+String(name); } void VisualScriptClassConstant::set_class_constant(const StringName& p_which) { name=p_which; _change_notify(); ports_changed_notify(); } StringName VisualScriptClassConstant::get_class_constant() { return name; } void VisualScriptClassConstant::set_base_type(const StringName& p_which) { base_type=p_which; _change_notify(); ports_changed_notify(); } StringName VisualScriptClassConstant::get_base_type() { return base_type; } class VisualScriptNodeInstanceClassConstant : public VisualScriptNodeInstance { public: int value; bool valid; //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { if (!valid) { r_error_str="Invalid constant name, pick a valid class constant."; r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; } *p_outputs[0] = value; return 0; } }; VisualScriptNodeInstance* VisualScriptClassConstant::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceClassConstant * instance = memnew(VisualScriptNodeInstanceClassConstant ); instance->value=ClassDB::get_integer_constant(base_type,name,&instance->valid); return instance; } void VisualScriptClassConstant::_validate_property(PropertyInfo& property) const { if (property.name=="constant") { List constants; ClassDB::get_integer_constant_list(base_type,&constants,true); property.hint_string=""; for(List::Element *E=constants.front();E;E=E->next()) { if (property.hint_string!=String()) { property.hint_string+=","; } property.hint_string+=E->get(); } } } void VisualScriptClassConstant::_bind_methods() { ClassDB::bind_method(D_METHOD("set_class_constant","name"),&VisualScriptClassConstant::set_class_constant); ClassDB::bind_method(D_METHOD("get_class_constant"),&VisualScriptClassConstant::get_class_constant); ClassDB::bind_method(D_METHOD("set_base_type","name"),&VisualScriptClassConstant::set_base_type); ClassDB::bind_method(D_METHOD("get_base_type"),&VisualScriptClassConstant::get_base_type); ADD_PROPERTY(PropertyInfo(Variant::STRING,"base_type",PROPERTY_HINT_TYPE_STRING,"Object"),"set_base_type","get_base_type"); ADD_PROPERTY(PropertyInfo(Variant::STRING,"constant",PROPERTY_HINT_ENUM,""),"set_class_constant","get_class_constant"); } VisualScriptClassConstant::VisualScriptClassConstant() { base_type="Object"; } ////////////////////////////////////////// ////////////////BASICTYPECONSTANT/////////// ////////////////////////////////////////// int VisualScriptBasicTypeConstant::get_output_sequence_port_count() const { return 0; } bool VisualScriptBasicTypeConstant::has_input_sequence_port() const{ return false; } int VisualScriptBasicTypeConstant::get_input_value_port_count() const{ return 0; } int VisualScriptBasicTypeConstant::get_output_value_port_count() const{ return 1; } String VisualScriptBasicTypeConstant::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptBasicTypeConstant::get_input_value_port_info(int p_idx) const{ return PropertyInfo(); } PropertyInfo VisualScriptBasicTypeConstant::get_output_value_port_info(int p_idx) const{ return PropertyInfo(Variant::INT,"value"); } String VisualScriptBasicTypeConstant::get_caption() const { return "BasicConst"; } String VisualScriptBasicTypeConstant::get_text() const { return Variant::get_type_name(type)+"."+String(name); } void VisualScriptBasicTypeConstant::set_basic_type_constant(const StringName& p_which) { name=p_which; _change_notify(); ports_changed_notify(); } StringName VisualScriptBasicTypeConstant::get_basic_type_constant() const { return name; } void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) { type=p_which; _change_notify(); ports_changed_notify(); } Variant::Type VisualScriptBasicTypeConstant::get_basic_type() const { return type; } class VisualScriptNodeInstanceBasicTypeConstant : public VisualScriptNodeInstance { public: int value; bool valid; //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { if (!valid) { r_error_str="Invalid constant name, pick a valid basic type constant."; r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; } *p_outputs[0] = value; return 0; } }; VisualScriptNodeInstance* VisualScriptBasicTypeConstant::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceBasicTypeConstant * instance = memnew(VisualScriptNodeInstanceBasicTypeConstant ); instance->value=Variant::get_numeric_constant_value(type,name,&instance->valid); return instance; } void VisualScriptBasicTypeConstant::_validate_property(PropertyInfo& property) const { if (property.name=="constant") { List constants; Variant::get_numeric_constants_for_type(type,&constants); if (constants.size()==0) { property.usage=0; return; } property.hint_string=""; for(List::Element *E=constants.front();E;E=E->next()) { if (property.hint_string!=String()) { property.hint_string+=","; } property.hint_string+=String(E->get()); } } } void VisualScriptBasicTypeConstant::_bind_methods() { ClassDB::bind_method(D_METHOD("set_basic_type","name"),&VisualScriptBasicTypeConstant::set_basic_type); ClassDB::bind_method(D_METHOD("get_basic_type"),&VisualScriptBasicTypeConstant::get_basic_type); ClassDB::bind_method(D_METHOD("set_basic_type_constant","name"),&VisualScriptBasicTypeConstant::set_basic_type_constant); ClassDB::bind_method(D_METHOD("get_basic_type_constant"),&VisualScriptBasicTypeConstant::get_basic_type_constant); String argt="Null"; for(int i=1;ivalue=const_value[constant]; return instance; } void VisualScriptMathConstant::_bind_methods() { ClassDB::bind_method(D_METHOD("set_math_constant","which"),&VisualScriptMathConstant::set_math_constant); ClassDB::bind_method(D_METHOD("get_math_constant"),&VisualScriptMathConstant::get_math_constant); String cc; for(int i=0;i0) cc+=","; cc+=const_name[i]; } ADD_PROPERTY(PropertyInfo(Variant::INT,"constant",PROPERTY_HINT_ENUM,cc),"set_math_constant","get_math_constant"); } VisualScriptMathConstant::VisualScriptMathConstant() { constant=MATH_CONSTANT_ONE; } ////////////////////////////////////////// ////////////////GLOBALSINGLETON/////////// ////////////////////////////////////////// int VisualScriptEngineSingleton::get_output_sequence_port_count() const { return 0; } bool VisualScriptEngineSingleton::has_input_sequence_port() const{ return false; } int VisualScriptEngineSingleton::get_input_value_port_count() const{ return 0; } int VisualScriptEngineSingleton::get_output_value_port_count() const{ return 1; } String VisualScriptEngineSingleton::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptEngineSingleton::get_input_value_port_info(int p_idx) const{ return PropertyInfo(); } PropertyInfo VisualScriptEngineSingleton::get_output_value_port_info(int p_idx) const{ return PropertyInfo(Variant::OBJECT,"instance"); } String VisualScriptEngineSingleton::get_caption() const { return "EngineSingleton"; } String VisualScriptEngineSingleton::get_text() const { return singleton; } void VisualScriptEngineSingleton::set_singleton(const String& p_string) { singleton=p_string; _change_notify(); ports_changed_notify(); } String VisualScriptEngineSingleton::get_singleton() { return singleton; } class VisualScriptNodeInstanceEngineSingleton : public VisualScriptNodeInstance { public: Object* singleton; //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { *p_outputs[0]=singleton; return 0; } }; VisualScriptNodeInstance* VisualScriptEngineSingleton::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceEngineSingleton * instance = memnew(VisualScriptNodeInstanceEngineSingleton ); instance->singleton=GlobalConfig::get_singleton()->get_singleton_object(singleton); return instance; } VisualScriptEngineSingleton::TypeGuess VisualScriptEngineSingleton::guess_output_type(TypeGuess* p_inputs, int p_output) const { Object *obj=GlobalConfig::get_singleton()->get_singleton_object(singleton); TypeGuess tg; tg.type=Variant::OBJECT; if (obj) { tg.GDCLASS=obj->get_class(); tg.script=obj->get_script(); } return tg; } void VisualScriptEngineSingleton::_bind_methods() { ClassDB::bind_method(D_METHOD("set_singleton","name"),&VisualScriptEngineSingleton::set_singleton); ClassDB::bind_method(D_METHOD("get_singleton"),&VisualScriptEngineSingleton::get_singleton); String cc; List singletons; GlobalConfig::get_singleton()->get_singletons(&singletons); for (List::Element *E=singletons.front();E;E=E->next()) { if (E->get().name=="VS" || E->get().name=="PS" || E->get().name=="PS2D" || E->get().name=="AS" || E->get().name=="TS" || E->get().name=="SS" || E->get().name=="SS2D") continue; //skip these, too simple named if (cc!=String()) cc+=","; cc+=E->get().name; } ADD_PROPERTY(PropertyInfo(Variant::STRING,"constant",PROPERTY_HINT_ENUM,cc),"set_singleton","get_singleton"); } VisualScriptEngineSingleton::VisualScriptEngineSingleton() { singleton=String(); } ////////////////////////////////////////// ////////////////GETNODE/////////// ////////////////////////////////////////// int VisualScriptSceneNode::get_output_sequence_port_count() const { return 0; } bool VisualScriptSceneNode::has_input_sequence_port() const{ return false; } int VisualScriptSceneNode::get_input_value_port_count() const{ return 0; } int VisualScriptSceneNode::get_output_value_port_count() const{ return 1; } String VisualScriptSceneNode::get_output_sequence_port_text(int p_port) const { return String(); } PropertyInfo VisualScriptSceneNode::get_input_value_port_info(int p_idx) const{ return PropertyInfo(); } PropertyInfo VisualScriptSceneNode::get_output_value_port_info(int p_idx) const{ return PropertyInfo(Variant::OBJECT,"node"); } String VisualScriptSceneNode::get_caption() const { return "SceneNode"; } String VisualScriptSceneNode::get_text() const { return path.simplified(); } void VisualScriptSceneNode::set_node_path(const NodePath& p_path) { path=p_path; _change_notify(); ports_changed_notify(); } NodePath VisualScriptSceneNode::get_node_path() { return path; } class VisualScriptNodeInstanceSceneNode : public VisualScriptNodeInstance { public: VisualScriptSceneNode *node; VisualScriptInstance *instance; NodePath path; //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) { Node* node = instance->get_owner_ptr()->cast_to(); if (!node) { r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; r_error_str="Base object is not a Node!"; return 0; } Node* another = node->get_node(path); if (!node) { r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; r_error_str="Path does not lead Node!"; return 0; } *p_outputs[0]=another; return 0; } }; VisualScriptNodeInstance* VisualScriptSceneNode::instance(VisualScriptInstance* p_instance) { VisualScriptNodeInstanceSceneNode * instance = memnew(VisualScriptNodeInstanceSceneNode ); instance->node=this; instance->instance=p_instance; instance->path=path; return instance; } #ifdef TOOLS_ENABLED static Node* _find_script_node(Node* p_edited_scene,Node* p_current_node,const Ref