From 7b3453a4e1c3bb7c0d7dcc0c8b075f8bbdb8e65b Mon Sep 17 00:00:00 2001 From: mekolat Date: Wed, 28 Oct 2015 21:06:51 -0400 Subject: add builtin_call and builtin_getarg --- src/map/script-call.cpp | 2 +- src/map/script-fun.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/src/map/script-call.cpp b/src/map/script-call.cpp index 0164c2a..a669b59 100644 --- a/src/map/script-call.cpp +++ b/src/map/script-call.cpp @@ -728,7 +728,7 @@ void run_func(ScriptState *st) st->defsp = conv_num(st, &st->stack->stack_datav[olddefsp - 3]); // 基準スタックポインタを復元 // Number of arguments. int i = conv_num(st, &st->stack->stack_datav[olddefsp - 4]); // 引数の数所得 - assert (i == 0); + //assert (i == 0); pop_stack(st->stack, olddefsp - 4 - i, olddefsp); // 要らなくなったスタック(引数と復帰用データ)削除 diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index f59ba55..ccf8f11 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -131,7 +131,6 @@ void builtin_callfunc(ScriptState *st) for (int i = st->start + 3; i < st->end; i++, j++) push_copy(st->stack, i); #endif - push_int(st->stack, j); // 引数の数をプッシュ push_int(st->stack, st->defsp); // 現在の基準スタックポインタをプッシュ push_int(st->stack, st->scriptp.pos); // 現在のスクリプト位置をプッシュ @@ -151,6 +150,85 @@ void builtin_callfunc(ScriptState *st) OMATCH_END (); } +static +void builtin_call(ScriptState *st) +{ + struct script_data *sdata = &AARG(0); + get_val(st, sdata); + RString str; + if (sdata->is()) + { + str = conv_str(st, sdata); + Option> scr_ = userfunc_db.get(str); + OMATCH_BEGIN (scr_) + { + OMATCH_CASE_SOME (scr) + { + int j = 0; + + for (int i = st->start + 3; i < st->end; i++, j++) + push_copy(st->stack, i); + + push_int(st->stack, j); // 引数の数をプッシュ + push_int(st->stack, st->defsp); // 現在の基準スタックポインタをプッシュ + push_int(st->stack, st->scriptp.pos); // 現在のスクリプト位置をプッシュ + push_script(st->stack, TRY_UNWRAP(st->scriptp.code, abort())); // 現在のスクリプトをプッシュ + + st->scriptp = ScriptPointer(scr, 0); + st->defsp = st->start + 4 + j; + st->state = ScriptEndState::GOTO; + return; + } + OMATCH_CASE_NONE () + { + PRINTF("fatal: script: callfunc: function not found! [%s]\n"_fmt, str); + st->state = ScriptEndState::END; + abort(); + } + } + OMATCH_END (); + } + else + { + int pos_ = conv_num(st, &AARG(0)); + int j = 0; + + for (int i = st->start + 3; i < st->end; i++, j++) + push_copy(st->stack, i); + + push_int(st->stack, j); // 引数の数をプッシュ + push_int(st->stack, st->defsp); // 現在の基準スタックポインタをプッシュ + push_int(st->stack, st->scriptp.pos); // 現在のスクリプト位置をプッシュ + push_script(st->stack, TRY_UNWRAP(st->scriptp.code, abort())); // 現在のスクリプトをプッシュ + + st->scriptp.pos = pos_; + st->defsp = st->start + 4 + j; + st->state = ScriptEndState::GOTO; + } + +} + +static +void builtin_getarg(ScriptState *st) +{ + int arg = conv_num(st, &AARG(0)); + if(st->defsp < 1 || !(st->stack->stack_datav[st->defsp - 1].is())) + { + dumb_ptr nd = map_id_is_npc(st->oid); + if(nd) + PRINTF("builtin_getarg: no callfunc or callsub! @ %s\n"_fmt, nd->name); + else + PRINTF("builtin_getarg: no callfunc or callsub! (no npc)\n"_fmt); + st->state = ScriptEndState::END; + return; + } + + int i = conv_num(st, &st->stack->stack_datav[st->defsp - 4]); // Number of arguments. + if (arg > i || arg < 0) + return; + push_copy(st->stack, (st->defsp - 4 - i) + arg); +} + /*========================================== * サブルーティンの呼び出し *------------------------------------------ @@ -191,12 +269,12 @@ void builtin_return(ScriptState *st) else PRINTF("Deprecated: return outside of callfunc or callsub! (no npc)\n"_fmt); } -#if 0 + if (HARG(0)) { // 戻り値有り push_copy(st->stack, st->start + 2); } -#endif + st->state = ScriptEndState::RETFUNC; } @@ -4236,8 +4314,10 @@ BuiltinFunction builtin_functions[] = BUILTIN(mes, "s"_s, '\0'), BUILTIN(goto, "L"_s, '\0'), BUILTIN(callfunc, "F"_s, '\0'), + BUILTIN(call, "F?*"_s, '.'), BUILTIN(callsub, "L"_s, '\0'), - BUILTIN(return, ""_s, '\0'), + BUILTIN(getarg, "i"_s, '.'), + BUILTIN(return, "?*"_s, '\0'), BUILTIN(next, ""_s, '\0'), BUILTIN(close, ""_s, '\0'), BUILTIN(close2, ""_s, '\0'), -- cgit v1.2.3-60-g2f50