任务类型:
对话、送信、施放技能、杀怪、收集、采集、探索、护送(未实现)
任务定义:
Quest 定义了任务的需求、奖励、文本描述、完成条件以及QuestScrip扩展接口。和ItemPrototye类似,作为任务的定义模板,其对象在运行期间不变。
QuestLogEntry 任务的实例,记录了一个任务的运行期状态,如已完成的杀怪数量。和Item类似,引用一个Quest。每个Player对象有25个 QuestLogEntry位置,即可以同时接25个任务。
QuestStorage 缓存了数据库中的quest表,存放了所有的任务对象
QuestScrip 任务脚本的接口,声明了任务过程中各个阶段的接口函数,通过派生子类实现实现脚本功能扩充。(参考脚本部分)
QuestRelationList 定义了QuestGiver与Quest的关系列表,一个条目的类型可以是:
QUESTGIVER_QUEST_START,QUESTGIVER_QUEST_END,
也就是表示NPC是任务的发布者还是终结者。
QuestAssociationList 定义了Item与任务的关系列表,用于判断某个玩家是否有某个道具的任务。
QuestMgr 任务系统管理器,Singleton对象。
以<(key:QuestGiver) (value:QuestRelationList)>的形式维护所有的任务关系。
任务存储:
quest 存于world Db的quest表,其内容由GD定义,运行期间不变化。
QuestLogEntry 存放于charactor DB 的questlog表,记录了玩家的所有任务记录(所有完成的和正在做的任务)。
任务系统的流程:
加载:
服务器启动时QuestStorage 从quest表加载所有的任务模板,结构与数据库中基本一样。
QuestMgr::LoadExtraQuestStuff()从表
creature_quest_starter,creature_quest_finisher,gameobject_quest_startergameobject_quest_finisher,item_quest_association中加载所有的任务关系记录,即某个NPC都是哪些任务的发布者,又是哪些任务的终结者。
当一个NPC(或Gameobject,如公告栏)加载入游戏世界时,如果该NPC是QuestGiver,则加载拥有的任务列表(QuestRelationList),该列表由 QuestMgr 赋予。
通讯流程:
玩家跑动而刷出NPC时,向服务器发送
CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY 或
CMSG_QUESTGIVER_STATUS_QUERY
查询范围内所有的QuestGiver或者某个QuestGiver所带的任务对于玩家状态(enum QUEST_STATUS),用于客户端显示叹号问号。
玩家与QuestGiver对话(接任务或者交任务),发送
CMSG_QUESTGIVER_HELLO
若是与公告栏对话:则发送
CMSG_GAMEOBJ_USE
之后服务器返回可以接的任务列表,客户端选择其中一个:
CMSG_QUESTGIVER_QUERY_QUEST
然后可以接受任务:
CMSG_QUESTGIVER_ACCEPT_QUEST
这时服务器创建一个QuestLogEntry对象以及一些相关的任务物品放在玩家身上,之后客户端索取该任务的详细信息:
CMSG_QUEST_QUERY
服务器返回任务目标、说明文本等任务详细信息用于任务显示。
当玩家杀怪、探索、释放技能等操作时,调用了QuestMgr的各种函数接口,如:
玩家接了任务之后,在这些函数中会检查是否有相关的任务,如果有就更新任务状态。比如杀一个任务怪之后,OnPlayerKill会更新杀死数量,如果够任务需求则任务完成。同时,每当任务状态可能变化时,客户端均会向服务器发送
CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY更新所有的QuestGiver的显示状态。
任务完成后,找交任务的NPC对话,如果有多个任务,则返回一个任务列表,客户端通过:
CMSG_QUESTGIVER_COMPLETE_QUEST
选择一个任务,然后选择一个奖励物品,发送
CMSG_QUESTGIVER_CHOOSE_REWARD:
之后该任务完成,QuestMgr删除player的questLogEntry之后,将任务id加入player的完成任务列表m_finishedQuests中,以免重复任务。