diff options
-rw-r--r-- | src/map/clif.cpp | 2 | ||||
-rw-r--r-- | src/map/globals.cpp | 1 | ||||
-rw-r--r-- | src/map/globals.hpp | 1 | ||||
-rw-r--r-- | src/map/npc.cpp | 69 | ||||
-rw-r--r-- | src/map/npc.hpp | 1 | ||||
-rw-r--r-- | src/map/script-fun.cpp | 19 |
6 files changed, 91 insertions, 2 deletions
diff --git a/src/map/clif.cpp b/src/map/clif.cpp index df21a88..a2a2a33 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -3842,7 +3842,7 @@ RecvResult clif_parse_GlobalMessage(Session *s, dumb_ptr<map_session_data> sd) if (is_atcommand(s, sd, mbuf, GmLevel())) return rv; - if (!magic::magic_message(sd, mbuf)) + if (!magic_message(sd, mbuf)) { /* Don't send chat that results in an automatic ban. */ if (tmw_CheckChatSpam(sd, mbuf)) diff --git a/src/map/globals.cpp b/src/map/globals.cpp index dce3906..4a54843 100644 --- a/src/map/globals.cpp +++ b/src/map/globals.cpp @@ -85,6 +85,7 @@ namespace tmwa BlockId npc_id = START_NPC_NUM; Map<NpcEvent, struct event_data> ev_db; DMap<NpcName, dumb_ptr<npc_data>> npcs_by_name; + DMap<RString, NpcEvent> spells_by_name; // used for clock-based event triggers // only tm_min, tm_hour, and tm_mday are used tm ev_tm_b = diff --git a/src/map/globals.hpp b/src/map/globals.hpp index b457b4e..5a4ec82 100644 --- a/src/map/globals.hpp +++ b/src/map/globals.hpp @@ -79,6 +79,7 @@ namespace tmwa extern BlockId npc_id; extern Map<NpcEvent, event_data> ev_db; extern DMap<NpcName, dumb_ptr<npc_data>> npcs_by_name; + extern DMap<RString, NpcEvent> spells_by_name; extern tm ev_tm_b; extern Map<PartyId, PartyMost> party_db; extern std::map<AccountId, GmLevel> gm_accountm; diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 1707c1c..0175916 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -146,6 +146,75 @@ dumb_ptr<npc_data> npc_name2id(NpcName name) } /*========================================== + * NPCを名前で探す + *------------------------------------------ + */ +NpcEvent spell_name2id(RString name) +{ + return spells_by_name.get(name); +} + +/*========================================== + * Spell Toknise + * Return a pair of strings, {spellname, parameter} + * Parameter may be empty. + *------------------------------------------ + */ +static +std::pair<XString, XString> magic_tokenise(XString src) +{ + auto seeker = std::find(src.begin(), src.end(), ' '); + + if (seeker == src.end()) + { + return {src, XString()}; + } + else + { + XString rv1 = src.xislice_h(seeker); + ++seeker; + + while (seeker != src.end() && *seeker == ' ') + ++seeker; + + // Note: this very well could be empty + XString rv2 = src.xislice_t(seeker); + return {rv1, rv2}; + } +} + +/*========================================== + * NPC Spell + *------------------------------------------ + */ +int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation) +{ + if (pc_isdead(caster)) + return 0; + if (bool(caster->status.option & Opt0::HIDE)) + return 0; + if (caster->cast_tick > gettick()) + return 0; + + auto pair = magic_tokenise(source_invocation); + // Spell Cast + NpcName spell_name = stringish<NpcName>(pair.first); + RString spell_params = pair.second; + + NpcEvent event = spell_name2id(spell_name); + + if (event) + { + PRINTF("Cast: %s\n"_fmt, spell_name); + PRINTF("event: %s\n"_fmt, event); + PRINTF("Params: %s\n"_fmt, spell_params); + npc_event(caster, event, 0); + return 1; + } + return 0; +} + +/*========================================== * イベントキューのイベント処理 *------------------------------------------ */ diff --git a/src/map/npc.hpp b/src/map/npc.hpp index 7a96bf9..be4686a 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -58,6 +58,7 @@ dumb_ptr<npc_data> npc_name2id(NpcName name); BlockId npc_get_new_npc_id(void); +int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation); /** * Uninstalls and frees an NPC */ diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 9f9652e..35e119b 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -572,7 +572,7 @@ void builtin_injure(ScriptState *st) dumb_ptr<mob_data> mob = target->is_mob(); dumb_ptr<npc_data> nd = map_id_is_npc(st->oid); MAP_LOG_PC(caster_pc, "SPELLDMG MOB%d %d FOR %d BY %s"_fmt, - mob->bl_id, mob->mob_class, damage_caused, nd->name); + mob->bl_id, mob->mob_class, damage_caused, caster->is_player()->magic_attack); } } battle_damage(caster, target, damage_caused, mp_damage); @@ -3341,6 +3341,22 @@ void builtin_casttime(ScriptState *st) } /*========================================== + * register cmd + *------------------------------------------ + */ +static +void builtin_registercmd(ScriptState *st) +{ + dumb_ptr<npc_data> nd = map_id_is_npc(st->oid); + RString evoke = conv_str(st, &AARG(0)); + ZString event_ = conv_str(st, &AARG(1)); + NpcEvent event; + extract(event_, &event); + + spells_by_name.put(evoke, event); +} + +/*========================================== * getlook char info. getlook(arg) *------------------------------------------ */ @@ -3828,6 +3844,7 @@ BuiltinFunction builtin_functions[] = BUILTIN(message, "Ps"_s, '\0'), BUILTIN(npctalk, "ss?"_s, '\0'), BUILTIN(casttime, "i"_s, '\0'), + BUILTIN(registercmd, "sE"_s, '\0'), BUILTIN(title, "s"_s, '\0'), BUILTIN(smsg, "e??"_s, '\0'), BUILTIN(remotecmd, "s?"_s, '\0'), |