summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map/clif.cpp2
-rw-r--r--src/map/globals.cpp1
-rw-r--r--src/map/globals.hpp1
-rw-r--r--src/map/npc.cpp69
-rw-r--r--src/map/npc.hpp1
-rw-r--r--src/map/script-fun.cpp19
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'),