summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorwushin <pasekei@gmail.com>2015-04-05 23:11:16 -0500
committerwushin <pasekei@gmail.com>2015-04-25 12:26:55 -0500
commit950bc8a1a239829864600b82e40d801514fca709 (patch)
tree3252c51e196bec00a441f3cade55d03a8dd75eec /src/map
parente6ee7b3f99935a594e6462472fdc9d075408da0f (diff)
downloadtmwa-950bc8a1a239829864600b82e40d801514fca709.tar.gz
tmwa-950bc8a1a239829864600b82e40d801514fca709.tar.bz2
tmwa-950bc8a1a239829864600b82e40d801514fca709.tar.xz
tmwa-950bc8a1a239829864600b82e40d801514fca709.zip
Add Bitmasked Quest Log
Diffstat (limited to 'src/map')
-rw-r--r--src/map/clif.cpp54
-rw-r--r--src/map/clif.hpp3
-rw-r--r--src/map/fwd.hpp1
-rw-r--r--src/map/globals.cpp2
-rw-r--r--src/map/globals.hpp1
-rw-r--r--src/map/map.cpp3
-rw-r--r--src/map/pc.cpp78
-rw-r--r--src/map/pc.hpp3
-rw-r--r--src/map/quest.cpp135
-rw-r--r--src/map/quest.hpp51
10 files changed, 322 insertions, 9 deletions
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index 577d7be..6a7f0ea 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -4671,6 +4671,60 @@ RecvResult clif_parse_PartyMessage(Session *s, dumb_ptr<map_session_data> sd)
return rv;
}
+void clif_sendallquest(dumb_ptr<map_session_data> sd)
+{
+ int i;
+ QuestId questid;
+ if (!sd)
+ return;
+
+ if (!sd->sess)
+ return;
+
+ Session *s = sd->sess;
+ Packet_Head<0x0215> head_215;
+ std::vector<Packet_Repeat<0x0215>> repeat_215;
+
+ assert (sd->status.global_reg_num < GLOBAL_REG_NUM);
+ for (QuestId q = wrap<QuestId>(0); q < wrap<QuestId>(-1); q = next(q))
+ {
+ P<struct quest_data> quest_data_ = TRY_UNWRAP(questdb_exists(q), continue);
+ for (i = 0; i < sd->status.global_reg_num; i++)
+ {
+ if (sd->status.global_reg[i].str == quest_data_->quest_vr)
+ {
+ int val = ((sd->status.global_reg[i].value & (((1 << quest_data_->quest_mask) - 1) << (quest_data_->quest_shift * quest_data_->quest_mask))) >> (quest_data_->quest_shift * quest_data_->quest_mask));
+ Packet_Repeat<0x0215> info;
+ info.variable = unwrap<QuestId>(quest_data_->questid);
+ info.value = val;
+ repeat_215.push_back(info);
+ break;
+ }
+ }
+ }
+
+ send_vpacket<0x0215, 4, 6>(s, head_215, repeat_215);
+ return;
+}
+
+void clif_sendquest(dumb_ptr<map_session_data> sd, QuestId questid, int value)
+{
+ if (!sd)
+ return;
+
+ if (!sd->sess)
+ return;
+
+ Session *s = sd->sess;
+
+ Packet_Fixed<0x0214> fixed;
+ fixed.variable = unwrap<QuestId>(questid);
+ fixed.value = value;
+ send_fpacket<0x0214, 8>(s, fixed);
+ return;
+}
+
+
func_table clif_parse_func_table[0x0220] =
{
{0, 10, nullptr, }, // 0x0000
diff --git a/src/map/clif.hpp b/src/map/clif.hpp
index 153cc7c..abbde04 100644
--- a/src/map/clif.hpp
+++ b/src/map/clif.hpp
@@ -174,6 +174,9 @@ int clif_GM_kick(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd,
int type);
int clif_foreachclient(std::function<void(dumb_ptr<map_session_data>)>);
+// quest
+void clif_sendallquest(dumb_ptr<map_session_data> sd);
+void clif_sendquest(dumb_ptr<map_session_data> sd, QuestId questid, int value);
void do_init_clif(void);
} // namespace map
diff --git a/src/map/fwd.hpp b/src/map/fwd.hpp
index 1db4ed0..911d566 100644
--- a/src/map/fwd.hpp
+++ b/src/map/fwd.hpp
@@ -65,6 +65,7 @@ class npc_data_warp;
class npc_data_message;
struct item_data;
+struct quest_data;
struct ScriptState;
struct str_data_t;
diff --git a/src/map/globals.cpp b/src/map/globals.cpp
index 09ff157..dce3906 100644
--- a/src/map/globals.cpp
+++ b/src/map/globals.cpp
@@ -26,6 +26,7 @@
#include "battle_conf.hpp"
#include "itemdb.hpp"
+#include "quest.hpp"
#include "magic-interpreter.hpp"
#include "map_conf.hpp"
#include "mob.hpp"
@@ -49,6 +50,7 @@ namespace tmwa
int chrif_state;
std::map<MapName, RString> resnametable;
Map<ItemNameId, item_data> item_db;
+ Map<QuestId, quest_data> quest_db;
namespace magic
{
// Global magic conf
diff --git a/src/map/globals.hpp b/src/map/globals.hpp
index 33cfec8..b457b4e 100644
--- a/src/map/globals.hpp
+++ b/src/map/globals.hpp
@@ -48,6 +48,7 @@ namespace tmwa
extern int chrif_state;
extern std::map<MapName, RString> resnametable;
extern Map<ItemNameId, item_data> item_db;
+ extern Map<QuestId, quest_data> quest_db;
namespace magic
{
// Global magic conf
diff --git a/src/map/map.cpp b/src/map/map.cpp
index d502fbb..c1d760a 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -74,6 +74,7 @@
#include "magic-v2.hpp"
#include "map_conf.hpp"
#include "mob.hpp"
+#include "quest.hpp"
#include "npc.hpp"
#include "npc-parse.hpp"
#include "party.hpp"
@@ -1489,6 +1490,8 @@ bool map_confs(io::Spanned<XString> key, io::Spanned<ZString> value)
return itemdb_readdb(value.data);
if (key.data == "mob_db"_s)
return mob_readdb(value.data);
+ if (key.data == "quest_db"_s)
+ return quest_readdb(value.data);
if (key.data == "mob_skill_db"_s)
return mob_readskilldb(value.data);
if (key.data == "skill_db"_s)
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 1e840ea..0a5df8a 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -64,6 +64,7 @@
#include "skill.hpp"
#include "storage.hpp"
#include "trade.hpp"
+#include "quest.hpp"
#include "../poison.hpp"
@@ -793,7 +794,8 @@ int pc_authok(AccountId id, int login_id2,
sd->packet_flood_in = 0;
pc_calcstatus(sd, 1);
-
+ // Init Quest Log
+ clif_sendallquest(sd);
return 0;
}
@@ -3827,14 +3829,37 @@ void pc_setregstr(dumb_ptr<map_session_data> sd, SIR reg, RString str)
int pc_readglobalreg(dumb_ptr<map_session_data> sd, VarName reg)
{
int i;
-
+ int quest_shift = 0;
+ int quest_mask = 0;
nullpo_retz(sd);
+ QuestId questid;
+ XString var = reg;
+ VarName vr;
assert (sd->status.global_reg_num < GLOBAL_REG_NUM);
+ Option<P<struct quest_data>> quest_data_ = questdb_searchname(var);
+ OMATCH_BEGIN_SOME(quest_data, quest_data_)
+ {
+ questid = quest_data->questid;
+ reg = quest_data->quest_vr;
+ vr = quest_data->quest_var;
+ quest_shift = quest_data->quest_shift;
+ quest_mask = quest_data->quest_mask;
+ }
+ OMATCH_END ();
for (i = 0; i < sd->status.global_reg_num; i++)
{
if (sd->status.global_reg[i].str == reg)
- return sd->status.global_reg[i].value;
+ {
+ if (questid)
+ {
+ return ((sd->status.global_reg[i].value & (((1 << quest_mask) - 1) << (quest_shift * quest_mask))) >> (quest_shift * quest_mask));
+ }
+ else
+ {
+ return sd->status.global_reg[i].value;
+ }
+ }
}
return 0;
@@ -3847,8 +3872,13 @@ int pc_readglobalreg(dumb_ptr<map_session_data> sd, VarName reg)
int pc_setglobalreg(dumb_ptr<map_session_data> sd, VarName reg, int val)
{
int i;
-
+ int quest_shift = 0;
+ int quest_mask = 0;
+ int bitval = val;
nullpo_retz(sd);
+ QuestId questid;
+ XString var = reg;
+ VarName vr;
//PC_DIE_COUNTERがスクリプトなどで変更された時の処理
if (reg == stringish<VarName>("PC_DIE_COUNTER"_s) && sd->die_counter != val)
@@ -3856,6 +3886,17 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, VarName reg, int val)
sd->die_counter = val;
pc_calcstatus(sd, 0);
}
+ Option<P<struct quest_data>> quest_data_ = questdb_searchname(var);
+ OMATCH_BEGIN_SOME(quest_data, quest_data_)
+ {
+ questid = quest_data->questid;
+ reg = quest_data->quest_vr;
+ vr = quest_data->quest_var;
+ quest_shift = quest_data->quest_shift;
+ quest_mask = quest_data->quest_mask;
+ assert (((1 << quest_mask) - 1) >= val);
+ }
+ OMATCH_END ();
assert (sd->status.global_reg_num < GLOBAL_REG_NUM);
if (val == 0)
{
@@ -3863,9 +3904,18 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, VarName reg, int val)
{
if (sd->status.global_reg[i].str == reg)
{
- sd->status.global_reg[i] =
- sd->status.global_reg[sd->status.global_reg_num - 1];
- sd->status.global_reg_num--;
+ if (questid)
+ {
+ bitval = ((sd->status.global_reg[i].value & ~(((1 << quest_mask) - 1) << (quest_shift * quest_mask))) | (val << (quest_shift * quest_mask)));
+ clif_sendquest(sd, questid, val);
+ }
+ sd->status.global_reg[i].value = bitval;
+ if (sd->status.global_reg[i].value == 0)
+ {
+ sd->status.global_reg[i] =
+ sd->status.global_reg[sd->status.global_reg_num - 1];
+ sd->status.global_reg_num--;
+ }
break;
}
}
@@ -3875,14 +3925,24 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, VarName reg, int val)
{
if (sd->status.global_reg[i].str == reg)
{
- sd->status.global_reg[i].value = val;
+ if (questid)
+ {
+ bitval = ((sd->status.global_reg[i].value & ~(((1 << quest_mask) - 1) << (quest_shift * quest_mask))) | (val << (quest_shift * quest_mask)));
+ clif_sendquest(sd, questid, val);
+ }
+ sd->status.global_reg[i].value = bitval;
return 0;
}
}
if (sd->status.global_reg_num < GLOBAL_REG_NUM)
{
sd->status.global_reg[i].str = reg;
- sd->status.global_reg[i].value = val;
+ if (questid)
+ {
+ bitval = ((sd->status.global_reg[i].value & ~(((1 << quest_mask) - 1) << (quest_shift * quest_mask))) | (val << (quest_shift * quest_mask)));
+ clif_sendquest(sd, questid, val);
+ }
+ sd->status.global_reg[i].value = bitval;
sd->status.global_reg_num++;
return 0;
}
diff --git a/src/map/pc.hpp b/src/map/pc.hpp
index 14829d1..6c0803f 100644
--- a/src/map/pc.hpp
+++ b/src/map/pc.hpp
@@ -28,6 +28,7 @@
#include "../mmo/clif.t.hpp"
#include "map.hpp"
+#include "quest.hpp"
namespace tmwa
@@ -146,6 +147,8 @@ 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);
+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 );
int pc_setglobalreg(dumb_ptr<map_session_data>, VarName , int);
int pc_readaccountreg(dumb_ptr<map_session_data>, VarName );
diff --git a/src/map/quest.cpp b/src/map/quest.cpp
new file mode 100644
index 0000000..dfe19ff
--- /dev/null
+++ b/src/map/quest.cpp
@@ -0,0 +1,135 @@
+#include "quest.hpp"
+// quest.cpp - Quest Log.
+//
+// Copyright © 2015 Ed Pasek <pasekei@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include <algorithm>
+
+#include "../strings/astring.hpp"
+#include "../strings/zstring.hpp"
+#include "../strings/xstring.hpp"
+
+#include "../generic/db.hpp"
+
+#include "../io/cxxstdio.hpp"
+#include "../io/extract.hpp"
+#include "../io/line.hpp"
+
+#include "../mmo/config_parse.hpp"
+#include "../mmo/extract_enums.hpp"
+
+#include "../ast/quest.hpp"
+
+#include "../poison.hpp"
+#include "globals.hpp"
+#include "script-parse.hpp"
+
+namespace tmwa
+{
+namespace map
+{
+// Function declarations
+
+static
+void questdb_searchname_sub(Borrowed<struct quest_data> quest, VarName str, Borrowed<Option<Borrowed<struct quest_data>>> dst)
+{
+ if (quest->quest_var == str)
+ *dst = Some(quest);
+}
+
+Option<Borrowed<struct quest_data>> questdb_searchname(XString str_)
+{
+ VarName str = stringish<VarName>(str_);
+ if (XString(str) != str_)
+ return None;
+ Option<P<struct quest_data>> quest = None;
+ for (auto& pair : quest_db)
+ questdb_searchname_sub(borrow(pair.second), str, borrow(quest));
+ return quest;
+}
+
+Borrowed<struct quest_data> questdb_search(QuestId questid)
+{
+ Option<P<struct quest_data>> id_ = quest_db.search(questid);
+ OMATCH_BEGIN_SOME (id, id_)
+ {
+ return id;
+ }
+ OMATCH_END ();
+
+ P<struct quest_data> id = quest_db.init(questid);
+
+ id->questid = questid;
+
+ return id;
+}
+
+Option<Borrowed<struct quest_data>> questdb_exists(QuestId questid)
+{
+ return quest_db.search(questid);
+}
+
+bool quest_readdb(ZString filename)
+{
+ io::LineCharReader in(filename);
+
+ if (!in.is_open())
+ {
+ PRINTF("can't read %s\n"_fmt, filename);
+ return false;
+ }
+
+ int ln = 0;
+
+ while (true)
+ {
+ auto res = TRY_UNWRAP(ast::quest::parse_quest(in),
+ {
+ PRINTF("read %s done (count=%d)\n"_fmt, filename, ln);
+ return true;
+ });
+ if (res.get_failure())
+ PRINTF("%s\n"_fmt, res.get_failure());
+ ast::quest::QuestOrComment ioc = TRY_UNWRAP(std::move(res.get_success()), return false);
+
+ MATCH_BEGIN (ioc)
+ {
+ MATCH_CASE (const ast::quest::Comment&, c)
+ {
+ (void)c;
+ }
+ MATCH_CASE (const ast::quest::Quest&, quest)
+ {
+ ln++;
+
+ quest_data qdv {};
+ qdv.questid = quest.questid.data;
+ qdv.quest_var = quest.quest_var.data;
+ qdv.quest_vr = quest.quest_vr.data;
+ qdv.quest_shift = quest.quest_shift.data;
+ qdv.quest_mask = quest.quest_mask.data;
+
+ Borrowed<struct quest_data> id = questdb_search(qdv.questid);
+ *id = std::move(qdv);
+ }
+ }
+ MATCH_END ();
+ }
+}
+} // namespace map
+} // namespace tmwa
diff --git a/src/map/quest.hpp b/src/map/quest.hpp
new file mode 100644
index 0000000..65e6f4e
--- /dev/null
+++ b/src/map/quest.hpp
@@ -0,0 +1,51 @@
+#pragma once
+// quest.hpp - Quest Log.
+//
+// Copyright © 2015 Ed Pasek <pasekei@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "fwd.hpp"
+
+#include "../mmo/ids.hpp"
+#include "../high/mmo.hpp"
+
+#include "map.hpp"
+#include "script-buffer.hpp"
+
+namespace tmwa
+{
+namespace map
+{
+constexpr int MAX_QUEST_DB (60355+1);
+struct quest_data
+{
+ QuestId questid;
+ VarName quest_var;
+ VarName quest_vr;
+ int quest_shift;
+ int quest_mask;
+};
+inline
+Option<Borrowed<struct quest_data>> questdb_searchname(VarName) = delete;
+Option<Borrowed<struct quest_data>> questdb_searchname(XString quest_var);
+Borrowed<struct quest_data> questdb_search(QuestId questid);
+Option<Borrowed<struct quest_data>> questdb_exists(QuestId questid);
+
+// get quest var by quest name / mask / bit
+bool quest_readdb(ZString filename);
+} // namespace map
+} // namespace tmwa