当前位置: 首页 > 工具软件 > Arcemu > 使用案例 >

Ascent/Arcemu代码分析8-任务系统

匡晟
2023-12-01

 

任务类型:

对话、送信、施放技能、杀怪、收集、采集、探索、护送(未实现)

 

任务定义:

Quest 定义了任务的需求、奖励、文本描述、完成条件以及QuestScrip扩展接口。和ItemPrototye类似,作为任务的定义模板,其对象在运行期间不变。

 

QuestLogEntry 任务的实例,记录了一个任务的运行期状态,如已完成的杀怪数量。和Item类似,引用一个Quest。每个Player对象有25 QuestLogEntry位置,即可以同时接25个任务。

QuestStorage 缓存了数据库中的quest表,存放了所有的任务对象

QuestScrip 任务脚本的接口,声明了任务过程中各个阶段的接口函数,通过派生子类实现实现脚本功能扩充。(参考脚本部分)

QuestRelationList 定义了QuestGiverQuest的关系列表,一个条目的类型可以是:

QUESTGIVER_QUEST_STARTQUESTGIVER_QUEST_END

                                                        也就是表示NPC是任务的发布者还是终结者。

QuestAssociationList 定义了Item与任务的关系列表,用于判断某个玩家是否有某个道具的任务。

QuestMgr 任务系统管理器,Singleton对象。

<(key:QuestGiver) (value:QuestRelationList)>的形式维护所有的任务关系。

任务存储:

quest 存于world Dbquest表,其内容由GD定义,运行期间不变化。

QuestLogEntry 存放于charactor DB questlog表,记录了玩家的所有任务记录(所有完成的和正在做的任务)。

 

任务系统的流程:

加载:

服务器启动时QuestStorage quest表加载所有的任务模板,结构与数据库中基本一样。

QuestMgr::LoadExtraQuestStuff()从表

creature_quest_startercreature_quest_finishergameobject_quest_startergameobject_quest_finisheritem_quest_association中加载所有的任务关系记录,即某个NPC都是哪些任务的发布者,又是哪些任务的终结者。

 

当一个NPC(或Gameobject,如公告栏)加载入游戏世界时,如果该NPCQuestGiver,则加载拥有的任务列表(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删除playerquestLogEntry之后,将任务id加入player的完成任务列表m_finishedQuests中,以免重复任务。

 

 类似资料: