diff options
-rw-r--r-- | doc/constants.md | 7 | ||||
-rw-r--r-- | doc/script_commands.txt | 27 | ||||
-rw-r--r-- | src/map/achievement.c | 2 | ||||
-rw-r--r-- | src/map/script.c | 52 | ||||
-rw-r--r-- | src/map/skill.c | 6 |
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. |