diff options
author | Haru <haru@dotalux.com> | 2018-08-24 23:17:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-24 23:17:03 +0200 |
commit | f8ef0e08bdf620c69db72c04196256895b55ea3c (patch) | |
tree | 28c71f88eb7f64f6301a166e280c6a1a4f0cd3ce | |
parent | dbfe2391f4481cb88dac3c86902a58e71cf22920 (diff) | |
parent | 2452b21bead32ee545731fd00b48f1cbc2a1ec11 (diff) | |
download | hercules-f8ef0e08bdf620c69db72c04196256895b55ea3c.tar.gz hercules-f8ef0e08bdf620c69db72c04196256895b55ea3c.tar.bz2 hercules-f8ef0e08bdf620c69db72c04196256895b55ea3c.tar.xz hercules-f8ef0e08bdf620c69db72c04196256895b55ea3c.zip |
Merge pull request #2154 from mekolat/isfunction
improve is_function()
-rw-r--r-- | doc/script_commands.txt | 27 | ||||
-rw-r--r-- | src/map/script.c | 52 |
2 files changed, 68 insertions, 11 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 10b4e5653..d5e9d79f2 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -1976,18 +1976,35 @@ prontera,150,150,0 script TestNPC 123,{ *is_function("<function name>") -This command checks whether a function exists. -It returns 1 if function is found, or 0 if it isn't. +This command checks whether or not a function exists and returns its type. +Returns false if it cannot be found. + +return values: + + FUNCTION_IS_COMMAND - built-in script command (eg: mes, select, ...) + FUNCTION_IS_GLOBAL - user-defined global function (callable with callfunc) + FUNCTION_IS_LOCAL - user-defined local function + FUNCTION_IS_LABEL - user-defined label function (callable with callsub) Example: - function script try { + function script func1 { dothat(); } - script test FAKE_NPC,{ - .@try = is_function("try"); // 1 - .@not = is_function("notafunction"); // 0 + function func2 { + do_something(); + } + + func3: + end; + + is_function("func1"); // FUNCTION_IS_GLOBAL + is_function("func2"); // FUNCTION_IS_LOCAL + is_function("func3"); // FUNCTION_IS_LABEL + is_function("select"); // FUNCTION_IS_COMMAND + is_function("invalid"); // false } --------------------------------------- diff --git a/src/map/script.c b/src/map/script.c index 846075c0e..cba844c1a 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -22471,18 +22471,52 @@ static BUILDIN(getcharip) return true; } +enum function_type { + FUNCTION_IS_NONE = 0, + FUNCTION_IS_COMMAND, + FUNCTION_IS_GLOBAL, + FUNCTION_IS_LOCAL, + FUNCTION_IS_LABEL, +}; + /** - * is_function(<function name>) -> 1 if function exists, 0 otherwise + * is_function(<function name>) **/ static BUILDIN(is_function) { - const char* str = script_getstr(st,2); + const char *str = script_getstr(st, 2); + enum function_type type = FUNCTION_IS_NONE; - if( strdb_exists(script->userfunc_db, str) ) - script_pushint(st,1); - else - script_pushint(st,0); + // TODO: add support for exported functions (#2142) + + if (strdb_exists(script->userfunc_db, str)) { + type = FUNCTION_IS_GLOBAL; + } else { + int n = script->search_str(str); + + if (n >= 0) { + switch (script->str_data[n].type) { + case C_FUNC: + type = FUNCTION_IS_COMMAND; + break; + case C_USERFUNC: + case C_USERFUNC_POS: + type = FUNCTION_IS_LOCAL; + break; + case C_POS: + type = FUNCTION_IS_LABEL; + break; + case C_NAME: + if (script->str_data[n].label >= 0) { + // WTF... ? + // for some reason local functions can have type C_NAME + type = FUNCTION_IS_LOCAL; + } + } + } + } + script_pushint(st, type); return true; } @@ -25781,6 +25815,12 @@ static void script_hardcoded_constants(void) script->set_constant("QINFO_HOMUN_TYPE", QINFO_HOMUN_TYPE, false, false); script->set_constant("QINFO_QUEST", QINFO_QUEST, false, false); + script->constdb_comment("function types"); + script->set_constant("FUNCTION_IS_COMMAND", FUNCTION_IS_COMMAND, false, false); + script->set_constant("FUNCTION_IS_GLOBAL", FUNCTION_IS_GLOBAL, false, false); + script->set_constant("FUNCTION_IS_LOCAL", FUNCTION_IS_LOCAL, false, false); + script->set_constant("FUNCTION_IS_LABEL", FUNCTION_IS_LABEL, false, false); + script->constdb_comment("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); |