summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/map.hpp14
-rw-r--r--src/map/pc.cpp8
-rw-r--r--src/map/pc.hpp8
-rw-r--r--src/map/script-call-internal.hpp18
-rw-r--r--src/map/script-call.cpp87
-rw-r--r--src/map/script-fun.cpp272
-rw-r--r--src/map/script-parse.cpp5
7 files changed, 339 insertions, 73 deletions
diff --git a/src/map/map.hpp b/src/map/map.hpp
index a2d0f5d..72d5dd3 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -77,6 +77,13 @@ struct block_list
short bl_x, bl_y;
BL bl_type;
+ // register keys are ints (interned)
+ // Not anymore! Well, sort of.
+ DMap<SIR, int> regm;
+ // can't be DMap because we want predictable .c_str()s
+ // TODO this can change now
+ Map<SIR, RString> regstrm;
+
// This deletes the copy-ctor also
// TODO give proper ctors.
block_list& operator = (block_list&&) = delete;
@@ -251,13 +258,6 @@ struct map_session_data : block_list, SessionData
int die_counter;
- // register keys are ints (interned)
- // Not anymore! Well, sort of.
- DMap<SIR, int> regm;
- // can't be DMap because we want predictable .c_str()s
- // TODO this can change now
- Map<SIR, RString> regstrm;
-
earray<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
AccountId trade_partner;
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 7f7512c..f65e2b4 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -3814,7 +3814,7 @@ int pc_changelook(dumb_ptr<map_session_data> sd, LOOK type, int val)
* script用変数の値を読む
*------------------------------------------
*/
-int pc_readreg(dumb_ptr<map_session_data> sd, SIR reg)
+int pc_readreg(dumb_ptr<block_list> sd, SIR reg)
{
nullpo_retz(sd);
@@ -3825,7 +3825,7 @@ int pc_readreg(dumb_ptr<map_session_data> sd, SIR reg)
* script用変数の値を設定
*------------------------------------------
*/
-void pc_setreg(dumb_ptr<map_session_data> sd, SIR reg, int val)
+void pc_setreg(dumb_ptr<block_list> sd, SIR reg, int val)
{
nullpo_retv(sd);
@@ -3836,7 +3836,7 @@ void pc_setreg(dumb_ptr<map_session_data> sd, SIR reg, int val)
* script用文字列変数の値を読む
*------------------------------------------
*/
-ZString pc_readregstr(dumb_ptr<map_session_data> sd, SIR reg)
+ZString pc_readregstr(dumb_ptr<block_list> sd, SIR reg)
{
nullpo_retr(ZString(), sd);
@@ -3848,7 +3848,7 @@ ZString pc_readregstr(dumb_ptr<map_session_data> sd, SIR reg)
* script用文字列変数の値を設定
*------------------------------------------
*/
-void pc_setregstr(dumb_ptr<map_session_data> sd, SIR reg, RString str)
+void pc_setregstr(dumb_ptr<block_list> sd, SIR reg, RString str)
{
nullpo_retv(sd);
diff --git a/src/map/pc.hpp b/src/map/pc.hpp
index 3a35330..6bcfadb 100644
--- a/src/map/pc.hpp
+++ b/src/map/pc.hpp
@@ -144,10 +144,10 @@ int pc_changelook(dumb_ptr<map_session_data>, LOOK, int);
int pc_readparam(dumb_ptr<map_session_data>, SP);
int pc_setparam(dumb_ptr<map_session_data>, SP, int);
-int pc_readreg(dumb_ptr<map_session_data>, SIR);
-void pc_setreg(dumb_ptr<map_session_data>, SIR, int);
-ZString pc_readregstr(dumb_ptr<map_session_data> sd, SIR reg);
-void pc_setregstr(dumb_ptr<map_session_data> sd, SIR reg, RString str);
+int pc_readreg(dumb_ptr<block_list>, SIR);
+void pc_setreg(dumb_ptr<block_list>, SIR, int);
+ZString pc_readregstr(dumb_ptr<block_list> sd, SIR reg);
+void pc_setregstr(dumb_ptr<block_list> sd, SIR reg, RString str);
void update_quest(dumb_ptr<map_session_data> sd, VarName quest_var, int value);
void update_allquest(dumb_ptr<map_session_data> sd);
int pc_readglobalreg(dumb_ptr<map_session_data>, VarName );
diff --git a/src/map/script-call-internal.hpp b/src/map/script-call-internal.hpp
index a887eb8..b3dfb5a 100644
--- a/src/map/script-call-internal.hpp
+++ b/src/map/script-call-internal.hpp
@@ -25,6 +25,8 @@
#include "../mmo/ids.hpp"
+#include "../strings/rstring.hpp"
+#include "../generic/db.hpp"
#include "script-persist.hpp"
@@ -55,6 +57,13 @@ public:
ScriptPointer scriptp, new_scriptp;
int defsp, new_defsp, freeloop;
int is_true = 0;
+
+ // register keys are ints (interned)
+ // Not anymore! Well, sort of.
+ DMap<SIR, int> regm;
+ // can't be DMap because we want predictable .c_str()s
+ // TODO this can change now
+ Map<SIR, RString> regstrm;
};
void run_func(ScriptState *st);
@@ -70,13 +79,14 @@ enum class ScriptEndState
};
dumb_ptr<map_session_data> script_rid2sd(ScriptState *st);
-void get_val(dumb_ptr<map_session_data> sd, struct script_data *data);
+void get_val(dumb_ptr<block_list> sd, struct script_data *data);
__attribute__((deprecated))
void get_val(ScriptState *st, struct script_data *data);
struct script_data get_val2(ScriptState *st, SIR reg);
-void set_reg(dumb_ptr<map_session_data> sd, VariableCode type, SIR reg, struct script_data vd);
-void set_reg(dumb_ptr<map_session_data> sd, VariableCode type, SIR reg, int id);
-void set_reg(dumb_ptr<map_session_data> sd, VariableCode type, SIR reg, RString zd);
+void set_scope_reg(ScriptState *, SIR, struct script_data);
+void set_reg(dumb_ptr<block_list> sd, VariableCode type, SIR reg, struct script_data vd);
+void set_reg(dumb_ptr<block_list> sd, VariableCode type, SIR reg, int id);
+void set_reg(dumb_ptr<block_list> sd, VariableCode type, SIR reg, RString zd);
__attribute__((warn_unused_result))
RString conv_str(ScriptState *st, struct script_data *data);
__attribute__((warn_unused_result))
diff --git a/src/map/script-call.cpp b/src/map/script-call.cpp
index b8f531a..2ebfca3 100644
--- a/src/map/script-call.cpp
+++ b/src/map/script-call.cpp
@@ -78,7 +78,7 @@ dumb_ptr<map_session_data> script_rid2sd(ScriptState *st)
* 変数の読み取り
*------------------------------------------
*/
-void get_val(dumb_ptr<map_session_data> sd, struct script_data *data)
+void get_val(dumb_ptr<block_list> sd, struct script_data *data)
{
MATCH_BEGIN (*data)
{
@@ -88,7 +88,7 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data)
PRINTF("get_val error param SP::%d\n"_fmt, u.reg.sp());
int numi = 0;
if (sd)
- numi = pc_readparam(sd, u.reg.sp());
+ numi = pc_readparam(sd->is_player(), u.reg.sp());
*data = ScriptDataInt{numi};
}
MATCH_CASE (const ScriptDataVariable&, u)
@@ -106,7 +106,7 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data)
if (postfix == '$')
{
RString str;
- if (prefix == '@')
+ if (prefix == '@' || prefix == '.')
{
if (sd)
str = pc_readregstr(sd, u.reg);
@@ -130,7 +130,7 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data)
else
{
int numi = 0;
- if (prefix == '@')
+ if (prefix == '@' || prefix == '.')
{
if (sd)
numi = pc_readreg(sd, u.reg);
@@ -144,18 +144,18 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data)
if (name[1] == '#')
{
if (sd)
- numi = pc_readaccountreg2(sd, name);
+ numi = pc_readaccountreg2(sd->is_player(), name);
}
else
{
if (sd)
- numi = pc_readaccountreg(sd, name);
+ numi = pc_readaccountreg(sd->is_player(), name);
}
}
else
{
if (sd)
- numi = pc_readglobalreg(sd, name);
+ numi = pc_readglobalreg(sd->is_player(), name);
}
*data = ScriptDataInt{numi};
}
@@ -166,8 +166,38 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data)
void get_val(ScriptState *st, struct script_data *data)
{
- dumb_ptr<map_session_data> sd = st->rid ? map_id2sd(st->rid) : nullptr;
- get_val(sd, data);
+ dumb_ptr<block_list> bl = nullptr;
+ MATCH_BEGIN (*data)
+ {
+ MATCH_CASE (const ScriptDataParam&, u)
+ {
+ bl = map_id2bl(st->rid);
+ }
+ MATCH_CASE (const ScriptDataVariable&, u)
+ {
+ ZString name_ = variable_names.outtern(u.reg.base());
+ VarName name = stringish<VarName>(name_);
+ char prefix = name.front();
+ if (prefix == '.' && name[1] == '@')
+ {
+ if (name.back() == '$')
+ {
+ Option<P<RString>> s = st->regstrm.search(u.reg);
+ ZString val = s.map([](P<RString> s_) -> ZString { return *s_; }).copy_or(""_s);
+ *data = ScriptDataStr{val};
+ }
+ else
+ *data = ScriptDataInt{st->regm.get(u.reg)};
+ return;
+ }
+ if (prefix == '.' && st->oid)
+ bl = map_id2bl(st->oid);
+ else if (prefix != '$' && st->rid)
+ bl = map_id2bl(st->rid);
+ }
+ }
+ MATCH_END ();
+ get_val(bl, data);
}
/*==========================================
@@ -185,12 +215,12 @@ struct script_data get_val2(ScriptState *st, SIR reg)
* 変数設定用
*------------------------------------------
*/
-void set_reg(dumb_ptr<map_session_data> sd, VariableCode type, SIR reg, struct script_data vd)
+void set_reg(dumb_ptr<block_list> sd, VariableCode type, SIR reg, struct script_data vd)
{
if (type == VariableCode::PARAM)
{
int val = vd.get_if<ScriptDataInt>()->numi;
- pc_setparam(sd, reg.sp(), val);
+ pc_setparam(sd->is_player(), reg.sp(), val);
return;
}
assert (type == VariableCode::VARIABLE);
@@ -203,7 +233,7 @@ void set_reg(dumb_ptr<map_session_data> sd, VariableCode type, SIR reg, struct s
if (postfix == '$')
{
RString str = vd.get_if<ScriptDataStr>()->str;
- if (prefix == '@')
+ if (prefix == '@' || prefix == '.')
{
pc_setregstr(sd, reg, str);
}
@@ -219,7 +249,7 @@ void set_reg(dumb_ptr<map_session_data> sd, VariableCode type, SIR reg, struct s
else
{
int val = vd.get_if<ScriptDataInt>()->numi;
- if (prefix == '@')
+ if (prefix == '@' || prefix == '.')
{
pc_setreg(sd, reg, val);
}
@@ -230,24 +260,45 @@ void set_reg(dumb_ptr<map_session_data> sd, VariableCode type, SIR reg, struct s
else if (prefix == '#')
{
if (name[1] == '#')
- pc_setaccountreg2(sd, name, val);
+ pc_setaccountreg2(sd->is_player(), name, val);
else
- pc_setaccountreg(sd, name, val);
+ pc_setaccountreg(sd->is_player(), name, val);
}
else
{
- pc_setglobalreg(sd, name, val);
+ pc_setglobalreg(sd->is_player(), name, val);
+ }
+ }
+}
+
+void set_scope_reg(ScriptState *st, SIR reg, struct script_data vd)
+{
+ ZString name = variable_names.outtern(reg.base());
+ if (name.back() == '$')
+ {
+ if (auto *u = vd.get_if<ScriptDataStr>())
+ {
+ if (!u->str)
+ {
+ st->regstrm.erase(reg);
+ return;
+ }
+ st->regstrm.insert(reg, u->str);
}
+ else
+ st->regstrm.erase(reg);
}
+ else if (auto *u = vd.get_if<ScriptDataInt>())
+ st->regm.put(reg, u->numi);
}
-void set_reg(dumb_ptr<map_session_data> sd, VariableCode type, SIR reg, int id)
+void set_reg(dumb_ptr<block_list> sd, VariableCode type, SIR reg, int id)
{
struct script_data vd = ScriptDataInt{id};
set_reg(sd, type, reg, vd);
}
-void set_reg(dumb_ptr<map_session_data> sd, VariableCode type, SIR reg, RString zd)
+void set_reg(dumb_ptr<block_list> sd, VariableCode type, SIR reg, RString zd)
{
struct script_data vd = ScriptDataStr{zd};
set_reg(sd, type, reg, vd);
diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp
index 4ef6499..f215d73 100644
--- a/src/map/script-fun.cpp
+++ b/src/map/script-fun.cpp
@@ -780,7 +780,7 @@ void builtin_foreach(ScriptState *st)
*----------------------------------------
*/
static
-void builtin_destroypuppet(ScriptState *st)
+void builtin_destroy(ScriptState *st)
{
BlockId id;
if (HARG(0))
@@ -909,37 +909,116 @@ void builtin_puppet(ScriptState *st)
static
void builtin_set(ScriptState *st)
{
- dumb_ptr<map_session_data> sd = nullptr;
+ BlockId id;
+ dumb_ptr<block_list> bl = nullptr;
if (auto *u = AARG(0).get_if<ScriptDataParam>())
{
SIR reg = u->reg;
- sd = script_rid2sd(st);
+ if(HARG(2))
+ {
+ struct script_data *sdata = &AARG(2);
+ get_val(st, sdata);
+ CharName name;
+ if (sdata->is<ScriptDataStr>())
+ {
+ name = stringish<CharName>(ZString(conv_str(st, sdata)));
+ if (name.to__actual())
+ bl = map_nick2sd(name);
+ }
+ else
+ {
+ id = wrap<BlockId>(conv_num(st, sdata));
+ bl = map_id2bl(id);
+ }
+ }
+
+ else
+ bl = script_rid2sd(st)->is_player();
+ if (bl == nullptr)
+ return;
int val = conv_num(st, &AARG(1));
- set_reg(sd, VariableCode::PARAM, reg, val);
+ set_reg(bl, VariableCode::PARAM, reg, val);
return;
}
SIR reg = AARG(0).get_if<ScriptDataVariable>()->reg;
ZString name = variable_names.outtern(reg.base());
- char prefix = name.front();
- char postfix = name.back();
+ VarName name_ = stringish<VarName>(name);
+ char prefix = name_.front();
+ char postfix = name_.back();
if (prefix != '$')
- sd = script_rid2sd(st);
+ {
+ if(HARG(2))
+ {
+ struct script_data *sdata = &AARG(2);
+ get_val(st, sdata);
+ if(prefix == '.')
+ {
+ if (name_[1] == '@')
+ {
+ PRINTF("builtin_set: illegal scope!\n"_fmt);
+ return;
+ }
+ NpcName n_name;
+ if (sdata->is<ScriptDataStr>())
+ {
+ n_name = stringish<NpcName>(ZString(conv_str(st, sdata)));
+ bl = npc_name2id(n_name);
+ }
+ else
+ {
+ id = wrap<BlockId>(conv_num(st, sdata));
+ bl = map_id2bl(id);
+ }
+ }
+ else
+ {
+ CharName c_name;
+ if (sdata->is<ScriptDataStr>())
+ {
+ c_name = stringish<CharName>(ZString(conv_str(st, sdata)));
+ if (c_name.to__actual())
+ bl = map_nick2sd(c_name);
+ }
+ else
+ {
+ id = wrap<BlockId>(conv_num(st, sdata));
+ bl = map_id2bl(id);
+ }
+ }
+ }
+ else
+ {
+ if(prefix == '.')
+ {
+ if (name_[1] == '@')
+ {
+ set_scope_reg(st, reg, AARG(1));
+ return;
+ }
+ bl = map_id2bl(st->oid)->is_npc();
+ }
+ else
+ bl = map_id2bl(st->rid)->is_player();
+ }
+ if (bl == nullptr)
+ return;
+ }
if (postfix == '$')
{
// 文字列
RString str = conv_str(st, &AARG(1));
- set_reg(sd, VariableCode::VARIABLE, reg, str);
+ set_reg(bl, VariableCode::VARIABLE, reg, str);
}
else
{
// 数値
int val = conv_num(st, &AARG(1));
- set_reg(sd, VariableCode::VARIABLE, reg, val);
+ set_reg(bl, VariableCode::VARIABLE, reg, val);
}
}
@@ -951,26 +1030,30 @@ void builtin_set(ScriptState *st)
static
void builtin_setarray(ScriptState *st)
{
- dumb_ptr<map_session_data> sd = nullptr;
+ dumb_ptr<block_list> bl = nullptr;
SIR reg = AARG(0).get_if<ScriptDataVariable>()->reg;
ZString name = variable_names.outtern(reg.base());
char prefix = name.front();
char postfix = name.back();
- if (prefix != '$' && prefix != '@')
+ if (prefix != '$' && prefix != '@' && prefix != '.')
{
PRINTF("builtin_setarray: illegal scope!\n"_fmt);
return;
}
- if (prefix != '$')
- sd = script_rid2sd(st);
+ if (prefix == '.' && name[1] != '@')
+ bl = map_id2bl(st->oid)->is_npc();
+ else if (prefix != '$')
+ bl = map_id2bl(st->rid)->is_player();
for (int j = 0, i = 1; i < st->end - st->start - 2 && j < 256; i++, j++)
{
- if (postfix == '$')
- set_reg(sd, VariableCode::VARIABLE, reg.iplus(j), conv_str(st, &AARG(i)));
+ if (prefix == '.' && name[1] == '@')
+ set_scope_reg(st, reg.iplus(j), AARG(i));
+ else if (postfix == '$')
+ set_reg(bl, VariableCode::VARIABLE, reg.iplus(j), conv_str(st, &AARG(i)));
else
- set_reg(sd, VariableCode::VARIABLE, reg.iplus(j), conv_num(st, &AARG(i)));
+ set_reg(bl, VariableCode::VARIABLE, reg.iplus(j), conv_num(st, &AARG(i)));
}
}
@@ -981,27 +1064,31 @@ void builtin_setarray(ScriptState *st)
static
void builtin_cleararray(ScriptState *st)
{
- dumb_ptr<map_session_data> sd = nullptr;
+ dumb_ptr<block_list> bl = nullptr;
SIR reg = AARG(0).get_if<ScriptDataVariable>()->reg;
ZString name = variable_names.outtern(reg.base());
char prefix = name.front();
char postfix = name.back();
int sz = conv_num(st, &AARG(2));
- if (prefix != '$' && prefix != '@')
+ if (prefix != '$' && prefix != '@' && prefix != '.')
{
PRINTF("builtin_cleararray: illegal scope!\n"_fmt);
return;
}
- if (prefix != '$')
- sd = script_rid2sd(st);
+ if (prefix == '.' && name[1] != '@')
+ bl = map_id2bl(st->oid)->is_npc();
+ else if (prefix != '$')
+ bl = map_id2bl(st->rid)->is_player();
for (int i = 0; i < sz; i++)
{
- if (postfix == '$')
- set_reg(sd, VariableCode::VARIABLE, reg.iplus(i), conv_str(st, &AARG(1)));
+ if (prefix == '.' && name[1] == '@')
+ set_scope_reg(st, reg.iplus(i), AARG(i));
+ else if (postfix == '$')
+ set_reg(bl, VariableCode::VARIABLE, reg.iplus(i), conv_str(st, &AARG(1)));
else
- set_reg(sd, VariableCode::VARIABLE, reg.iplus(i), conv_num(st, &AARG(1)));
+ set_reg(bl, VariableCode::VARIABLE, reg.iplus(i), conv_num(st, &AARG(1)));
}
}
@@ -1045,7 +1132,7 @@ void builtin_getarraysize(ScriptState *st)
ZString name = variable_names.outtern(reg.base());
char prefix = name.front();
- if (prefix != '$' && prefix != '@')
+ if (prefix != '$' && prefix != '@' && prefix != '.')
{
PRINTF("builtin_copyarray: illegal scope!\n"_fmt);
return;
@@ -2908,7 +2995,7 @@ void builtin_getpartnerid2(ScriptState *st)
static
void builtin_explode(ScriptState *st)
{
- dumb_ptr<map_session_data> sd = nullptr;
+ dumb_ptr<block_list> bl = nullptr;
SIR reg = AARG(0).get_if<ScriptDataVariable>()->reg;
ZString name = variable_names.outtern(reg.base());
const char separator = conv_str(st, &AARG(2))[0];
@@ -2917,33 +3004,49 @@ void builtin_explode(ScriptState *st)
char prefix = name.front();
char postfix = name.back();
- if (prefix != '$' && prefix != '@')
+ if (prefix != '$' && prefix != '@' && prefix != '.')
{
PRINTF("builtin_explode: illegal scope!\n"_fmt);
return;
}
- if (prefix != '$')
- sd = script_rid2sd(st);
+ if (prefix == '.' && name[1] != '@')
+ bl = map_id2bl(st->oid)->is_npc();
+ else if (prefix != '$' && prefix != '.')
+ bl = map_id2bl(st->rid)->is_player();
for (int j = 0; j < 256; j++)
{
auto find = std::find(str.begin(), str.end(), separator);
if (find == str.end())
{
- if (postfix == '$')
- set_reg(sd, VariableCode::VARIABLE, reg.iplus(j), str);
+ if (prefix == '.' && name[1] == '@')
+ {
+ struct script_data vd = script_data(ScriptDataInt{atoi(str.c_str())});
+ if (postfix == '$')
+ vd = script_data(ScriptDataStr{str});
+ set_scope_reg(st, reg.iplus(j), &vd);
+ }
+ else if (postfix == '$')
+ set_reg(bl, VariableCode::VARIABLE, reg.iplus(j), str);
else
- set_reg(sd, VariableCode::VARIABLE, reg.iplus(j), atoi(str.c_str()));
+ set_reg(bl, VariableCode::VARIABLE, reg.iplus(j), atoi(str.c_str()));
break;
}
{
val = str.xislice_h(find);
str = str.xislice_t(find + 1);
- if (postfix == '$')
- set_reg(sd, VariableCode::VARIABLE, reg.iplus(j), val);
+ if (prefix == '.' && name[1] == '@')
+ {
+ struct script_data vd = script_data(ScriptDataInt{atoi(val.c_str())});
+ if (postfix == '$')
+ vd = script_data(ScriptDataStr{val});
+ set_scope_reg(st, reg.iplus(j), &vd);
+ }
+ else if (postfix == '$')
+ set_reg(bl, VariableCode::VARIABLE, reg.iplus(j), val);
else
- set_reg(sd, VariableCode::VARIABLE, reg.iplus(j), atoi(val.c_str()));
+ set_reg(bl, VariableCode::VARIABLE, reg.iplus(j), atoi(val.c_str()));
}
}
}
@@ -3149,6 +3252,102 @@ void builtin_specialeffect2(ScriptState *st)
}
+static
+void builtin_get(ScriptState *st)
+{
+ BlockId id;
+ dumb_ptr<block_list> bl = nullptr;
+ if (auto *u = AARG(0).get_if<ScriptDataParam>())
+ {
+ SIR reg = u->reg;
+ struct script_data *sdata = &AARG(1);
+ get_val(st, sdata);
+ CharName name;
+ if (sdata->is<ScriptDataStr>())
+ {
+ name = stringish<CharName>(ZString(conv_str(st, sdata)));
+ if (name.to__actual())
+ bl = map_nick2sd(name);
+ }
+ else
+ {
+ id = wrap<BlockId>(conv_num(st, sdata));
+ bl = map_id2bl(id);
+ }
+
+ if (bl == nullptr)
+ return;
+ int var = pc_readparam(bl->is_player(), reg.sp());
+ push_int<ScriptDataInt>(st->stack, var);
+ return;
+ }
+
+ struct script_data *sdata = &AARG(1);
+ get_val(st, sdata);
+
+ SIR reg = AARG(0).get_if<ScriptDataVariable>()->reg;
+ ZString name_ = variable_names.outtern(reg.base());
+ char prefix = name_.front();
+ char postfix = name_.back();
+
+ if(prefix == '.')
+ {
+ if (name_[1] == '@')
+ {
+ PRINTF("builtin_get: illegal scope!\n"_fmt);
+ return;
+ }
+ NpcName name;
+ if (sdata->is<ScriptDataStr>())
+ {
+ name = stringish<NpcName>(ZString(conv_str(st, sdata)));
+ bl = npc_name2id(name);
+ }
+ else
+ {
+ id = wrap<BlockId>(conv_num(st, sdata));
+ bl = map_id2bl(id);
+ }
+ }
+ else if(prefix != '$')
+ {
+ CharName name;
+ if (sdata->is<ScriptDataStr>())
+ {
+ name = stringish<CharName>(ZString(conv_str(st, sdata)));
+ if (name.to__actual())
+ bl = map_nick2sd(name);
+ }
+ else
+ {
+ id = wrap<BlockId>(conv_num(st, sdata));
+ bl = map_id2bl(id);
+ }
+ }
+ else
+ {
+ PRINTF("builtin_get: illegal scope !\n"_fmt);
+ return;
+ }
+
+ if (!bl)
+ {
+ PRINTF("builtin_get: no block list attached !\n"_fmt);
+ return;
+ }
+
+ if (postfix == '$')
+ {
+ ZString var = pc_readregstr(bl, reg);
+ push_str<ScriptDataStr>(st->stack, var);
+ }
+ else
+ {
+ int var = pc_readreg(bl, reg);
+ push_int<ScriptDataInt>(st->stack, var);
+ }
+}
+
/*==========================================
* Nude [Valaris]
*------------------------------------------
@@ -3859,7 +4058,8 @@ BuiltinFunction builtin_functions[] =
BUILTIN(if, "iF*"_s, '\0'),
BUILTIN(elif, "iF*"_s, '\0'),
BUILTIN(else, "F*"_s, '\0'),
- BUILTIN(set, "Ne"_s, '\0'),
+ BUILTIN(set, "Ne?"_s, '\0'),
+ BUILTIN(get, "Ne"_s, '.'),
BUILTIN(setarray, "Ne*"_s, '\0'),
BUILTIN(cleararray, "Nei"_s, '\0'),
BUILTIN(getarraysize, "N"_s, 'i'),
@@ -3968,7 +4168,7 @@ BuiltinFunction builtin_functions[] =
BUILTIN(aggravate, "Mxyxyi"_s, '\0'),
BUILTIN(fakenpcname, "ssi"_s, '\0'),
BUILTIN(puppet, "mxysi"_s, 'i'),
- BUILTIN(destroypuppet, "?"_s, '\0'),
+ BUILTIN(destroy, "?"_s, '\0'),
BUILTIN(getx, ""_s, 'i'),
BUILTIN(gety, ""_s, 'i'),
BUILTIN(getnpcx, "?"_s, 'i'),
diff --git a/src/map/script-parse.cpp b/src/map/script-parse.cpp
index a785748..a69df40 100644
--- a/src/map/script-parse.cpp
+++ b/src/map/script-parse.cpp
@@ -283,6 +283,10 @@ ZString::iterator skip_word(ZString::iterator p)
p++; // MAP鯖内共有変数用
if (*p == '@')
p++; // 一時的変数用(like weiss)
+ if (*p == '.')
+ p++; // npc
+ if (*p == '@')
+ p++; // scope
if (*p == '#')
p++; // account変数用
if (*p == '#')
@@ -623,6 +627,7 @@ ZString::iterator ScriptBuffer::parse_line(ZString::iterator p, bool *can_step)
"end"_s,
"mapexit"_s,
"shop"_s,
+ "destroy"_s,
};
*can_step = terminators.count(cmd->strs) == 0;
}