summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2018-08-24 23:17:03 +0200
committerGitHub <noreply@github.com>2018-08-24 23:17:03 +0200
commitf8ef0e08bdf620c69db72c04196256895b55ea3c (patch)
tree28c71f88eb7f64f6301a166e280c6a1a4f0cd3ce
parentdbfe2391f4481cb88dac3c86902a58e71cf22920 (diff)
parent2452b21bead32ee545731fd00b48f1cbc2a1ec11 (diff)
downloadhercules-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.txt27
-rw-r--r--src/map/script.c52
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);