summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/constants.md7
-rw-r--r--doc/script_commands.txt27
-rw-r--r--src/map/achievement.c2
-rw-r--r--src/map/script.c52
-rw-r--r--src/map/skill.c6
5 files changed, 82 insertions, 12 deletions
diff --git a/doc/constants.md b/doc/constants.md
index a64d75152..ead85314d 100644
--- a/doc/constants.md
+++ b/doc/constants.md
@@ -4302,6 +4302,13 @@
- `QINFO_HOMUN_TYPE`: 6
- `QINFO_QUEST`: 7
+### function types
+
+- `FUNCTION_IS_COMMAND`: 1
+- `FUNCTION_IS_GLOBAL`: 2
+- `FUNCTION_IS_LOCAL`: 3
+- `FUNCTION_IS_LABEL`: 4
+
### Renewal
- `RENEWAL`: 1
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 414a72924..c5c58b991 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/achievement.c b/src/map/achievement.c
index 6abdb74ee..fe2c685b5 100644
--- a/src/map/achievement.c
+++ b/src/map/achievement.c
@@ -733,7 +733,7 @@ static void achievement_validate_zeny(struct map_session_data *sd, int amount)
achievement->validate_type(sd, ACH_ZENY_GET_ONCE, &criteria, false);
achievement->validate_type(sd, ACH_ZENY_GET_TOTAL, &criteria, true);
} else {
- criteria.goal = amount;
+ criteria.goal = -amount;
achievement->validate_type(sd, ACH_ZENY_SPEND_ONCE, &criteria, false);
achievement->validate_type(sd, ACH_ZENY_SPEND_TOTAL, &criteria, true);
}
diff --git a/src/map/script.c b/src/map/script.c
index 61059b811..c40137c55 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;
}
@@ -25821,6 +25855,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);
diff --git a/src/map/skill.c b/src/map/skill.c
index a4ebff9f1..7d47cfcb6 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2745,7 +2745,11 @@ static int skill_magic_reflect(struct block_list *src, struct block_list *bl, in
static int skill_attack(int attack_type, struct block_list *src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag)
{
struct Damage dmg;
+#if MAGIC_REFLECTION_TYPE
struct status_data *sstatus, *tstatus;
+#else
+ struct status_data *tstatus;
+#endif
struct status_change *sc;
struct map_session_data *sd, *tsd;
int type;
@@ -2780,7 +2784,9 @@ static int skill_attack(int attack_type, struct block_list *src, struct block_li
)
return 0;
+#if MAGIC_REFLECTION_TYPE
sstatus = status->get_status_data(src);
+#endif
tstatus = status->get_status_data(bl);
sc = status->get_sc(bl);
if (sc && !sc->count) sc = NULL; //Don't need it.