diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.cpp | 2 | ||||
-rw-r--r-- | src/map/clif.cpp | 6 | ||||
-rw-r--r-- | src/map/fwd.hpp | 1 | ||||
-rw-r--r-- | src/map/map.hpp | 1 | ||||
-rw-r--r-- | src/map/map.t.hpp | 1 | ||||
-rw-r--r-- | src/map/mob.cpp | 13 | ||||
-rw-r--r-- | src/map/npc.cpp | 47 | ||||
-rw-r--r-- | src/map/pc.cpp | 19 | ||||
-rw-r--r-- | src/map/script-call.cpp | 20 | ||||
-rw-r--r-- | src/map/script-fun.cpp | 202 | ||||
-rw-r--r-- | src/map/script-parse.cpp | 1 |
11 files changed, 209 insertions, 104 deletions
diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 554ef14..031b79d 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -85,6 +85,8 @@ Species battle_get_class(dumb_ptr<block_list> bl) nullpo_retr(Species(), bl); if (bl->bl_type == BL::MOB) return bl->is_mob()->mob_class; + else if (bl->bl_type == BL::NPC) + return bl->is_npc()->npc_class; else if (bl->bl_type == BL::PC) return bl->is_player()->status.species; else diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 4cf1de2..ea11bbf 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -2550,7 +2550,9 @@ int clif_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst, nullpo_retz(src); nullpo_retz(dst); - sc_data = battle_get_sc_data(dst); + int target_hp = battle_get_hp(dst); + if (target_hp < damage) + damage = target_hp; // limit damage to hp Packet_Fixed<0x008a> fixed_8a; fixed_8a.src_id = src->bl_id; @@ -4423,6 +4425,8 @@ RecvResult clif_parse_NpcClicked(Session *s, dumb_ptr<map_session_data> sd) } if (sd->npc_id) return rv; + if (battle_get_class(map_id2bl(fixed.block_id)) == INVISIBLE_CLASS) + return rv; npc_click(sd, fixed.block_id); return rv; diff --git a/src/map/fwd.hpp b/src/map/fwd.hpp index de65216..74e0ccf 100644 --- a/src/map/fwd.hpp +++ b/src/map/fwd.hpp @@ -61,7 +61,6 @@ struct map_local; class npc_data_script; class npc_data_shop; class npc_data_warp; -class npc_data_message; struct item_data; struct quest_data; diff --git a/src/map/map.hpp b/src/map/map.hpp index 2919d04..25fdba5 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -332,7 +332,6 @@ struct npc_data : block_list Opt3 opt3; Opt0 option; short flag; - bool disposable; std::list<RString> eventqueuel; Array<Timer, MAX_EVENTTIMER> eventtimer; diff --git a/src/map/map.t.hpp b/src/map/map.t.hpp index ea7ead5..d685c01 100644 --- a/src/map/map.t.hpp +++ b/src/map/map.t.hpp @@ -49,7 +49,6 @@ enum class NpcSubtype : uint8_t WARP, SHOP, SCRIPT, - MESSAGE, COUNT, }; diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 1be40f0..0da946a 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -2701,7 +2701,6 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, } // [MouseJstr] // SCRIPT実行 - if (md->npc_event) { if (sd == nullptr) { @@ -2711,7 +2710,17 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, } } if (sd) - npc_event(sd, md->npc_event, 0); + { + if (md->npc_event) + npc_event(sd, md->npc_event, 0); + + // TODO: in the future, OnPCKillEvent, OnMobKillEvent and OnPCDieEvent should be combined + argrec_t arg[1] = + { + {"@mobID"_s, static_cast<int32_t>(unwrap<Species>(md->mob_class))}, + }; + npc_event_doall_l(stringish<ScriptLabel>("OnMobKillEvent"_s), sd->bl_id, arg); + } } clif_clearchar(md, BeingRemoveWhy::DEAD); diff --git a/src/map/npc.cpp b/src/map/npc.cpp index a8c90d8..5b0ee7b 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -202,23 +202,23 @@ int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation) auto pair = magic_tokenise(source_invocation); // Spell Cast NpcEvent spell_event = spell_event2id(pair.first); - PRINTF("Cast: %s\n"_fmt, RString(pair.first)); RString spell_params = pair.second; - dumb_ptr<npc_data> nd = npc_name2id(spell_event.npc); - - if (nd) + if (spell_event.npc) { - PRINTF("NPC: '%s' %d\n"_fmt, nd->name, nd->bl_id); - PRINTF("Params: '%s'\n"_fmt, spell_params); - argrec_t arg[1] = + dumb_ptr<npc_data> nd = npc_name2id(spell_event.npc); + + if (nd) { - {"@args$"_s, spell_params}, - }; + argrec_t arg[1] = + { + {"@args$"_s, spell_params}, + }; - npc_event(caster, spell_event, 0, arg); - return 1; + npc_event(caster, spell_event, 0, arg); + return 1; + } } return 0; } @@ -274,7 +274,7 @@ void npc_event_doall_sub(NpcEvent key, struct event_data *ev, if (name == p) { - if (ev->nd->disposable) + if (ev->nd->scr.parent != BlockId()) return; // temporary npcs only respond to commands directly issued to them run_script_l(ScriptPointer(script_or_parent(ev->nd), ev->pos), rid, ev->nd->bl_id, argv); @@ -647,7 +647,7 @@ int npc_event(dumb_ptr<map_session_data> sd, NpcEvent eventname, */ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, Borrowed<map_local> m, int x, int y) { - int i, f = 1; + int i; int xs, ys; nullpo_retr(1, sd); @@ -658,10 +658,7 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, Borrowed<map_local> m, int for (i = 0; i < m->npc_num; i++) { if (m->npc[i]->flag & 1) - { // 無効化されている - f = 0; continue; - } switch (m->npc[i]->npc_subtype) { @@ -684,11 +681,6 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, Borrowed<map_local> m, int } if (i == m->npc_num) { - if (f) - { - if (battle_config.error_log) - PRINTF("npc_touch_areanpc : some bug \n"_fmt); - } return 1; } switch (m->npc[i]->npc_subtype) @@ -1005,6 +997,19 @@ void npc_free_internal(dumb_ptr<npc_data> nd_) dumb_ptr<npc_data_script> nd = nd_->is_script(); nd->scr.timerid.cancel(); nd->scr.timer_eventv.clear(); + nd->eventqueuel.clear(); + for (int i = 0; i < MAX_EVENTTIMER; i++) + nd->eventtimer[i].cancel(); + + // destroy all children (puppets), if any + if (nd_->name && nd->scr.parent == BlockId()) + { + for (auto& pair : npcs_by_name) + if (pair.second->npc_subtype == NpcSubtype::SCRIPT + && pair.second->is_script()->scr.parent == nd_->bl_id) + npc_free(pair.second); + } + nd->scr.script.reset(); nd->scr.label_listv.clear(); } diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 929143c..db3b372 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -2731,7 +2731,8 @@ int pc_attack(dumb_ptr<map_session_data> sd, BlockId target_id, int type) if (bl->bl_type == BL::NPC) { // monster npcs [Valaris] - npc_click(sd, target_id); + if (battle_get_class(bl) != INVISIBLE_CLASS && !pc_isdead(sd)) + npc_click(sd, target_id); return 0; } @@ -3352,13 +3353,10 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd, if (src && src->bl_type == BL::PC) { // [Fate] PK death, trigger scripts - argrec_t arg[3] = + argrec_t arg[1] = { - {"@killerrid"_s, static_cast<int32_t>(unwrap<BlockId>(src->bl_id))}, {"@victimrid"_s, static_cast<int32_t>(unwrap<BlockId>(sd->bl_id))}, - {"@victimlvl"_s, sd->status.base_level}, }; - npc_event_doall_l(stringish<ScriptLabel>("OnPCKilledEvent"_s), sd->bl_id, arg); npc_event_doall_l(stringish<ScriptLabel>("OnPCKillEvent"_s), src->bl_id, arg); sd->state.pvp_rank = 0; @@ -3487,7 +3485,10 @@ int pc_readparam(dumb_ptr<block_list> bl, SP type) case SP::INT: case SP::DEX: case SP::LUK: - val = battle_get_stat(type, bl); + if (bl && bl->bl_type == BL::PC) + val = bl->is_player()->status.attrs[sp_to_attr(type)]; + else + val = battle_get_stat(type, bl); break; case SP::SPEED: val = battle_get_speed(bl).count(); @@ -3531,6 +3532,12 @@ int pc_readparam(dumb_ptr<block_list> bl, SP type) case SP::CHAR_ID: val = sd ? unwrap<CharId>(sd->status_key.char_id) : 0; break; + case SP::ELTLVL: + val = static_cast<int>(battle_get_element(sd).level); + break; + case SP::ELTTYPE: + val = static_cast<int>(battle_get_element(sd).element); + break; } return val; diff --git a/src/map/script-call.cpp b/src/map/script-call.cpp index fbb9b97..085d90a 100644 --- a/src/map/script-call.cpp +++ b/src/map/script-call.cpp @@ -908,7 +908,6 @@ void run_script_main(ScriptState *st, Borrowed<const ScriptBuffer> rootscript) if (st->state != ScriptEndState::END) { // 再開するためにスタック情報を保存 - dumb_ptr<map_session_data> sd = map_id2sd(st->rid); if (sd) { sd->npc_stackbuf = stack->stack_datav; @@ -938,17 +937,20 @@ int run_script_l(ScriptPointer sp, BlockId rid, BlockId oid, if (oid) { dumb_ptr<block_list> oid_bl = map_id2bl(oid); - if (oid_bl->bl_type == BL::NPC) + if (oid_bl) { - dumb_ptr<npc_data> nd = oid_bl->is_npc(); - if(nd->npc_subtype == NpcSubtype::SCRIPT) + if (oid_bl->bl_type == BL::NPC) { - dumb_ptr<npc_data_script> nds = nd->is_script(); - if (nds->scr.parent) + dumb_ptr<npc_data> nd = oid_bl->is_npc(); + if(nd->npc_subtype == NpcSubtype::SCRIPT) { - dumb_ptr<npc_data_script> parent = map_id2bl(nds->scr.parent)->is_npc()->is_script(); - assert(parent->bl_type == BL::NPC && parent->npc_subtype == NpcSubtype::SCRIPT); - sp = ScriptPointer(borrow(*parent->scr.script), sp.pos); + dumb_ptr<npc_data_script> nds = nd->is_script(); + if (nds->scr.parent) + { + dumb_ptr<npc_data_script> parent = map_id2bl(nds->scr.parent)->is_npc()->is_script(); + assert(parent->bl_type == BL::NPC && parent->npc_subtype == NpcSubtype::SCRIPT); + sp = ScriptPointer(borrow(*parent->scr.script), sp.pos); + } } } } diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index faa8c81..beabef3 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -472,14 +472,43 @@ void builtin_max(ScriptState *st) static void builtin_min(ScriptState *st) { - int min, num; - min = conv_num(st, &AARG(0)); + int min = 0xFFFFFFF6, num; - for (int i = 1; HARG(i); i++) + if (HARG(1)) { - num = conv_num(st, &AARG(i)); - if (num < min) - min = num; + min = conv_num(st, &AARG(0)); + for (int i = 1; HARG(i); i++) + { + num = conv_num(st, &AARG(i)); + if (num < min) + min = num; + } + } + else + { + SIR reg = AARG(0).get_if<ScriptDataVariable>()->reg; + ZString name = variable_names.outtern(reg.base()); + char prefix = name.front(); + if (prefix != '$' && prefix != '@' && prefix != '.') + { + PRINTF("builtin_max: illegal scope!\n"_fmt); + return; + } + for (int i = reg.index(); i < 256; i++) + { + struct script_data vd = get_val2(st, reg.iplus(i)); + MATCH_BEGIN (vd) + { + MATCH_CASE (const ScriptDataInt&, u) + { + if (u.numi < min) + min = u.numi; + continue; + } + } + MATCH_END (); + abort(); + } } push_int<ScriptDataInt>(st->stack, min); @@ -618,28 +647,6 @@ void builtin_heal(ScriptState *st) *------------------------------------------ */ static -void builtin_elttype(ScriptState *st) -{ - int element_type = static_cast<int>(battle_get_element(map_id2bl(wrap<BlockId>(conv_num(st, &AARG(0))))).element); - push_int<ScriptDataInt>(st->stack, element_type); -} - -/*========================================== - * - *------------------------------------------ - */ -static -void builtin_eltlvl(ScriptState *st) -{ - int element_lvl = static_cast<int>(battle_get_element(map_id2bl(wrap<BlockId>(conv_num(st, &AARG(0))))).level); - push_int<ScriptDataInt>(st->stack, element_lvl); -} - -/*========================================== - * - *------------------------------------------ - */ -static void builtin_distance(ScriptState *st) { dumb_ptr<block_list> source = map_id2bl(wrap<BlockId>(conv_num(st, &AARG(0)))); @@ -816,8 +823,7 @@ void builtin_requestitem(ScriptState *st) if (prefix != '$' && prefix != '@' && prefix != '.') { PRINTF("builtin_requestitem: illegal scope!\n"_fmt); - runflag = 0; - return; + abort(); } sd = script_rid2sd(st); @@ -867,7 +873,7 @@ void builtin_requestitem(ScriptState *st) RString item_name = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); if (item_name == ""_s) goto fail; - if (prefix == '.' && name[1] == '@') + if (name.startswith(".@"_s)) { struct script_data vd = script_data(ScriptDataStr{item_name}); set_scope_reg(st, reg.iplus(j), &vd); @@ -877,7 +883,7 @@ void builtin_requestitem(ScriptState *st) } else { - if (prefix == '.' && name[1] == '@') + if (name.startswith(".@"_s)) { struct script_data vd = script_data(ScriptDataInt{num}); set_scope_reg(st, reg.iplus(j), &vd); @@ -907,21 +913,19 @@ void builtin_requestlang(ScriptState *st) assert (scrd.is<ScriptDataVariable>()); SIR reg = scrd.get_if<ScriptDataVariable>()->reg; ZString name = variable_names.outtern(reg.base()); - char prefix = name.front(); char postfix = name.back(); if (postfix != '$') { PRINTF("builtin_requestlang: illegal type (expects string)!\n"_fmt); - runflag = 0; - return; + abort(); } if (sd->state.menu_or_input) { // Second time (rerunline) sd->state.menu_or_input = 0; - if (prefix == '.' && name[1] == '@') + if (name.startswith(".@"_s)) { struct script_data vd = script_data(ScriptDataStr{sd->npc_str}); set_scope_reg(st, reg, &vd); @@ -1102,7 +1106,7 @@ void builtin_destroy(ScriptState *st) dumb_ptr<npc_data_script> nd = map_id2bl(id)->is_npc()->is_script(); if(!nd) return; - assert(nd->disposable == true); + //assert(nd->disposable == true); we don't care about it anymore npc_free(nd); if (!HARG(0)) st->state = ScriptEndState::END; @@ -1131,11 +1135,9 @@ void builtin_puppet(ScriptState *st) nd->bl_prev = nd->bl_next = nullptr; nd->scr.event_needs_map = false; - nd->disposable = true; // allow to destroy // PlayerName::SpellName NpcName npc = stringish<NpcName>(ZString(conv_str(st, &AARG(3)))); - PRINTF("Npc: %s\n"_fmt, npc); nd->name = npc; // Dynamically set location @@ -1285,7 +1287,7 @@ void builtin_set(ScriptState *st) get_val(st, sdata); if(prefix == '.') { - if (name_[1] == '@') + if (name_.startswith(".@"_s)) { PRINTF("builtin_set: illegal scope!\n"_fmt); return; @@ -1322,7 +1324,7 @@ void builtin_set(ScriptState *st) { if(prefix == '.') { - if (name_[1] == '@') + if (name_.startswith(".@"_s)) { set_scope_reg(st, reg, &AARG(1)); return; @@ -1351,6 +1353,45 @@ void builtin_set(ScriptState *st) } +// this is a special function that returns array index for a variable stored in another being +static +int getarraysize2(SIR reg, dumb_ptr<block_list> bl) +{ + int i = reg.index(), c = i; + bool zero = true; // index zero is empty + for (; i < 256; i++) + { + struct script_data vd = ScriptDataVariable{reg.iplus(i)}; + get_val(bl, &vd); + MATCH_BEGIN (vd) + { + MATCH_CASE (const ScriptDataStr&, u) + { + if (u.str[0]) + { + if (i == 0) + zero = false; // index zero is not empty + c = i; + } + continue; + } + MATCH_CASE (const ScriptDataInt&, u) + { + if (u.numi) + { + if (i == 0) + zero = false; // index zero is not empty + c = i; + } + continue; + } + } + MATCH_END (); + abort(); + } + return (c == 0 && zero) ? c : (c + 1); +} + /*========================================== * 配列変数設定 *------------------------------------------ @@ -1363,20 +1404,51 @@ void builtin_setarray(ScriptState *st) ZString name = variable_names.outtern(reg.base()); char prefix = name.front(); char postfix = name.back(); + int i = 1, j = 0; if (prefix != '$' && prefix != '@' && prefix != '.') { PRINTF("builtin_setarray: illegal scope!\n"_fmt); return; } - if (prefix == '.' && name[1] != '@') - bl = map_id2bl(st->oid)->is_npc(); - else if (prefix != '$' && !(prefix == '.' && name[1] == '@')) + if (prefix == '.' && !name.startswith(".@"_s)) + { + struct script_data *sdata = &AARG(1); + get_val(st, sdata); + i++; // 2nd argument is npc, not an array element + if (sdata->is<ScriptDataStr>()) + { + ZString tn = conv_str(st, sdata); + if (tn == "this"_s || tn == "oid"_s) + bl = map_id2bl(st->oid)->is_npc(); + else + { + NpcName name_ = stringish<NpcName>(tn); + bl = npc_name2id(name_); + } + } + else + { + int tid = conv_num(st, sdata); + if (tid == 0) + bl = map_id2bl(st->oid)->is_npc(); + else + bl = map_id2bl(wrap<BlockId>(tid))->is_npc(); + } + if (!bl) + { + PRINTF("builtin_setarray: npc not found\n"_fmt); + return; + } + if (st->oid && bl->bl_id != st->oid) + j = getarraysize2(reg, bl); + } + else if (prefix != '$' && !name.startswith(".@"_s)) bl = map_id2bl(st->rid)->is_player(); - for (int j = 0, i = 1; i < st->end - st->start - 2 && j < 256; i++, j++) + for (; i < st->end - st->start - 2 && j < 256; i++, j++) { - if (prefix == '.' && name[1] == '@') + if (name.startswith(".@"_s)) 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))); @@ -1404,14 +1476,14 @@ void builtin_cleararray(ScriptState *st) PRINTF("builtin_cleararray: illegal scope!\n"_fmt); return; } - if (prefix == '.' && name[1] != '@') + if (prefix == '.' && !name.startswith(".@"_s)) bl = map_id2bl(st->oid)->is_npc(); - else if (prefix != '$' && !(prefix == '.' && name[1] == '@')) + else if (prefix != '$' && !name.startswith(".@"_s)) bl = map_id2bl(st->rid)->is_player(); for (int i = 0; i < sz; i++) { - if (prefix == '.' && name[1] == '@') + if (name.startswith(".@"_s)) 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))); @@ -2673,8 +2745,7 @@ void builtin_camera(ScriptState *st) { dumb_ptr<block_list> bl; short x = 0, y = 0; - int id; - bool rel; + bool rel = false; if (auto *u = AARG(0).get_if<ScriptDataInt>()) bl = map_id2bl(wrap<BlockId>(u->numi)); if (auto *g = AARG(0).get_if<ScriptDataStr>()) @@ -3109,7 +3180,13 @@ void builtin_resetstatus(ScriptState *st) static void builtin_attachrid(ScriptState *st) { - st->rid = wrap<BlockId>(conv_num(st, &AARG(0))); + dumb_ptr<map_session_data> sd = map_id2sd(st->rid); + BlockId newid = wrap<BlockId>(conv_num(st, &AARG(0))); + + if (sd && newid != st->rid) + sd->npc_id = BlockId(); + + st->rid = newid; push_int<ScriptDataInt>(st->stack, (map_id2sd(st->rid) != nullptr)); } @@ -3121,6 +3198,9 @@ void builtin_attachrid(ScriptState *st) static void builtin_detachrid(ScriptState *st) { + dumb_ptr<map_session_data> sd = map_id2sd(st->rid); + if (sd) + sd->npc_id = BlockId(); st->rid = BlockId(); } @@ -3433,7 +3513,7 @@ void builtin_chr(ScriptState *st) static void builtin_ord(ScriptState *st) { - const char ascii = conv_str(st, &AARG(0))[0]; + const char ascii = conv_str(st, &AARG(0)).front(); push_int<ScriptDataInt>(st->stack, static_cast<int>(ascii)); } @@ -3443,7 +3523,7 @@ void builtin_explode(ScriptState *st) 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]; + const char separator = conv_str(st, &AARG(2)).front(); RString str = conv_str(st, &AARG(1)); RString val; char prefix = name.front(); @@ -3454,7 +3534,7 @@ void builtin_explode(ScriptState *st) PRINTF("builtin_explode: illegal scope!\n"_fmt); return; } - if (prefix == '.' && name[1] != '@') + if (prefix == '.' && !name.startswith(".@"_s)) bl = map_id2bl(st->oid)->is_npc(); else if (prefix != '$' && prefix != '.') bl = map_id2bl(st->rid)->is_player(); @@ -3464,7 +3544,7 @@ void builtin_explode(ScriptState *st) auto find = std::find(str.begin(), str.end(), separator); if (find == str.end()) { - if (prefix == '.' && name[1] == '@') + if (name.startswith(".@"_s)) { struct script_data vd = script_data(ScriptDataInt{atoi(str.c_str())}); if (postfix == '$') @@ -3481,7 +3561,7 @@ void builtin_explode(ScriptState *st) val = str.xislice_h(find); str = str.xislice_t(find + 1); - if (prefix == '.' && name[1] == '@') + if (name.startswith(".@"_s)) { struct script_data vd = script_data(ScriptDataInt{atoi(val.c_str())}); if (postfix == '$') @@ -3749,7 +3829,7 @@ void builtin_get(ScriptState *st) if(prefix == '.') { - if (name_[1] == '@') + if (name_.startswith(".@"_s)) { PRINTF("builtin_get: illegal scope!\n"_fmt); return; @@ -3807,7 +3887,7 @@ void builtin_get(ScriptState *st) int var; if (prefix == '#' && bl) { - if (name_[1] == '#') + if (name_.startswith("##"_s)) var = pc_readaccountreg2(bl->is_player(), stringish<VarName>(name_)); else var = pc_readaccountreg(bl->is_player(), stringish<VarName>(name_)); @@ -4546,8 +4626,6 @@ BuiltinFunction builtin_functions[] = BUILTIN(warp, "Mxy"_s, '\0'), BUILTIN(areawarp, "MxyxyMxy"_s, '\0'), BUILTIN(heal, "ii?"_s, '\0'), - BUILTIN(elttype, "i"_s, 'i'), - BUILTIN(eltlvl, "i"_s, 'i'), BUILTIN(injure, "iii"_s, '\0'), BUILTIN(input, "N"_s, '\0'), BUILTIN(requestitem, "N?"_s, '\0'), @@ -4680,7 +4758,7 @@ BuiltinFunction builtin_functions[] = BUILTIN(freeloop, "i"_s, '\0'), BUILTIN(if_then_else, "iii"_s, '.'), BUILTIN(max, "e?*"_s, 'i'), - BUILTIN(min, "ii*"_s, 'i'), + BUILTIN(min, "e?*"_s, 'i'), BUILTIN(average, "ii*"_s, 'i'), BUILTIN(sqrt, "i"_s, 'i'), BUILTIN(cbrt, "i"_s, 'i'), diff --git a/src/map/script-parse.cpp b/src/map/script-parse.cpp index a69df40..f8d7b6b 100644 --- a/src/map/script-parse.cpp +++ b/src/map/script-parse.cpp @@ -617,6 +617,7 @@ ZString::iterator ScriptBuffer::parse_line(ZString::iterator p, bool *can_step) { // TODO should be LString, but no heterogenous lookup yet + // FIXME / TODO: allow destroy to both be a statement and a terminator static std::set<ZString> terminators = { |