| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072 | /*************************************************************************//*  visual_script_nodes.cpp                                              *//*************************************************************************//*                       This file is part of:                           *//*                           GODOT ENGINE                                *//*                      https://godotengine.org                          *//*************************************************************************//* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 *//* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   *//*                                                                       *//* 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 "core/config/engine.h"#include "core/config/project_settings.h"#include "core/core_constants.h"#include "core/input/input.h"#include "core/os/os.h"#include "scene/main/node.h"#include "scene/main/scene_tree.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 < new_argc; i++) {			arguments.write[i].name = "arg" + itos(i + 1);			arguments.write[i].type = Variant::NIL;		}		ports_changed_notify();		notify_property_list_changed();		return true;	}	if (String(p_name).begins_with("argument_")) {		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;		ERR_FAIL_INDEX_V(idx, arguments.size(), false);		String what = String(p_name).get_slice("/", 1);		if (what == "type") {			Variant::Type new_type = Variant::Type(int(p_value));			arguments.write[idx].type = new_type;			ports_changed_notify();			return true;		}		if (what == "name") {			arguments.write[idx].name = p_value;			ports_changed_notify();			return true;		}	}	if (p_name == "stack/stackless") {		set_stack_less(p_value);		return true;	}	if (p_name == "stack/size") {		stack_size = p_value;		return true;	}	if (p_name == "rpc/mode") {		rpc_mode = Multiplayer::RPCMode(int(p_value));		return true;	}	if (p_name == "sequenced/sequenced") {		sequenced = p_value;		ports_changed_notify();		return true;	}	return false;}bool VisualScriptFunction::_get(const StringName &p_name, Variant &r_ret) const {	if (p_name == "argument_count") {		r_ret = arguments.size();		return true;	}	if (String(p_name).begins_with("argument_")) {		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;		ERR_FAIL_INDEX_V(idx, arguments.size(), false);		String what = String(p_name).get_slice("/", 1);		if (what == "type") {			r_ret = arguments[idx].type;			return true;		}		if (what == "name") {			r_ret = arguments[idx].name;			return true;		}	}	if (p_name == "stack/stackless") {		r_ret = stack_less;		return true;	}	if (p_name == "stack/size") {		r_ret = stack_size;		return true;	}	if (p_name == "rpc/mode") {		r_ret = rpc_mode;		return true;	}	if (p_name == "sequenced/sequenced") {		r_ret = sequenced;		return true;	}	return false;}void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const {	p_list->push_back(PropertyInfo(Variant::INT, "argument_count", PROPERTY_HINT_RANGE, "0,256"));	String argt = "Any";	for (int i = 1; i < Variant::VARIANT_MAX; i++) {		argt += "," + Variant::get_type_name(Variant::Type(i));	}	for (int i = 0; i < arguments.size(); i++) {		p_list->push_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"));	}	p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced/sequenced"));	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,Any,Authority"));}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());}PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const {	// Need to check it without ERR_FAIL_COND, to prevent warnings from appearing on node creation via dragging.	if (p_idx < 0 || p_idx >= arguments.size()) {		return PropertyInfo();	}	PropertyInfo out;	out.type = arguments[p_idx].type;	out.name = arguments[p_idx].name;	out.hint = arguments[p_idx].hint;	out.hint_string = arguments[p_idx].hint_string;	return out;}String VisualScriptFunction::get_caption() const {	return RTR("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, const PropertyHint p_hint, const String &p_hint_string) {	Argument arg;	arg.name = p_name;	arg.type = p_type;	arg.hint = p_hint;	arg.hint_string = p_hint_string;	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.write[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.write[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_at(p_argidx);	ports_changed_notify();}int VisualScriptFunction::get_argument_count() const {	return arguments.size();}void VisualScriptFunction::set_rpc_mode(Multiplayer::RPCMode p_mode) {	rpc_mode = p_mode;}Multiplayer::RPCMode VisualScriptFunction::get_rpc_mode() const {	return rpc_mode;}class VisualScriptNodeInstanceFunction : public VisualScriptNodeInstance {public:	VisualScriptFunction *node = nullptr;	VisualScriptInstance *instance = nullptr;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		int ac = node->get_argument_count();		for (int i = 0; i < ac; i++) {#ifdef DEBUG_ENABLED			Variant::Type expected = node->get_argument_type(i);			if (expected != Variant::NIL) {				if (!Variant::can_convert_strict(p_inputs[i]->get_type(), expected)) {					r_error.error = Callable::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::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceFunction *instance = memnew(VisualScriptNodeInstanceFunction);	instance->node = this;	instance->instance = p_instance;	return instance;}void VisualScriptFunction::reset_state() {	arguments.clear();	stack_size = 256;	stack_less = false;	sequenced = true;	rpc_mode = Multiplayer::RPC_MODE_DISABLED;}VisualScriptFunction::VisualScriptFunction() {	stack_size = 256;	stack_less = false;	sequenced = true;	rpc_mode = Multiplayer::RPC_MODE_DISABLED;}void VisualScriptFunction::set_stack_less(bool p_enable) {	stack_less = p_enable;	notify_property_list_changed();}bool VisualScriptFunction::is_stack_less() const {	return stack_less;}void VisualScriptFunction::set_sequenced(bool p_enable) {	sequenced = p_enable;}bool VisualScriptFunction::is_sequenced() const {	return sequenced;}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;}///////////////////////////////////////////////////////////LISTS//////////////////////////////////////////////////////////////int VisualScriptLists::get_output_sequence_port_count() const {	if (sequenced) {		return 1;	}	return 0;}bool VisualScriptLists::has_input_sequence_port() const {	return sequenced;}String VisualScriptLists::get_output_sequence_port_text(int p_port) const {	return "";}int VisualScriptLists::get_input_value_port_count() const {	return inputports.size();}int VisualScriptLists::get_output_value_port_count() const {	return outputports.size();}PropertyInfo VisualScriptLists::get_input_value_port_info(int p_idx) const {	ERR_FAIL_INDEX_V(p_idx, inputports.size(), PropertyInfo());	PropertyInfo pi;	pi.name = inputports[p_idx].name;	pi.type = inputports[p_idx].type;	return pi;}PropertyInfo VisualScriptLists::get_output_value_port_info(int p_idx) const {	ERR_FAIL_INDEX_V(p_idx, outputports.size(), PropertyInfo());	PropertyInfo pi;	pi.name = outputports[p_idx].name;	pi.type = outputports[p_idx].type;	return pi;}bool VisualScriptLists::is_input_port_editable() const {	return ((flags & INPUT_EDITABLE) == INPUT_EDITABLE);}bool VisualScriptLists::is_input_port_name_editable() const {	return ((flags & INPUT_NAME_EDITABLE) == INPUT_NAME_EDITABLE);}bool VisualScriptLists::is_input_port_type_editable() const {	return ((flags & INPUT_TYPE_EDITABLE) == INPUT_TYPE_EDITABLE);}bool VisualScriptLists::is_output_port_editable() const {	return ((flags & OUTPUT_EDITABLE) == OUTPUT_EDITABLE);}bool VisualScriptLists::is_output_port_name_editable() const {	return ((flags & INPUT_NAME_EDITABLE) == INPUT_NAME_EDITABLE);}bool VisualScriptLists::is_output_port_type_editable() const {	return ((flags & INPUT_TYPE_EDITABLE) == INPUT_TYPE_EDITABLE);}// for the inspectorbool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {	if (p_name == "input_count" && is_input_port_editable()) {		int new_argc = p_value;		int argc = inputports.size();		if (argc == new_argc) {			return true;		}		inputports.resize(new_argc);		for (int i = argc; i < new_argc; i++) {			inputports.write[i].name = "arg" + itos(i + 1);			inputports.write[i].type = Variant::NIL;		}		ports_changed_notify();		notify_property_list_changed();		return true;	}	if (String(p_name).begins_with("input_") && is_input_port_editable()) {		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;		ERR_FAIL_INDEX_V(idx, inputports.size(), false);		String what = String(p_name).get_slice("/", 1);		if (what == "type") {			Variant::Type new_type = Variant::Type(int(p_value));			inputports.write[idx].type = new_type;			ports_changed_notify();			return true;		}		if (what == "name") {			inputports.write[idx].name = p_value;			ports_changed_notify();			return true;		}	}	if (p_name == "output_count" && is_output_port_editable()) {		int new_argc = p_value;		int argc = outputports.size();		if (argc == new_argc) {			return true;		}		outputports.resize(new_argc);		for (int i = argc; i < new_argc; i++) {			outputports.write[i].name = "arg" + itos(i + 1);			outputports.write[i].type = Variant::NIL;		}		ports_changed_notify();		notify_property_list_changed();		return true;	}	if (String(p_name).begins_with("output_") && is_output_port_editable()) {		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;		ERR_FAIL_INDEX_V(idx, outputports.size(), false);		String what = String(p_name).get_slice("/", 1);		if (what == "type") {			Variant::Type new_type = Variant::Type(int(p_value));			outputports.write[idx].type = new_type;			ports_changed_notify();			return true;		}		if (what == "name") {			outputports.write[idx].name = p_value;			ports_changed_notify();			return true;		}	}	if (p_name == "sequenced/sequenced") {		sequenced = p_value;		ports_changed_notify();		return true;	}	return false;}bool VisualScriptLists::_get(const StringName &p_name, Variant &r_ret) const {	if (p_name == "input_count" && is_input_port_editable()) {		r_ret = inputports.size();		return true;	}	if (String(p_name).begins_with("input_") && is_input_port_editable()) {		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;		ERR_FAIL_INDEX_V(idx, inputports.size(), false);		String what = String(p_name).get_slice("/", 1);		if (what == "type") {			r_ret = inputports[idx].type;			return true;		}		if (what == "name") {			r_ret = inputports[idx].name;			return true;		}	}	if (p_name == "output_count" && is_output_port_editable()) {		r_ret = outputports.size();		return true;	}	if (String(p_name).begins_with("output_") && is_output_port_editable()) {		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;		ERR_FAIL_INDEX_V(idx, outputports.size(), false);		String what = String(p_name).get_slice("/", 1);		if (what == "type") {			r_ret = outputports[idx].type;			return true;		}		if (what == "name") {			r_ret = outputports[idx].name;			return true;		}	}	if (p_name == "sequenced/sequenced") {		r_ret = sequenced;		return true;	}	return false;}void VisualScriptLists::_get_property_list(List<PropertyInfo> *p_list) const {	if (is_input_port_editable()) {		p_list->push_back(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,256"));		String argt = "Any";		for (int i = 1; i < Variant::VARIANT_MAX; i++) {			argt += "," + Variant::get_type_name(Variant::Type(i));		}		for (int i = 0; i < inputports.size(); i++) {			p_list->push_back(PropertyInfo(Variant::INT, "input_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt));			p_list->push_back(PropertyInfo(Variant::STRING, "input_" + itos(i + 1) + "/name"));		}	}	if (is_output_port_editable()) {		p_list->push_back(PropertyInfo(Variant::INT, "output_count", PROPERTY_HINT_RANGE, "0,256"));		String argt = "Any";		for (int i = 1; i < Variant::VARIANT_MAX; i++) {			argt += "," + Variant::get_type_name(Variant::Type(i));		}		for (int i = 0; i < outputports.size(); i++) {			p_list->push_back(PropertyInfo(Variant::INT, "output_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt));			p_list->push_back(PropertyInfo(Variant::STRING, "output_" + itos(i + 1) + "/name"));		}	}	p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced/sequenced"));}// input data port interactionvoid VisualScriptLists::add_input_data_port(Variant::Type p_type, const String &p_name, int p_index) {	if (!is_input_port_editable()) {		return;	}	Port inp;	inp.name = p_name;	inp.type = p_type;	if (p_index >= 0) {		inputports.insert(p_index, inp);	} else {		inputports.push_back(inp);	}	ports_changed_notify();	notify_property_list_changed();}void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type) {	if (!is_input_port_type_editable()) {		return;	}	ERR_FAIL_INDEX(p_idx, inputports.size());	inputports.write[p_idx].type = p_type;	ports_changed_notify();	notify_property_list_changed();}void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name) {	if (!is_input_port_name_editable()) {		return;	}	ERR_FAIL_INDEX(p_idx, inputports.size());	inputports.write[p_idx].name = p_name;	ports_changed_notify();	notify_property_list_changed();}void VisualScriptLists::remove_input_data_port(int p_argidx) {	if (!is_input_port_editable()) {		return;	}	ERR_FAIL_INDEX(p_argidx, inputports.size());	inputports.remove_at(p_argidx);	ports_changed_notify();	notify_property_list_changed();}// output data port interactionvoid VisualScriptLists::add_output_data_port(Variant::Type p_type, const String &p_name, int p_index) {	if (!is_output_port_editable()) {		return;	}	Port out;	out.name = p_name;	out.type = p_type;	if (p_index >= 0) {		outputports.insert(p_index, out);	} else {		outputports.push_back(out);	}	ports_changed_notify();	notify_property_list_changed();}void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_type) {	if (!is_output_port_type_editable()) {		return;	}	ERR_FAIL_INDEX(p_idx, outputports.size());	outputports.write[p_idx].type = p_type;	ports_changed_notify();	notify_property_list_changed();}void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_name) {	if (!is_output_port_name_editable()) {		return;	}	ERR_FAIL_INDEX(p_idx, outputports.size());	outputports.write[p_idx].name = p_name;	ports_changed_notify();	notify_property_list_changed();}void VisualScriptLists::remove_output_data_port(int p_argidx) {	if (!is_output_port_editable()) {		return;	}	ERR_FAIL_INDEX(p_argidx, outputports.size());	outputports.remove_at(p_argidx);	ports_changed_notify();	notify_property_list_changed();}// sequencesvoid VisualScriptLists::set_sequenced(bool p_enable) {	if (sequenced == p_enable) {		return;	}	sequenced = p_enable;	ports_changed_notify();}bool VisualScriptLists::is_sequenced() const {	return sequenced;}void VisualScriptLists::reset_state() {	inputports.clear();	outputports.clear();	sequenced = false;	flags = 0;}VisualScriptLists::VisualScriptLists() {	// initialize	sequenced = false;	flags = 0;}void VisualScriptLists::_bind_methods() {	ClassDB::bind_method(D_METHOD("add_input_data_port", "type", "name", "index"), &VisualScriptLists::add_input_data_port);	ClassDB::bind_method(D_METHOD("set_input_data_port_name", "index", "name"), &VisualScriptLists::set_input_data_port_name);	ClassDB::bind_method(D_METHOD("set_input_data_port_type", "index", "type"), &VisualScriptLists::set_input_data_port_type);	ClassDB::bind_method(D_METHOD("remove_input_data_port", "index"), &VisualScriptLists::remove_input_data_port);	ClassDB::bind_method(D_METHOD("add_output_data_port", "type", "name", "index"), &VisualScriptLists::add_output_data_port);	ClassDB::bind_method(D_METHOD("set_output_data_port_name", "index", "name"), &VisualScriptLists::set_output_data_port_name);	ClassDB::bind_method(D_METHOD("set_output_data_port_type", "index", "type"), &VisualScriptLists::set_output_data_port_type);	ClassDB::bind_method(D_METHOD("remove_output_data_port", "index"), &VisualScriptLists::remove_output_data_port);}////////////////////////////////////////////////////////COMPOSEARRAY//////////////////////////////////////////////////////////int VisualScriptComposeArray::get_output_sequence_port_count() const {	if (sequenced) {		return 1;	}	return 0;}bool VisualScriptComposeArray::has_input_sequence_port() const {	return sequenced;}String VisualScriptComposeArray::get_output_sequence_port_text(int p_port) const {	return "";}int VisualScriptComposeArray::get_input_value_port_count() const {	return inputports.size();}int VisualScriptComposeArray::get_output_value_port_count() const {	return 1;}PropertyInfo VisualScriptComposeArray::get_input_value_port_info(int p_idx) const {	ERR_FAIL_INDEX_V(p_idx, inputports.size(), PropertyInfo());	PropertyInfo pi;	pi.name = inputports[p_idx].name;	pi.type = inputports[p_idx].type;	return pi;}PropertyInfo VisualScriptComposeArray::get_output_value_port_info(int p_idx) const {	PropertyInfo pi;	pi.name = "out";	pi.type = Variant::ARRAY;	return pi;}String VisualScriptComposeArray::get_caption() const {	return RTR("Compose Array");}String VisualScriptComposeArray::get_text() const {	return "";}class VisualScriptComposeArrayNode : public VisualScriptNodeInstance {public:	int input_count = 0;	virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		if (input_count > 0) {			Array arr;			for (int i = 0; i < input_count; i++) {				arr.push_back((*p_inputs[i]));			}			Variant va = Variant(arr);			*p_outputs[0] = va;		}		return 0;	}};VisualScriptNodeInstance *VisualScriptComposeArray::instantiate(VisualScriptInstance *p_instance) {	VisualScriptComposeArrayNode *instance = memnew(VisualScriptComposeArrayNode);	instance->input_count = inputports.size();	return instance;}VisualScriptComposeArray::VisualScriptComposeArray() {	// initialize stuff here	sequenced = false;	flags = INPUT_EDITABLE;}//////////////////////////////////////////////////////////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_SUBTRACT,		{ 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,		//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, 2, 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] = {		//comparison		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_SUBTRACT,		Variant::NIL, //OP_MULTIPLY,		Variant::NIL, //OP_DIVIDE,		Variant::NIL, //OP_NEGATE,		Variant::NIL, //OP_POSITIVE,		Variant::INT, //OP_MODULE,		//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;}String VisualScriptOperator::get_caption() const {	switch (op) {		// comparison		case Variant::OP_EQUAL:			return U"A = B";		case Variant::OP_NOT_EQUAL:			return U"A \u2260 B";		case Variant::OP_LESS:			return U"A < B";		case Variant::OP_LESS_EQUAL:			return U"A \u2264 B";		case Variant::OP_GREATER:			return U"A > B";		case Variant::OP_GREATER_EQUAL:			return U"A \u2265 B";		// mathematic		case Variant::OP_ADD:			return U"A + B";		case Variant::OP_SUBTRACT:			return U"A - B";		case Variant::OP_MULTIPLY:			return U"A \u00D7 B";		case Variant::OP_DIVIDE:			return U"A \u00F7 B";		case Variant::OP_NEGATE:			return U"\u00AC A";		case Variant::OP_POSITIVE:			return U"+ A";		case Variant::OP_MODULE:			return U"A mod B";		// bitwise		case Variant::OP_SHIFT_LEFT:			return U"A << B";		case Variant::OP_SHIFT_RIGHT:			return U"A >> B";		case Variant::OP_BIT_AND:			return U"A & B";		case Variant::OP_BIT_OR:			return U"A | B";		case Variant::OP_BIT_XOR:			return U"A ^ B";		case Variant::OP_BIT_NEGATE:			return U"~A";		// logic		case Variant::OP_AND:			return U"A and B";		case Variant::OP_OR:			return U"A or B";		case Variant::OP_XOR:			return U"A xor B";		case Variant::OP_NOT:			return U"not A";		case Variant::OP_IN:			return U"A in B";		default: {			ERR_FAIL_V_MSG(					U"Unknown node",					U"Unknown node type encountered, caption not available.");		}	}}String VisualScriptOperator::get_operator_name(Variant::Operator p_op) {	switch (p_op) {		// comparison		case Variant::OP_EQUAL:			return "Are Equal";		case Variant::OP_NOT_EQUAL:			return "Are Not Equal";		case Variant::OP_LESS:			return "Less Than";		case Variant::OP_LESS_EQUAL:			return "Less Than or Equal";		case Variant::OP_GREATER:			return "Greater Than";		case Variant::OP_GREATER_EQUAL:			return "Greater Than or Equal";		// mathematic		case Variant::OP_ADD:			return "Add";		case Variant::OP_SUBTRACT:			return "Subtract";		case Variant::OP_MULTIPLY:			return "Multiply";		case Variant::OP_DIVIDE:			return "Divide";		case Variant::OP_NEGATE:			return "Negate";		case Variant::OP_POSITIVE:			return "Positive";		case Variant::OP_MODULE:			return "Remainder";		// bitwise		case Variant::OP_SHIFT_LEFT:			return "Bit Shift Left";		case Variant::OP_SHIFT_RIGHT:			return "Bit Shift Right";		case Variant::OP_BIT_AND:			return "Bit And";		case Variant::OP_BIT_OR:			return "Bit Or";		case Variant::OP_BIT_XOR:			return "Bit Xor";		case Variant::OP_BIT_NEGATE:			return "Bit Negate";		// logic		case Variant::OP_AND:			return "And";		case Variant::OP_OR:			return "Or";		case Variant::OP_XOR:			return "Xor";		case Variant::OP_NOT:			return "Not";		case Variant::OP_IN:			return "In";		default: {			ERR_FAIL_INDEX_V(p_op, Variant::OP_MAX, "");			return "Unknown Operator";		}	}}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; i < Variant::OP_MAX; i++) {		if (i > 0) {			types += ",";		}		types += get_operator_name(static_cast<Variant::Operator>(i));	}	String argt = "Any";	for (int i = 1; i < Variant::VARIANT_MAX; i++) {		argt += "," + Variant::get_type_name(Variant::Type(i));	}	ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, types), "set_operator", "get_operator");	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_typed", "get_typed");}class VisualScriptNodeInstanceOperator : public VisualScriptNodeInstance {public:	bool unary = false;	Variant::Operator op;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		bool valid;		if (unary) {			Variant::evaluate(op, *p_inputs[0], Variant(), *p_outputs[0], valid);		} else {			Variant::evaluate(op, *p_inputs[0], *p_inputs[1], *p_outputs[0], valid);		}		if (!valid) {			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;			if (p_outputs[0]->get_type() == Variant::STRING) {				r_error_str = *p_outputs[0];			} else {				if (unary) {					r_error_str = String(Variant::get_operator_name(op)) + ": " + RTR("Invalid argument of type:") + " " + Variant::get_type_name(p_inputs[0]->get_type());				} else {					r_error_str = String(Variant::get_operator_name(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::instantiate(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 <Variant::Operator OP>static Ref<VisualScriptNode> create_op_node(const String &p_name) {	Ref<VisualScriptOperator> node;	node.instantiate();	node->set_operator(OP);	return node;}//////////////////////////////////////////////////////////OPERATOR////////////////////////////////////////////////////////////int VisualScriptSelect::get_output_sequence_port_count() const {	return 0;}bool VisualScriptSelect::has_input_sequence_port() const {	return false;}int VisualScriptSelect::get_input_value_port_count() const {	return 3;}int VisualScriptSelect::get_output_value_port_count() const {	return 1;}String VisualScriptSelect::get_output_sequence_port_text(int p_port) const {	return String();}PropertyInfo VisualScriptSelect::get_input_value_port_info(int p_idx) const {	if (p_idx == 0) {		return PropertyInfo(Variant::BOOL, "cond");	} else if (p_idx == 1) {		return PropertyInfo(typed, "a");	} else {		return PropertyInfo(typed, "b");	}}PropertyInfo VisualScriptSelect::get_output_value_port_info(int p_idx) const {	return PropertyInfo(typed, "out");}String VisualScriptSelect::get_caption() const {	return RTR("Select");}String VisualScriptSelect::get_text() const {	return RTR("a if cond, else b");}void VisualScriptSelect::set_typed(Variant::Type p_op) {	if (typed == p_op) {		return;	}	typed = p_op;	ports_changed_notify();}Variant::Type VisualScriptSelect::get_typed() const {	return typed;}void VisualScriptSelect::_bind_methods() {	ClassDB::bind_method(D_METHOD("set_typed", "type"), &VisualScriptSelect::set_typed);	ClassDB::bind_method(D_METHOD("get_typed"), &VisualScriptSelect::get_typed);	String argt = "Any";	for (int i = 1; i < Variant::VARIANT_MAX; i++) {		argt += "," + Variant::get_type_name(Variant::Type(i));	}	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_typed", "get_typed");}class VisualScriptNodeInstanceSelect : public VisualScriptNodeInstance {public:	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		bool cond = *p_inputs[0];		if (cond) {			*p_outputs[0] = *p_inputs[1];		} else {			*p_outputs[0] = *p_inputs[2];		}		return 0;	}};VisualScriptNodeInstance *VisualScriptSelect::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceSelect *instance = memnew(VisualScriptNodeInstanceSelect);	return instance;}VisualScriptSelect::VisualScriptSelect() {	typed = Variant::NIL;}//////////////////////////////////////////////////////////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 vformat(RTR("Get %s"), 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 == "var_name" && get_visual_script().is_valid()) {		Ref<VisualScript> vs = get_visual_script();		List<StringName> vars;		vs->get_variable_list(&vars);		String vhint;		for (const StringName &E : vars) {			if (!vhint.is_empty()) {				vhint += ",";			}			vhint += E.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, "var_name"), "set_variable", "get_variable");}class VisualScriptNodeInstanceVariableGet : public VisualScriptNodeInstance {public:	VisualScriptVariableGet *node = nullptr;	VisualScriptInstance *instance = nullptr;	StringName variable;	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		if (!instance->get_variable(variable, p_outputs[0])) {			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;			r_error_str = RTR("VariableGet not found in script:") + " '" + String(variable) + "'";			return 0;		}		return 0;	}};VisualScriptNodeInstance *VisualScriptVariableGet::instantiate(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 vformat(RTR("Set %s"), 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 == "var_name" && get_visual_script().is_valid()) {		Ref<VisualScript> vs = get_visual_script();		List<StringName> vars;		vs->get_variable_list(&vars);		String vhint;		for (const StringName &E : vars) {			if (!vhint.is_empty()) {				vhint += ",";			}			vhint += E.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, "var_name"), "set_variable", "get_variable");}class VisualScriptNodeInstanceVariableSet : public VisualScriptNodeInstance {public:	VisualScriptVariableSet *node = nullptr;	VisualScriptInstance *instance = nullptr;	StringName variable;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		if (!instance->set_variable(variable, *p_inputs[0])) {			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;			r_error_str = RTR("VariableSet not found in script:") + " '" + String(variable) + "'";		}		return 0;	}};VisualScriptNodeInstance *VisualScriptVariableSet::instantiate(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 = String(value);	pinfo.type = type;	return pinfo;}String VisualScriptConstant::get_caption() const {	return RTR("Constant");}void VisualScriptConstant::set_constant_type(Variant::Type p_type) {	if (type == p_type) {		return;	}	type = p_type;	Callable::CallError ce;	Variant::construct(type, value, nullptr, 0, ce);	ports_changed_notify();	notify_property_list_changed();}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 == "value") {		property.type = type;		if (type == Variant::NIL) {			property.usage = PROPERTY_USAGE_NONE; //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; i < Variant::VARIANT_MAX; i++) {		argt += "," + Variant::get_type_name(Variant::Type(i));	}	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_constant_type", "get_constant_type");	ADD_PROPERTY(PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT | PROPERTY_USAGE_DEFAULT), "set_constant_value", "get_constant_value");}class VisualScriptNodeInstanceConstant : public VisualScriptNodeInstance {public:	Variant constant;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		*p_outputs[0] = constant;		return 0;	}};VisualScriptNodeInstance *VisualScriptConstant::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceConstant *instance = memnew(VisualScriptNodeInstanceConstant);	instance->constant = 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;	pinfo.type = Variant::OBJECT;	if (preload.is_valid()) {		pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;		pinfo.hint_string = preload->get_class();		if (preload->get_path().is_resource_file()) {			pinfo.name = preload->get_path();		} else if (!preload->get_name().is_empty()) {			pinfo.name = preload->get_name();		} else {			pinfo.name = preload->get_class();		}	} else {		pinfo.name = "<empty>";	}	return pinfo;}String VisualScriptPreload::get_caption() const {	return RTR("Preload");}void VisualScriptPreload::set_preload(const Ref<Resource> &p_preload) {	if (preload == p_preload) {		return;	}	preload = p_preload;	ports_changed_notify();}Ref<Resource> 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<Resource> preload;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		*p_outputs[0] = preload;		return 0;	}};VisualScriptNodeInstance *VisualScriptPreload::instantiate(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 RTR("Get Index");}class VisualScriptNodeInstanceIndexGet : public VisualScriptNodeInstance {public:	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		bool valid;		*p_outputs[0] = p_inputs[0]->get(*p_inputs[1], &valid);		if (!valid) {			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;			r_error_str = "Invalid get: " + p_inputs[0]->get_construct_string();		}		return 0;	}};VisualScriptNodeInstance *VisualScriptIndexGet::instantiate(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 RTR("Set Index");}class VisualScriptNodeInstanceIndexSet : public VisualScriptNodeInstance {public:	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		bool valid;		((Variant *)p_inputs[0])->set(*p_inputs[1], *p_inputs[2], &valid);		if (!valid) {			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;			r_error_str = "Invalid set: " + p_inputs[1]->get_construct_string();		}		return 0;	}};VisualScriptNodeInstance *VisualScriptIndexSet::instantiate(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 {	String name = CoreConstants::get_global_constant_name(index);	return PropertyInfo(Variant::INT, name);}String VisualScriptGlobalConstant::get_caption() const {	return RTR("Global Constant");}void VisualScriptGlobalConstant::set_global_constant(int p_which) {	index = p_which;	notify_property_list_changed();	ports_changed_notify();}int VisualScriptGlobalConstant::get_global_constant() {	return index;}class VisualScriptNodeInstanceGlobalConstant : public VisualScriptNodeInstance {public:	int index = 0;	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		*p_outputs[0] = CoreConstants::get_global_constant_value(index);		return 0;	}};VisualScriptNodeInstance *VisualScriptGlobalConstant::instantiate(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; i < CoreConstants::get_global_constant_count(); i++) {		if (i > 0) {			cc += ",";		}		cc += CoreConstants::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 {	if (name == "") {		return PropertyInfo(Variant::INT, String(base_type));	} else {		return PropertyInfo(Variant::INT, String(base_type) + "." + String(name));	}}String VisualScriptClassConstant::get_caption() const {	return RTR("Class Constant");}void VisualScriptClassConstant::set_class_constant(const StringName &p_which) {	name = p_which;	notify_property_list_changed();	ports_changed_notify();}StringName VisualScriptClassConstant::get_class_constant() {	return name;}void VisualScriptClassConstant::set_base_type(const StringName &p_which) {	base_type = p_which;	List<String> constants;	ClassDB::get_integer_constant_list(base_type, &constants, true);	if (constants.size() > 0) {		bool found_name = false;		for (const String &E : constants) {			if (E == name) {				found_name = true;				break;			}		}		if (!found_name) {			name = constants[0];		}	} else {		name = "";	}	notify_property_list_changed();	ports_changed_notify();}StringName VisualScriptClassConstant::get_base_type() {	return base_type;}class VisualScriptNodeInstanceClassConstant : public VisualScriptNodeInstance {public:	int value = 0;	bool valid = false;	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		if (!valid) {			r_error_str = "Invalid constant name, pick a valid class constant.";			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;		}		*p_outputs[0] = value;		return 0;	}};VisualScriptNodeInstance *VisualScriptClassConstant::instantiate(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<String> constants;		ClassDB::get_integer_constant_list(base_type, &constants, true);		property.hint_string = "";		for (const String &E : constants) {			if (!property.hint_string.is_empty()) {				property.hint_string += ",";			}			property.hint_string += E;		}	}}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(type, "value");}String VisualScriptBasicTypeConstant::get_caption() const {	return RTR("Basic Constant");}String VisualScriptBasicTypeConstant::get_text() const {	if (name == "") {		return Variant::get_type_name(type);	} else {		return Variant::get_type_name(type) + "." + String(name);	}}void VisualScriptBasicTypeConstant::set_basic_type_constant(const StringName &p_which) {	name = p_which;	notify_property_list_changed();	ports_changed_notify();}StringName VisualScriptBasicTypeConstant::get_basic_type_constant() const {	return name;}void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) {	type = p_which;	List<StringName> constants;	Variant::get_constants_for_type(type, &constants);	if (constants.size() > 0) {		bool found_name = false;		for (const StringName &E : constants) {			if (E == name) {				found_name = true;				break;			}		}		if (!found_name) {			name = constants[0];		}	} else {		name = "";	}	notify_property_list_changed();	ports_changed_notify();}Variant::Type VisualScriptBasicTypeConstant::get_basic_type() const {	return type;}class VisualScriptNodeInstanceBasicTypeConstant : public VisualScriptNodeInstance {public:	Variant value;	bool valid = false;	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		if (!valid) {			r_error_str = "Invalid constant name, pick a valid basic type constant.";			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;		}		*p_outputs[0] = value;		return 0;	}};VisualScriptNodeInstance *VisualScriptBasicTypeConstant::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceBasicTypeConstant *instance = memnew(VisualScriptNodeInstanceBasicTypeConstant);	instance->value = Variant::get_constant_value(type, name, &instance->valid);	return instance;}void VisualScriptBasicTypeConstant::_validate_property(PropertyInfo &property) const {	if (property.name == "constant") {		List<StringName> constants;		Variant::get_constants_for_type(type, &constants);		if (constants.size() == 0) {			property.usage = PROPERTY_USAGE_NONE;			return;		}		property.hint_string = "";		for (const StringName &E : constants) {			if (!property.hint_string.is_empty()) {				property.hint_string += ",";			}			property.hint_string += String(E);		}	}}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; i < Variant::VARIANT_MAX; i++) {		argt += "," + Variant::get_type_name(Variant::Type(i));	}	ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, argt), "set_basic_type", "get_basic_type");	ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_basic_type_constant", "get_basic_type_constant");}VisualScriptBasicTypeConstant::VisualScriptBasicTypeConstant() {	type = Variant::NIL;}//////////////////////////////////////////////////////////MATHCONSTANT/////////////////////////////////////////////////////const char *VisualScriptMathConstant::const_name[MATH_CONSTANT_MAX] = {	"One",	"PI",	"PI/2",	"TAU",	"E",	"Sqrt2",	"INF",	"NAN"};double VisualScriptMathConstant::const_value[MATH_CONSTANT_MAX] = {	1.0,	Math_PI,	Math_PI * 0.5,	Math_TAU,	2.71828182845904523536,	Math::sqrt(2.0),	INFINITY,	NAN};int VisualScriptMathConstant::get_output_sequence_port_count() const {	return 0;}bool VisualScriptMathConstant::has_input_sequence_port() const {	return false;}int VisualScriptMathConstant::get_input_value_port_count() const {	return 0;}int VisualScriptMathConstant::get_output_value_port_count() const {	return 1;}String VisualScriptMathConstant::get_output_sequence_port_text(int p_port) const {	return String();}PropertyInfo VisualScriptMathConstant::get_input_value_port_info(int p_idx) const {	return PropertyInfo();}PropertyInfo VisualScriptMathConstant::get_output_value_port_info(int p_idx) const {	return PropertyInfo(Variant::FLOAT, const_name[constant]);}String VisualScriptMathConstant::get_caption() const {	return RTR("Math Constant");}void VisualScriptMathConstant::set_math_constant(MathConstant p_which) {	constant = p_which;	notify_property_list_changed();	ports_changed_notify();}VisualScriptMathConstant::MathConstant VisualScriptMathConstant::get_math_constant() {	return constant;}class VisualScriptNodeInstanceMathConstant : public VisualScriptNodeInstance {public:	float value = 0.0f;	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		*p_outputs[0] = value;		return 0;	}};VisualScriptNodeInstance *VisualScriptMathConstant::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceMathConstant *instance = memnew(VisualScriptNodeInstanceMathConstant);	instance->value = 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; i < MATH_CONSTANT_MAX; i++) {		if (i > 0) {			cc += ",";		}		cc += const_name[i];	}	ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_math_constant", "get_math_constant");	BIND_ENUM_CONSTANT(MATH_CONSTANT_ONE);	BIND_ENUM_CONSTANT(MATH_CONSTANT_PI);	BIND_ENUM_CONSTANT(MATH_CONSTANT_HALF_PI);	BIND_ENUM_CONSTANT(MATH_CONSTANT_TAU);	BIND_ENUM_CONSTANT(MATH_CONSTANT_E);	BIND_ENUM_CONSTANT(MATH_CONSTANT_SQRT2);	BIND_ENUM_CONSTANT(MATH_CONSTANT_INF);	BIND_ENUM_CONSTANT(MATH_CONSTANT_NAN);	BIND_ENUM_CONSTANT(MATH_CONSTANT_MAX);}VisualScriptMathConstant::VisualScriptMathConstant() {	constant = MATH_CONSTANT_ONE;}//////////////////////////////////////////////////////////ENGINESINGLETON/////////////////////////////////////////////////////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, singleton);}String VisualScriptEngineSingleton::get_caption() const {	return RTR("Get Engine Singleton");}void VisualScriptEngineSingleton::set_singleton(const String &p_string) {	singleton = p_string;	notify_property_list_changed();	ports_changed_notify();}String VisualScriptEngineSingleton::get_singleton() {	return singleton;}class VisualScriptNodeInstanceEngineSingleton : public VisualScriptNodeInstance {public:	Object *singleton = nullptr;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		*p_outputs[0] = singleton;		return 0;	}};VisualScriptNodeInstance *VisualScriptEngineSingleton::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceEngineSingleton *instance = memnew(VisualScriptNodeInstanceEngineSingleton);	instance->singleton = Engine::get_singleton()->get_singleton_object(singleton);	return instance;}VisualScriptEngineSingleton::TypeGuess VisualScriptEngineSingleton::guess_output_type(TypeGuess *p_inputs, int p_output) const {	Object *obj = Engine::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::_validate_property(PropertyInfo &property) const {	String cc;	List<Engine::Singleton> singletons;	Engine::get_singleton()->get_singletons(&singletons);	for (const Engine::Singleton &E : singletons) {		if (E.name == "VS" || E.name == "PS" || E.name == "PS2D" || E.name == "AS" || E.name == "TS" || E.name == "SS" || E.name == "SS2D") {			continue; //skip these, too simple named		}		if (!cc.is_empty()) {			cc += ",";		}		cc += E.name;	}	property.hint = PROPERTY_HINT_ENUM;	property.hint_string = cc;}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);	ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant"), "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, path.simplified());}String VisualScriptSceneNode::get_caption() const {	return RTR("Get Scene Node");}void VisualScriptSceneNode::set_node_path(const NodePath &p_path) {	path = p_path;	notify_property_list_changed();	ports_changed_notify();}NodePath VisualScriptSceneNode::get_node_path() {	return path;}class VisualScriptNodeInstanceSceneNode : public VisualScriptNodeInstance {public:	VisualScriptSceneNode *node = nullptr;	VisualScriptInstance *instance = nullptr;	NodePath path;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		Node *node = Object::cast_to<Node>(instance->get_owner_ptr());		if (!node) {			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;			r_error_str = "Base object is not a Node!";			return 0;		}		Node *another = node->get_node(path);		if (!another) {			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;			r_error_str = "Path does not lead Node!";			return 0;		}		*p_outputs[0] = another;		return 0;	}};VisualScriptNodeInstance *VisualScriptSceneNode::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceSceneNode *instance = memnew(VisualScriptNodeInstanceSceneNode);	instance->node = this;	instance->instance = p_instance;	instance->path = path;	return instance;}#ifdef TOOLS_ENABLEDstatic Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {	if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) {		return nullptr;	}	Ref<Script> scr = p_current_node->get_script();	if (scr.is_valid() && scr == script) {		return p_current_node;	}	for (int i = 0; i < p_current_node->get_child_count(); i++) {		Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);		if (n) {			return n;		}	}	return nullptr;}#endifVisualScriptSceneNode::TypeGuess VisualScriptSceneNode::guess_output_type(TypeGuess *p_inputs, int p_output) const {	VisualScriptSceneNode::TypeGuess tg;	tg.type = Variant::OBJECT;	tg.gdclass = SNAME("Node");#ifdef TOOLS_ENABLED	Ref<Script> script = get_visual_script();	if (!script.is_valid()) {		return tg;	}	MainLoop *main_loop = OS::get_singleton()->get_main_loop();	SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);	if (!scene_tree) {		return tg;	}	Node *edited_scene = scene_tree->get_edited_scene_root();	if (!edited_scene) {		return tg;	}	Node *script_node = _find_script_node(edited_scene, edited_scene, script);	if (!script_node) {		return tg;	}	Node *another = script_node->get_node(path);	if (another) {		tg.gdclass = another->get_class();		tg.script = another->get_script();	}#endif	return tg;}void VisualScriptSceneNode::_validate_property(PropertyInfo &property) const {#ifdef TOOLS_ENABLED	if (property.name == "node_path") {		Ref<Script> script = get_visual_script();		if (!script.is_valid()) {			return;		}		MainLoop *main_loop = OS::get_singleton()->get_main_loop();		SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);		if (!scene_tree) {			return;		}		Node *edited_scene = scene_tree->get_edited_scene_root();		if (!edited_scene) {			return;		}		Node *script_node = _find_script_node(edited_scene, edited_scene, script);		if (!script_node) {			return;		}		property.hint_string = script_node->get_path();	}#endif}void VisualScriptSceneNode::_bind_methods() {	ClassDB::bind_method(D_METHOD("set_node_path", "path"), &VisualScriptSceneNode::set_node_path);	ClassDB::bind_method(D_METHOD("get_node_path"), &VisualScriptSceneNode::get_node_path);	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_node_path", "get_node_path");}VisualScriptSceneNode::VisualScriptSceneNode() {	path = String(".");}//////////////////////////////////////////////////////////SceneTree/////////////////////////////////////////////////////int VisualScriptSceneTree::get_output_sequence_port_count() const {	return 0;}bool VisualScriptSceneTree::has_input_sequence_port() const {	return false;}int VisualScriptSceneTree::get_input_value_port_count() const {	return 0;}int VisualScriptSceneTree::get_output_value_port_count() const {	return 1;}String VisualScriptSceneTree::get_output_sequence_port_text(int p_port) const {	return String();}PropertyInfo VisualScriptSceneTree::get_input_value_port_info(int p_idx) const {	return PropertyInfo();}PropertyInfo VisualScriptSceneTree::get_output_value_port_info(int p_idx) const {	return PropertyInfo(Variant::OBJECT, "Scene Tree", PROPERTY_HINT_TYPE_STRING, "SceneTree");}String VisualScriptSceneTree::get_caption() const {	return RTR("Get Scene Tree");}class VisualScriptNodeInstanceSceneTree : public VisualScriptNodeInstance {public:	VisualScriptSceneTree *node = nullptr;	VisualScriptInstance *instance = nullptr;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		Node *node = Object::cast_to<Node>(instance->get_owner_ptr());		if (!node) {			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;			r_error_str = "Base object is not a Node!";			return 0;		}		SceneTree *tree = node->get_tree();		if (!tree) {			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;			r_error_str = "Attempt to get SceneTree while node is not in the active tree.";			return 0;		}		*p_outputs[0] = tree;		return 0;	}};VisualScriptNodeInstance *VisualScriptSceneTree::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceSceneTree *instance = memnew(VisualScriptNodeInstanceSceneTree);	instance->node = this;	instance->instance = p_instance;	return instance;}VisualScriptSceneTree::TypeGuess VisualScriptSceneTree::guess_output_type(TypeGuess *p_inputs, int p_output) const {	TypeGuess tg;	tg.type = Variant::OBJECT;	tg.gdclass = SNAME("SceneTree");	return tg;}void VisualScriptSceneTree::_validate_property(PropertyInfo &property) const {}void VisualScriptSceneTree::_bind_methods() {}VisualScriptSceneTree::VisualScriptSceneTree() {}//////////////////////////////////////////////////////////RESPATH/////////////////////////////////////////////////////int VisualScriptResourcePath::get_output_sequence_port_count() const {	return 0;}bool VisualScriptResourcePath::has_input_sequence_port() const {	return false;}int VisualScriptResourcePath::get_input_value_port_count() const {	return 0;}int VisualScriptResourcePath::get_output_value_port_count() const {	return 1;}String VisualScriptResourcePath::get_output_sequence_port_text(int p_port) const {	return String();}PropertyInfo VisualScriptResourcePath::get_input_value_port_info(int p_idx) const {	return PropertyInfo();}PropertyInfo VisualScriptResourcePath::get_output_value_port_info(int p_idx) const {	return PropertyInfo(Variant::STRING, path);}String VisualScriptResourcePath::get_caption() const {	return RTR("Resource Path");}void VisualScriptResourcePath::set_resource_path(const String &p_path) {	path = p_path;	notify_property_list_changed();	ports_changed_notify();}String VisualScriptResourcePath::get_resource_path() {	return path;}class VisualScriptNodeInstanceResourcePath : public VisualScriptNodeInstance {public:	String path;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		*p_outputs[0] = path;		return 0;	}};VisualScriptNodeInstance *VisualScriptResourcePath::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceResourcePath *instance = memnew(VisualScriptNodeInstanceResourcePath);	instance->path = path;	return instance;}void VisualScriptResourcePath::_bind_methods() {	ClassDB::bind_method(D_METHOD("set_resource_path", "path"), &VisualScriptResourcePath::set_resource_path);	ClassDB::bind_method(D_METHOD("get_resource_path"), &VisualScriptResourcePath::get_resource_path);	ADD_PROPERTY(PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE), "set_resource_path", "get_resource_path");}VisualScriptResourcePath::VisualScriptResourcePath() {	path = "";}//////////////////////////////////////////////////////////SELF/////////////////////////////////////////////////////int VisualScriptSelf::get_output_sequence_port_count() const {	return 0;}bool VisualScriptSelf::has_input_sequence_port() const {	return false;}int VisualScriptSelf::get_input_value_port_count() const {	return 0;}int VisualScriptSelf::get_output_value_port_count() const {	return 1;}String VisualScriptSelf::get_output_sequence_port_text(int p_port) const {	return String();}PropertyInfo VisualScriptSelf::get_input_value_port_info(int p_idx) const {	return PropertyInfo();}PropertyInfo VisualScriptSelf::get_output_value_port_info(int p_idx) const {	StringName type_name;	if (get_visual_script().is_valid()) {		type_name = get_visual_script()->get_instance_base_type();	} else {		type_name = SNAME("instance");	}	return PropertyInfo(Variant::OBJECT, type_name);}String VisualScriptSelf::get_caption() const {	return RTR("Get Self");}class VisualScriptNodeInstanceSelf : public VisualScriptNodeInstance {public:	VisualScriptInstance *instance = nullptr;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		*p_outputs[0] = instance->get_owner_ptr();		return 0;	}};VisualScriptNodeInstance *VisualScriptSelf::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceSelf *instance = memnew(VisualScriptNodeInstanceSelf);	instance->instance = p_instance;	return instance;}VisualScriptSelf::TypeGuess VisualScriptSelf::guess_output_type(TypeGuess *p_inputs, int p_output) const {	VisualScriptSceneNode::TypeGuess tg;	tg.type = Variant::OBJECT;	tg.gdclass = SNAME("Object");	Ref<Script> script = get_visual_script();	if (!script.is_valid()) {		return tg;	}	tg.gdclass = script->get_instance_base_type();	tg.script = script;	return tg;}void VisualScriptSelf::_bind_methods() {}VisualScriptSelf::VisualScriptSelf() {}//////////////////////////////////////////////////////////CUSTOM (SCRIPTED)/////////////////////////////////////////////////////int VisualScriptCustomNode::get_output_sequence_port_count() const {	int ret;	if (GDVIRTUAL_CALL(_get_output_sequence_port_count, ret)) {		return ret;	}	return 0;}bool VisualScriptCustomNode::has_input_sequence_port() const {	bool ret;	if (GDVIRTUAL_CALL(_has_input_sequence_port, ret)) {		return ret;	}	return false;}int VisualScriptCustomNode::get_input_value_port_count() const {	int ret;	if (GDVIRTUAL_CALL(_get_input_value_port_count, ret)) {		return ret;	}	return 0;}int VisualScriptCustomNode::get_output_value_port_count() const {	int ret;	if (GDVIRTUAL_CALL(_get_output_value_port_count, ret)) {		return ret;	}	return 0;}String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const {	String ret;	if (GDVIRTUAL_CALL(_get_output_sequence_port_text, p_port, ret)) {		return ret;	}	return String();}PropertyInfo VisualScriptCustomNode::get_input_value_port_info(int p_idx) const {	PropertyInfo info;	{		int type;		if (GDVIRTUAL_CALL(_get_input_value_port_type, p_idx, type)) {			info.type = Variant::Type(type);		}	}	{		String name;		if (GDVIRTUAL_CALL(_get_input_value_port_name, p_idx, name)) {			info.name = name;		}	}	{		int hint;		if (GDVIRTUAL_CALL(_get_input_value_port_hint, p_idx, hint)) {			info.hint = PropertyHint(hint);		}	}	{		String hint_string;		if (GDVIRTUAL_CALL(_get_input_value_port_hint_string, p_idx, hint_string)) {			info.hint_string = hint_string;		}	}	return info;}PropertyInfo VisualScriptCustomNode::get_output_value_port_info(int p_idx) const {	PropertyInfo info;	{		int type;		if (GDVIRTUAL_CALL(_get_output_value_port_type, p_idx, type)) {			info.type = Variant::Type(type);		}	}	{		String name;		if (GDVIRTUAL_CALL(_get_output_value_port_name, p_idx, name)) {			info.name = name;		}	}	{		int hint;		if (GDVIRTUAL_CALL(_get_output_value_port_hint, p_idx, hint)) {			info.hint = PropertyHint(hint);		}	}	{		String hint_string;		if (GDVIRTUAL_CALL(_get_output_value_port_hint_string, p_idx, hint_string)) {			info.hint_string = hint_string;		}	}	return info;}VisualScriptCustomNode::TypeGuess VisualScriptCustomNode::guess_output_type(TypeGuess *p_inputs, int p_output) const {	TypeGuess tg;	PropertyInfo pi = VisualScriptCustomNode::get_output_value_port_info(p_output);	tg.type = pi.type;	if (pi.type == Variant::OBJECT) {		if (pi.hint == PROPERTY_HINT_RESOURCE_TYPE) {			if (pi.hint_string.is_resource_file()) {				tg.script = ResourceLoader::load(pi.hint_string);			} else if (ClassDB::class_exists(pi.hint_string)) {				tg.gdclass = pi.hint_string;			}		}	}	return tg;}String VisualScriptCustomNode::get_caption() const {	String ret;	if (GDVIRTUAL_CALL(_get_caption, ret)) {		return ret;	}	return RTR("CustomNode");}String VisualScriptCustomNode::get_text() const {	String ret;	if (GDVIRTUAL_CALL(_get_text, ret)) {		return ret;	}	return "";}String VisualScriptCustomNode::get_category() const {	String ret;	if (GDVIRTUAL_CALL(_get_category, ret)) {		return ret;	}	return "Custom";}class VisualScriptNodeInstanceCustomNode : public VisualScriptNodeInstance {public:	VisualScriptInstance *instance = nullptr;	VisualScriptCustomNode *node = nullptr;	int in_count = 0;	int out_count = 0;	int work_mem_size = 0;	virtual int get_working_memory_size() const override { return work_mem_size; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		if (GDVIRTUAL_IS_OVERRIDDEN_PTR(node, _step)) {			Array in_values;			Array out_values;			Array work_mem;			in_values.resize(in_count);			for (int i = 0; i < in_count; i++) {				in_values[i] = *p_inputs[i];			}			out_values.resize(out_count);			work_mem.resize(work_mem_size);			for (int i = 0; i < work_mem_size; i++) {				work_mem[i] = p_working_mem[i];			}			int ret_out;			Variant ret;			GDVIRTUAL_CALL_PTR(node, _step, in_values, out_values, p_start_mode, work_mem, ret);			if (ret.get_type() == Variant::STRING) {				r_error_str = ret;				r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;				return 0;			} else if (ret.is_num()) {				ret_out = ret;			} else {				r_error_str = RTR("Invalid return value from _step(), must be integer (seq out), or string (error).");				r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;				return 0;			}			for (int i = 0; i < out_count; i++) {				if (i < out_values.size()) {					*p_outputs[i] = out_values[i];				}			}			for (int i = 0; i < work_mem_size; i++) {				if (i < work_mem.size()) {					p_working_mem[i] = work_mem[i];				}			}			return ret_out;		} else {			r_error_str = RTR("Custom node has no _step() method, can't process graph.");			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;		}		return 0;	}};VisualScriptNodeInstance *VisualScriptCustomNode::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceCustomNode *instance = memnew(VisualScriptNodeInstanceCustomNode);	instance->instance = p_instance;	instance->node = this;	instance->in_count = get_input_value_port_count();	instance->out_count = get_output_value_port_count();	instance->work_mem_size = 0;	GDVIRTUAL_CALL(_get_working_memory_size, instance->work_mem_size);	return instance;}void VisualScriptCustomNode::_script_changed() {	call_deferred(SNAME("ports_changed_notify"));}void VisualScriptCustomNode::_bind_methods() {	GDVIRTUAL_BIND(_get_output_sequence_port_count);	GDVIRTUAL_BIND(_has_input_sequence_port);	GDVIRTUAL_BIND(_get_output_sequence_port_text, "seq_idx");	GDVIRTUAL_BIND(_get_input_value_port_count);	GDVIRTUAL_BIND(_get_input_value_port_type, "input_idx");	GDVIRTUAL_BIND(_get_input_value_port_name, "input_idx");	GDVIRTUAL_BIND(_get_input_value_port_hint, "input_idx");	GDVIRTUAL_BIND(_get_input_value_port_hint_string, "input_idx");	GDVIRTUAL_BIND(_get_output_value_port_count);	GDVIRTUAL_BIND(_get_output_value_port_type, "output_idx");	GDVIRTUAL_BIND(_get_output_value_port_name, "output_idx");	GDVIRTUAL_BIND(_get_output_value_port_hint, "output_idx");	GDVIRTUAL_BIND(_get_output_value_port_hint_string, "output_idx");	GDVIRTUAL_BIND(_get_caption);	GDVIRTUAL_BIND(_get_text);	GDVIRTUAL_BIND(_get_category);	GDVIRTUAL_BIND(_get_working_memory_size);	GDVIRTUAL_BIND(_step, "inputs", "outputs", "start_mode", "working_mem");	BIND_ENUM_CONSTANT(START_MODE_BEGIN_SEQUENCE);	BIND_ENUM_CONSTANT(START_MODE_CONTINUE_SEQUENCE);	BIND_ENUM_CONSTANT(START_MODE_RESUME_YIELD);	BIND_CONSTANT(STEP_PUSH_STACK_BIT);	BIND_CONSTANT(STEP_GO_BACK_BIT);	BIND_CONSTANT(STEP_NO_ADVANCE_BIT);	BIND_CONSTANT(STEP_EXIT_FUNCTION_BIT);	BIND_CONSTANT(STEP_YIELD_BIT);}VisualScriptCustomNode::VisualScriptCustomNode() {	connect("script_changed", callable_mp(this, &VisualScriptCustomNode::_script_changed));}//////////////////////////////////////////////////////////SUBCALL/////////////////////////////////////////////////////int VisualScriptSubCall::get_output_sequence_port_count() const {	return 1;}bool VisualScriptSubCall::has_input_sequence_port() const {	return true;}int VisualScriptSubCall::get_input_value_port_count() const {	Ref<Script> script = get_script();	if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {		MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall);		return mi.arguments.size();	}	return 0;}int VisualScriptSubCall::get_output_value_port_count() const {	return 1;}String VisualScriptSubCall::get_output_sequence_port_text(int p_port) const {	return String();}PropertyInfo VisualScriptSubCall::get_input_value_port_info(int p_idx) const {	Ref<Script> script = get_script();	if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {		MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall);		return mi.arguments[p_idx];	}	return PropertyInfo();}PropertyInfo VisualScriptSubCall::get_output_value_port_info(int p_idx) const {	Ref<Script> script = get_script();	if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {		MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall);		return mi.return_val;	}	return PropertyInfo();}String VisualScriptSubCall::get_caption() const {	return RTR("SubCall");}String VisualScriptSubCall::get_text() const {	Ref<Script> script = get_script();	if (script.is_valid()) {		if (!script->get_name().is_empty()) {			return script->get_name();		}		if (script->get_path().is_resource_file()) {			return script->get_path().get_file();		}		return script->get_class();	}	return "";}String VisualScriptSubCall::get_category() const {	return "custom";}class VisualScriptNodeInstanceSubCall : public VisualScriptNodeInstance {public:	VisualScriptInstance *instance = nullptr;	VisualScriptSubCall *subcall = nullptr;	int input_args = 0;	bool valid = false;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		if (!valid) {			r_error_str = "Node requires a script with a _subcall(<args>) method to work.";			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;			return 0;		}		*p_outputs[0] = subcall->callp(VisualScriptLanguage::singleton->_subcall, p_inputs, input_args, r_error);		return 0;	}};VisualScriptNodeInstance *VisualScriptSubCall::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceSubCall *instance = memnew(VisualScriptNodeInstanceSubCall);	instance->instance = p_instance;	Ref<Script> script = get_script();	if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {		instance->valid = true;		instance->input_args = get_input_value_port_count();	} else {		instance->valid = false;	}	return instance;}void VisualScriptSubCall::_bind_methods() {	// Since this is script only, registering virtual function is no longer valid. Will have to go in docs.}VisualScriptSubCall::VisualScriptSubCall() {}//////////////////////////////////////////////////////////Comment/////////////////////////////////////////////////////int VisualScriptComment::get_output_sequence_port_count() const {	return 0;}bool VisualScriptComment::has_input_sequence_port() const {	return false;}int VisualScriptComment::get_input_value_port_count() const {	return 0;}int VisualScriptComment::get_output_value_port_count() const {	return 0;}String VisualScriptComment::get_output_sequence_port_text(int p_port) const {	return String();}PropertyInfo VisualScriptComment::get_input_value_port_info(int p_idx) const {	return PropertyInfo();}PropertyInfo VisualScriptComment::get_output_value_port_info(int p_idx) const {	return PropertyInfo();}String VisualScriptComment::get_caption() const {	return title;}String VisualScriptComment::get_text() const {	return description;}void VisualScriptComment::set_title(const String &p_title) {	if (title == p_title) {		return;	}	title = p_title;	ports_changed_notify();}String VisualScriptComment::get_title() const {	return title;}void VisualScriptComment::set_description(const String &p_description) {	if (description == p_description) {		return;	}	description = p_description;	ports_changed_notify();}String VisualScriptComment::get_description() const {	return description;}void VisualScriptComment::set_size(const Size2 &p_size) {	if (size == p_size) {		return;	}	size = p_size;	ports_changed_notify();}Size2 VisualScriptComment::get_size() const {	return size;}String VisualScriptComment::get_category() const {	return "data";}class VisualScriptNodeInstanceComment : public VisualScriptNodeInstance {public:	VisualScriptInstance *instance = nullptr;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		return 0;	}};VisualScriptNodeInstance *VisualScriptComment::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceComment *instance = memnew(VisualScriptNodeInstanceComment);	instance->instance = p_instance;	return instance;}void VisualScriptComment::_bind_methods() {	ClassDB::bind_method(D_METHOD("set_title", "title"), &VisualScriptComment::set_title);	ClassDB::bind_method(D_METHOD("get_title"), &VisualScriptComment::get_title);	ClassDB::bind_method(D_METHOD("set_description", "description"), &VisualScriptComment::set_description);	ClassDB::bind_method(D_METHOD("get_description"), &VisualScriptComment::get_description);	ClassDB::bind_method(D_METHOD("set_size", "size"), &VisualScriptComment::set_size);	ClassDB::bind_method(D_METHOD("get_size"), &VisualScriptComment::get_size);	ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");	ADD_PROPERTY(PropertyInfo(Variant::STRING, "description", PROPERTY_HINT_MULTILINE_TEXT), "set_description", "get_description");	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");}VisualScriptComment::VisualScriptComment() {	title = "Comment";	size = Size2(150, 150);}//////////////////////////////////////////////////////////Constructor/////////////////////////////////////////////////////int VisualScriptConstructor::get_output_sequence_port_count() const {	return 0;}bool VisualScriptConstructor::has_input_sequence_port() const {	return false;}int VisualScriptConstructor::get_input_value_port_count() const {	return constructor.arguments.size();}int VisualScriptConstructor::get_output_value_port_count() const {	return 1;}String VisualScriptConstructor::get_output_sequence_port_text(int p_port) const {	return "";}PropertyInfo VisualScriptConstructor::get_input_value_port_info(int p_idx) const {	return constructor.arguments[p_idx];}PropertyInfo VisualScriptConstructor::get_output_value_port_info(int p_idx) const {	return PropertyInfo(type, "value");}String VisualScriptConstructor::get_caption() const {	return vformat(RTR("Construct %s"), Variant::get_type_name(type));}String VisualScriptConstructor::get_category() const {	return "functions";}void VisualScriptConstructor::set_constructor_type(Variant::Type p_type) {	if (type == p_type) {		return;	}	type = p_type;	ports_changed_notify();}Variant::Type VisualScriptConstructor::get_constructor_type() const {	return type;}void VisualScriptConstructor::set_constructor(const Dictionary &p_info) {	constructor = MethodInfo::from_dict(p_info);	ports_changed_notify();}Dictionary VisualScriptConstructor::get_constructor() const {	return constructor;}class VisualScriptNodeInstanceConstructor : public VisualScriptNodeInstance {public:	VisualScriptInstance *instance = nullptr;	Variant::Type type;	int argcount = 0;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		Callable::CallError ce;		Variant::construct(type, *p_outputs[0], p_inputs, argcount, ce);		if (ce.error != Callable::CallError::CALL_OK) {			r_error_str = "Invalid arguments for constructor";		}		return 0;	}};VisualScriptNodeInstance *VisualScriptConstructor::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceConstructor *instance = memnew(VisualScriptNodeInstanceConstructor);	instance->instance = p_instance;	instance->type = type;	instance->argcount = constructor.arguments.size();	return instance;}void VisualScriptConstructor::_bind_methods() {	ClassDB::bind_method(D_METHOD("set_constructor_type", "type"), &VisualScriptConstructor::set_constructor_type);	ClassDB::bind_method(D_METHOD("get_constructor_type"), &VisualScriptConstructor::get_constructor_type);	ClassDB::bind_method(D_METHOD("set_constructor", "constructor"), &VisualScriptConstructor::set_constructor);	ClassDB::bind_method(D_METHOD("get_constructor"), &VisualScriptConstructor::get_constructor);	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor_type", "get_constructor_type");	ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "constructor", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor", "get_constructor");}VisualScriptConstructor::VisualScriptConstructor() {	type = Variant::NIL;}static HashMap<String, Pair<Variant::Type, MethodInfo>> constructor_map;static Ref<VisualScriptNode> create_constructor_node(const String &p_name) {	ERR_FAIL_COND_V(!constructor_map.has(p_name), Ref<VisualScriptNode>());	Ref<VisualScriptConstructor> vsc;	vsc.instantiate();	vsc->set_constructor_type(constructor_map[p_name].first);	vsc->set_constructor(constructor_map[p_name].second);	return vsc;}//////////////////////////////////////////////////////////LocalVar/////////////////////////////////////////////////////int VisualScriptLocalVar::get_output_sequence_port_count() const {	return 0;}bool VisualScriptLocalVar::has_input_sequence_port() const {	return false;}int VisualScriptLocalVar::get_input_value_port_count() const {	return 0;}int VisualScriptLocalVar::get_output_value_port_count() const {	return 1;}String VisualScriptLocalVar::get_output_sequence_port_text(int p_port) const {	return "";}PropertyInfo VisualScriptLocalVar::get_input_value_port_info(int p_idx) const {	return PropertyInfo();}PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const {	return PropertyInfo(type, name);}String VisualScriptLocalVar::get_caption() const {	return RTR("Get Local Var");}String VisualScriptLocalVar::get_category() const {	return "data";}void VisualScriptLocalVar::set_var_name(const StringName &p_name) {	if (name == p_name) {		return;	}	name = p_name;	ports_changed_notify();}StringName VisualScriptLocalVar::get_var_name() const {	return name;}void VisualScriptLocalVar::set_var_type(Variant::Type p_type) {	type = p_type;	ports_changed_notify();}Variant::Type VisualScriptLocalVar::get_var_type() const {	return type;}class VisualScriptNodeInstanceLocalVar : public VisualScriptNodeInstance {public:	VisualScriptInstance *instance = nullptr;	StringName name;	virtual int get_working_memory_size() const override { return 1; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		*p_outputs[0] = *p_working_mem;		return 0;	}};VisualScriptNodeInstance *VisualScriptLocalVar::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceLocalVar *instance = memnew(VisualScriptNodeInstanceLocalVar);	instance->instance = p_instance;	instance->name = name;	return instance;}void VisualScriptLocalVar::_bind_methods() {	ClassDB::bind_method(D_METHOD("set_var_name", "name"), &VisualScriptLocalVar::set_var_name);	ClassDB::bind_method(D_METHOD("get_var_name"), &VisualScriptLocalVar::get_var_name);	ClassDB::bind_method(D_METHOD("set_var_type", "type"), &VisualScriptLocalVar::set_var_type);	ClassDB::bind_method(D_METHOD("get_var_type"), &VisualScriptLocalVar::get_var_type);	String argt = "Any";	for (int i = 1; i < Variant::VARIANT_MAX; i++) {		argt += "," + Variant::get_type_name(Variant::Type(i));	}	ADD_PROPERTY(PropertyInfo(Variant::STRING, "var_name"), "set_var_name", "get_var_name");	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_var_type", "get_var_type");}VisualScriptLocalVar::VisualScriptLocalVar() {	name = "new_local";	type = Variant::NIL;}//////////////////////////////////////////////////////////LocalVar/////////////////////////////////////////////////////int VisualScriptLocalVarSet::get_output_sequence_port_count() const {	return 1;}bool VisualScriptLocalVarSet::has_input_sequence_port() const {	return true;}int VisualScriptLocalVarSet::get_input_value_port_count() const {	return 1;}int VisualScriptLocalVarSet::get_output_value_port_count() const {	return 1;}String VisualScriptLocalVarSet::get_output_sequence_port_text(int p_port) const {	return "";}PropertyInfo VisualScriptLocalVarSet::get_input_value_port_info(int p_idx) const {	return PropertyInfo(type, "set");}PropertyInfo VisualScriptLocalVarSet::get_output_value_port_info(int p_idx) const {	return PropertyInfo(type, "get");}String VisualScriptLocalVarSet::get_caption() const {	return RTR("Set Local Var");}String VisualScriptLocalVarSet::get_text() const {	return name;}String VisualScriptLocalVarSet::get_category() const {	return "data";}void VisualScriptLocalVarSet::set_var_name(const StringName &p_name) {	if (name == p_name) {		return;	}	name = p_name;	ports_changed_notify();}StringName VisualScriptLocalVarSet::get_var_name() const {	return name;}void VisualScriptLocalVarSet::set_var_type(Variant::Type p_type) {	type = p_type;	ports_changed_notify();}Variant::Type VisualScriptLocalVarSet::get_var_type() const {	return type;}class VisualScriptNodeInstanceLocalVarSet : public VisualScriptNodeInstance {public:	VisualScriptInstance *instance = nullptr;	StringName name;	virtual int get_working_memory_size() const override { return 1; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		*p_working_mem = *p_inputs[0];		*p_outputs[0] = *p_working_mem;		return 0;	}};VisualScriptNodeInstance *VisualScriptLocalVarSet::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceLocalVarSet *instance = memnew(VisualScriptNodeInstanceLocalVarSet);	instance->instance = p_instance;	instance->name = name;	return instance;}void VisualScriptLocalVarSet::_bind_methods() {	ClassDB::bind_method(D_METHOD("set_var_name", "name"), &VisualScriptLocalVarSet::set_var_name);	ClassDB::bind_method(D_METHOD("get_var_name"), &VisualScriptLocalVarSet::get_var_name);	ClassDB::bind_method(D_METHOD("set_var_type", "type"), &VisualScriptLocalVarSet::set_var_type);	ClassDB::bind_method(D_METHOD("get_var_type"), &VisualScriptLocalVarSet::get_var_type);	String argt = "Any";	for (int i = 1; i < Variant::VARIANT_MAX; i++) {		argt += "," + Variant::get_type_name(Variant::Type(i));	}	ADD_PROPERTY(PropertyInfo(Variant::STRING, "var_name"), "set_var_name", "get_var_name");	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_var_type", "get_var_type");}VisualScriptLocalVarSet::VisualScriptLocalVarSet() {	name = "new_local";	type = Variant::NIL;}//////////////////////////////////////////////////////////LocalVar/////////////////////////////////////////////////////int VisualScriptInputAction::get_output_sequence_port_count() const {	return 0;}bool VisualScriptInputAction::has_input_sequence_port() const {	return false;}int VisualScriptInputAction::get_input_value_port_count() const {	return 0;}int VisualScriptInputAction::get_output_value_port_count() const {	return 1;}String VisualScriptInputAction::get_output_sequence_port_text(int p_port) const {	return "";}PropertyInfo VisualScriptInputAction::get_input_value_port_info(int p_idx) const {	return PropertyInfo();}PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) const {	String mstr;	switch (mode) {		case MODE_PRESSED: {			mstr = "pressed";		} break;		case MODE_RELEASED: {			mstr = "not pressed";		} break;		case MODE_JUST_PRESSED: {			mstr = "just pressed";		} break;		case MODE_JUST_RELEASED: {			mstr = "just released";		} break;	}	return PropertyInfo(Variant::BOOL, mstr);}String VisualScriptInputAction::get_caption() const {	return vformat(RTR("Action %s"), name);}String VisualScriptInputAction::get_category() const {	return "data";}void VisualScriptInputAction::set_action_name(const StringName &p_name) {	if (name == p_name) {		return;	}	name = p_name;	ports_changed_notify();}StringName VisualScriptInputAction::get_action_name() const {	return name;}void VisualScriptInputAction::set_action_mode(Mode p_mode) {	if (mode == p_mode) {		return;	}	mode = p_mode;	ports_changed_notify();}VisualScriptInputAction::Mode VisualScriptInputAction::get_action_mode() const {	return mode;}class VisualScriptNodeInstanceInputAction : public VisualScriptNodeInstance {public:	VisualScriptInstance *instance = nullptr;	StringName action;	VisualScriptInputAction::Mode mode;	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		switch (mode) {			case VisualScriptInputAction::MODE_PRESSED: {				*p_outputs[0] = Input::get_singleton()->is_action_pressed(action);			} break;			case VisualScriptInputAction::MODE_RELEASED: {				*p_outputs[0] = !Input::get_singleton()->is_action_pressed(action);			} break;			case VisualScriptInputAction::MODE_JUST_PRESSED: {				*p_outputs[0] = Input::get_singleton()->is_action_just_pressed(action);			} break;			case VisualScriptInputAction::MODE_JUST_RELEASED: {				*p_outputs[0] = Input::get_singleton()->is_action_just_released(action);			} break;		}		return 0;	}};VisualScriptNodeInstance *VisualScriptInputAction::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceInputAction *instance = memnew(VisualScriptNodeInstanceInputAction);	instance->instance = p_instance;	instance->action = name;	instance->mode = mode;	return instance;}void VisualScriptInputAction::_validate_property(PropertyInfo &property) const {	if (property.name == "action") {		property.hint = PROPERTY_HINT_ENUM;		String actions;		List<PropertyInfo> pinfo;		ProjectSettings::get_singleton()->get_property_list(&pinfo);		Vector<String> al;		for (const PropertyInfo &pi : pinfo) {			if (!pi.name.begins_with("input/")) {				continue;			}			String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());			al.push_back(name);		}		al.sort();		for (int i = 0; i < al.size(); i++) {			if (!actions.is_empty()) {				actions += ",";			}			actions += al[i];		}		property.hint_string = actions;	}}void VisualScriptInputAction::_bind_methods() {	ClassDB::bind_method(D_METHOD("set_action_name", "name"), &VisualScriptInputAction::set_action_name);	ClassDB::bind_method(D_METHOD("get_action_name"), &VisualScriptInputAction::get_action_name);	ClassDB::bind_method(D_METHOD("set_action_mode", "mode"), &VisualScriptInputAction::set_action_mode);	ClassDB::bind_method(D_METHOD("get_action_mode"), &VisualScriptInputAction::get_action_mode);	ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), "set_action_name", "get_action_name");	ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Pressed,Released,JustPressed,JustReleased"), "set_action_mode", "get_action_mode");	BIND_ENUM_CONSTANT(MODE_PRESSED);	BIND_ENUM_CONSTANT(MODE_RELEASED);	BIND_ENUM_CONSTANT(MODE_JUST_PRESSED);	BIND_ENUM_CONSTANT(MODE_JUST_RELEASED);}VisualScriptInputAction::VisualScriptInputAction() {	name = "";	mode = MODE_PRESSED;}//////////////////////////////////////////////////////////Constructor/////////////////////////////////////////////////////int VisualScriptDeconstruct::get_output_sequence_port_count() const {	return 0;}bool VisualScriptDeconstruct::has_input_sequence_port() const {	return false;}int VisualScriptDeconstruct::get_input_value_port_count() const {	return 1;}int VisualScriptDeconstruct::get_output_value_port_count() const {	return elements.size();}String VisualScriptDeconstruct::get_output_sequence_port_text(int p_port) const {	return "";}PropertyInfo VisualScriptDeconstruct::get_input_value_port_info(int p_idx) const {	return PropertyInfo(type, "value");}PropertyInfo VisualScriptDeconstruct::get_output_value_port_info(int p_idx) const {	return PropertyInfo(elements[p_idx].type, elements[p_idx].name);}String VisualScriptDeconstruct::get_caption() const {	return vformat(RTR("Deconstruct %s"), Variant::get_type_name(type));}String VisualScriptDeconstruct::get_category() const {	return "functions";}void VisualScriptDeconstruct::_update_elements() {	elements.clear();	Variant v;	Callable::CallError ce;	Variant::construct(type, v, nullptr, 0, ce);	List<PropertyInfo> pinfo;	v.get_property_list(&pinfo);	for (const PropertyInfo &E : pinfo) {		Element e;		e.name = E.name;		e.type = E.type;		elements.push_back(e);	}}void VisualScriptDeconstruct::set_deconstruct_type(Variant::Type p_type) {	if (type == p_type) {		return;	}	type = p_type;	_update_elements();	ports_changed_notify();	notify_property_list_changed(); //to make input appear/disappear}Variant::Type VisualScriptDeconstruct::get_deconstruct_type() const {	return type;}void VisualScriptDeconstruct::_set_elem_cache(const Array &p_elements) {	ERR_FAIL_COND(p_elements.size() % 2 == 1);	elements.resize(p_elements.size() / 2);	for (int i = 0; i < elements.size(); i++) {		elements.write[i].name = p_elements[i * 2 + 0];		elements.write[i].type = Variant::Type(int(p_elements[i * 2 + 1]));	}}Array VisualScriptDeconstruct::_get_elem_cache() const {	Array ret;	for (int i = 0; i < elements.size(); i++) {		ret.push_back(elements[i].name);		ret.push_back(elements[i].type);	}	return ret;}class VisualScriptNodeInstanceDeconstruct : public VisualScriptNodeInstance {public:	VisualScriptInstance *instance = nullptr;	Vector<StringName> outputs;	//virtual int get_working_memory_size() const override { return 0; }	virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {		Variant in = *p_inputs[0];		for (int i = 0; i < outputs.size(); i++) {			bool valid;			*p_outputs[i] = in.get(outputs[i], &valid);			if (!valid) {				r_error_str = "Can't obtain element '" + String(outputs[i]) + "' from " + Variant::get_type_name(in.get_type());				r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;				return 0;			}		}		return 0;	}};VisualScriptNodeInstance *VisualScriptDeconstruct::instantiate(VisualScriptInstance *p_instance) {	VisualScriptNodeInstanceDeconstruct *instance = memnew(VisualScriptNodeInstanceDeconstruct);	instance->instance = p_instance;	instance->outputs.resize(elements.size());	for (int i = 0; i < elements.size(); i++) {		instance->outputs.write[i] = elements[i].name;	}	return instance;}void VisualScriptDeconstruct::_validate_property(PropertyInfo &property) const {}void VisualScriptDeconstruct::_bind_methods() {	ClassDB::bind_method(D_METHOD("set_deconstruct_type", "type"), &VisualScriptDeconstruct::set_deconstruct_type);	ClassDB::bind_method(D_METHOD("get_deconstruct_type"), &VisualScriptDeconstruct::get_deconstruct_type);	ClassDB::bind_method(D_METHOD("_set_elem_cache", "_cache"), &VisualScriptDeconstruct::_set_elem_cache);	ClassDB::bind_method(D_METHOD("_get_elem_cache"), &VisualScriptDeconstruct::_get_elem_cache);	String argt = "Any";	for (int i = 1; i < Variant::VARIANT_MAX; i++) {		argt += "," + Variant::get_type_name(Variant::Type(i));	}	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_deconstruct_type", "get_deconstruct_type");	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "elem_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_elem_cache", "_get_elem_cache");}VisualScriptDeconstruct::VisualScriptDeconstruct() {	type = Variant::NIL;}template <Variant::Type T>static Ref<VisualScriptNode> create_node_deconst_typed(const String &p_name) {	Ref<VisualScriptDeconstruct> node;	node.instantiate();	node->set_deconstruct_type(T);	return node;}void register_visual_script_nodes() {	VisualScriptLanguage::singleton->add_register_func("data/set_variable", create_node_generic<VisualScriptVariableSet>);	VisualScriptLanguage::singleton->add_register_func("data/get_variable", create_node_generic<VisualScriptVariableGet>);	VisualScriptLanguage::singleton->add_register_func("data/engine_singleton", create_node_generic<VisualScriptEngineSingleton>);	VisualScriptLanguage::singleton->add_register_func("data/scene_node", create_node_generic<VisualScriptSceneNode>);	VisualScriptLanguage::singleton->add_register_func("data/scene_tree", create_node_generic<VisualScriptSceneTree>);	VisualScriptLanguage::singleton->add_register_func("data/resource_path", create_node_generic<VisualScriptResourcePath>);	VisualScriptLanguage::singleton->add_register_func("data/self", create_node_generic<VisualScriptSelf>);	VisualScriptLanguage::singleton->add_register_func("data/comment", create_node_generic<VisualScriptComment>);	VisualScriptLanguage::singleton->add_register_func("data/get_local_variable", create_node_generic<VisualScriptLocalVar>);	VisualScriptLanguage::singleton->add_register_func("data/set_local_variable", create_node_generic<VisualScriptLocalVarSet>);	VisualScriptLanguage::singleton->add_register_func("data/preload", create_node_generic<VisualScriptPreload>);	VisualScriptLanguage::singleton->add_register_func("data/action", create_node_generic<VisualScriptInputAction>);	VisualScriptLanguage::singleton->add_register_func("constants/constant", create_node_generic<VisualScriptConstant>);	VisualScriptLanguage::singleton->add_register_func("constants/math_constant", create_node_generic<VisualScriptMathConstant>);	VisualScriptLanguage::singleton->add_register_func("constants/class_constant", create_node_generic<VisualScriptClassConstant>);	VisualScriptLanguage::singleton->add_register_func("constants/global_constant", create_node_generic<VisualScriptGlobalConstant>);	VisualScriptLanguage::singleton->add_register_func("constants/basic_type_constant", create_node_generic<VisualScriptBasicTypeConstant>);	VisualScriptLanguage::singleton->add_register_func("custom/custom_node", create_node_generic<VisualScriptCustomNode>);	VisualScriptLanguage::singleton->add_register_func("custom/sub_call", create_node_generic<VisualScriptSubCall>);	VisualScriptLanguage::singleton->add_register_func("index/get_index", create_node_generic<VisualScriptIndexGet>);	VisualScriptLanguage::singleton->add_register_func("index/set_index", create_node_generic<VisualScriptIndexSet>);	VisualScriptLanguage::singleton->add_register_func("operators/compare/equal", create_op_node<Variant::OP_EQUAL>);	VisualScriptLanguage::singleton->add_register_func("operators/compare/not_equal", create_op_node<Variant::OP_NOT_EQUAL>);	VisualScriptLanguage::singleton->add_register_func("operators/compare/less", create_op_node<Variant::OP_LESS>);	VisualScriptLanguage::singleton->add_register_func("operators/compare/less_equal", create_op_node<Variant::OP_LESS_EQUAL>);	VisualScriptLanguage::singleton->add_register_func("operators/compare/greater", create_op_node<Variant::OP_GREATER>);	VisualScriptLanguage::singleton->add_register_func("operators/compare/greater_equal", create_op_node<Variant::OP_GREATER_EQUAL>);	//mathematic	VisualScriptLanguage::singleton->add_register_func("operators/math/add", create_op_node<Variant::OP_ADD>);	VisualScriptLanguage::singleton->add_register_func("operators/math/subtract", create_op_node<Variant::OP_SUBTRACT>);	VisualScriptLanguage::singleton->add_register_func("operators/math/multiply", create_op_node<Variant::OP_MULTIPLY>);	VisualScriptLanguage::singleton->add_register_func("operators/math/divide", create_op_node<Variant::OP_DIVIDE>);	VisualScriptLanguage::singleton->add_register_func("operators/math/negate", create_op_node<Variant::OP_NEGATE>);	VisualScriptLanguage::singleton->add_register_func("operators/math/positive", create_op_node<Variant::OP_POSITIVE>);	VisualScriptLanguage::singleton->add_register_func("operators/math/remainder", create_op_node<Variant::OP_MODULE>);	//bitwise	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/shift_left", create_op_node<Variant::OP_SHIFT_LEFT>);	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/shift_right", create_op_node<Variant::OP_SHIFT_RIGHT>);	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_and", create_op_node<Variant::OP_BIT_AND>);	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_or", create_op_node<Variant::OP_BIT_OR>);	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_xor", create_op_node<Variant::OP_BIT_XOR>);	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_negate", create_op_node<Variant::OP_BIT_NEGATE>);	//logic	VisualScriptLanguage::singleton->add_register_func("operators/logic/and", create_op_node<Variant::OP_AND>);	VisualScriptLanguage::singleton->add_register_func("operators/logic/or", create_op_node<Variant::OP_OR>);	VisualScriptLanguage::singleton->add_register_func("operators/logic/xor", create_op_node<Variant::OP_XOR>);	VisualScriptLanguage::singleton->add_register_func("operators/logic/not", create_op_node<Variant::OP_NOT>);	VisualScriptLanguage::singleton->add_register_func("operators/logic/in", create_op_node<Variant::OP_IN>);	VisualScriptLanguage::singleton->add_register_func("operators/logic/select", create_node_generic<VisualScriptSelect>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2), create_node_deconst_typed<Variant::Type::VECTOR2>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2I), create_node_deconst_typed<Variant::Type::VECTOR2I>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3), create_node_deconst_typed<Variant::Type::VECTOR3>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3I), create_node_deconst_typed<Variant::Type::VECTOR3I>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR4), create_node_deconst_typed<Variant::Type::VECTOR4>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR4I), create_node_deconst_typed<Variant::Type::VECTOR4I>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::COLOR), create_node_deconst_typed<Variant::Type::COLOR>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2), create_node_deconst_typed<Variant::Type::RECT2>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2I), create_node_deconst_typed<Variant::Type::RECT2I>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM2D), create_node_deconst_typed<Variant::Type::TRANSFORM2D>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PLANE), create_node_deconst_typed<Variant::Type::PLANE>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::QUATERNION), create_node_deconst_typed<Variant::Type::QUATERNION>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::AABB), create_node_deconst_typed<Variant::Type::AABB>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::BASIS), create_node_deconst_typed<Variant::Type::BASIS>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM3D), create_node_deconst_typed<Variant::Type::TRANSFORM3D>);	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PROJECTION), create_node_deconst_typed<Variant::Type::PROJECTION>);	VisualScriptLanguage::singleton->add_register_func("functions/compose_array", create_node_generic<VisualScriptComposeArray>);	for (int i = 1; i < Variant::VARIANT_MAX; i++) {		List<MethodInfo> constructors;		Variant::get_constructor_list(Variant::Type(i), &constructors);		for (const MethodInfo &E : constructors) {			if (E.arguments.size() > 0) {				String name = "functions/constructors/" + Variant::get_type_name(Variant::Type(i)) + "(";				for (int j = 0; j < E.arguments.size(); j++) {					if (j > 0) {						name += ", ";					}					if (E.arguments.size() == 1) {						name += Variant::get_type_name(E.arguments[j].type);					} else {						name += E.arguments[j].name;					}				}				name += ")";				VisualScriptLanguage::singleton->add_register_func(name, create_constructor_node);				Pair<Variant::Type, MethodInfo> pair;				pair.first = Variant::Type(i);				pair.second = E;				constructor_map[name] = pair;			}		}	}}void unregister_visual_script_nodes() {	constructor_map.clear();}
 |