第十五章:L2JMobius学习 – 刷新NPC和对话

首先,我们介绍一下城镇里面的传送师NPC的刷新和对话。

传送师对应的类是L2TeleporterInstance,它继承L2FolkInstance,再继承L2NpcInstance。

我们要处理的是“单击/双击”传送师的业务逻辑,对应的是Action数据包。这个数据包具有普遍性,我们很多的点击操作都会发送该数据包。我们如何处理这个Action数据包呢?这里要分两种情况,第一次“单击”和第二次“单击”。第一次单击是选中传送师NPC,第二次单击就是弹出对话框。虽然我们可以双击,但是代码处理还是两次进行的。

第一次单击选中传送师NPC的时候,会向客户端发送TargetSelected 数据包和MyTargetSelected数据包。通过数据包名称我们也能知道,这个就代表选中目标的意思。

第二次单击传送师的时候,对应的依然是Action数据包的处理。由于已经选中了传送师NPC,所以这次向客户端发送NpcHtmlMessage数据包。这个数据包的内容本质是一段html代码。不同的传送师,对应的html代码是不一样的。这些html代码在哪里呢?就在工程根目录下的“data\html\teleporter”下。如下图所示:

第十五章:L2JMobius学习 – 刷新NPC和对话_第1张图片

在上面的“30006.html”文件对应的是“说话岛村庄”里面的传送师“拉普吉儿”。这个数字30006其实就是npc表中传送师“拉普吉儿”的主键ID。

第十五章:L2JMobius学习 – 刷新NPC和对话_第2张图片

我们打开这个“30006.html”文件,如下所示:

第十五章:L2JMobius学习 – 刷新NPC和对话_第3张图片

我们简单翻译一下,

第十五章:L2JMobius学习 – 刷新NPC和对话_第4张图片

上图中的文件内容就是我们双击传送师“拉普吉儿”出现的对话框的内容。也就是我们的NpcHtmlMessage数据包要返回的数据。

第十五章:L2JMobius学习 – 刷新NPC和对话_第5张图片

接下来,当我们在对话框里面选择“传送”的时候,客户端会向服务器端发送RequestBypassToServer请求,然后服务器端会向客户端继续发送NpcHtmlMessage数据包,实际上读取的就是“30006-1.htm”文件。

之所以读取“30006-1.htm”文件是由NPC的ID和后面传递的参数“1”决定的。我们在RequestBypassToServer数据包中需要获取一个“_command”的请求参数。这个参数的格式类似于:npc_268466749_Chat 1  我们可以看到,这个字符串格式就是上面里面决定的。而数字268466749 则是传送师“拉普吉儿”游戏对象的ID。L2World游戏世界类中的Map _allObjects集合就是以游戏对象的ID为KEY来存储该游戏对象的。

接下来,我们介绍RequestBypassToServer数据包中的代码处理。

// 点击NPC后的反馈,就是返回NpcHtmlMessage数据包
((L2NpcInstance)object).onBypassFeedback(activeChar, this._command.substring(endOfId + 1));

我们发现,代码处理就是调用L2TeleporterInstance类的onBypassFeedback方法,以及父类L2FolkInstance里面的onBypassFeedback方法,以及父类L2NpcInstance中的onBypassFeedback方法。这些被重写的onBypassFeedback方法处理的对话方式是不一样的。例如,对于“Chat”是在L2NpcInstance中处理的,而“goto”则是在L2TeleporterInstance中处理的。他们处理的大致逻辑都是相似的,就是找到对应的html文件,然后封装到NpcHtmlMessage数据包中发送给客户端。最终当我们选择传送到某一个村庄的时候,则会执行L2TeleporterInstance类中的doTeleport方法,参数为村庄的ID。这里,我们需要根据村庄来查询teleport数据表来获取传送点坐标信息。有了传送点之后,我们就可以调用L2Character的teleToLocation方法进行传送,向客户端广播TeleportToLocation数据包(向周围的玩家发送此数据包)。接下来,我们在GamePacketHandler中增加两种数据包的处理。

case 4: { msg = new Action(); break; }
case 33: { msg = new RequestBypassToServer(); break; }

如果你的角色没有金币的话,不用担心,我们在“characters”数据表中找到你的角色的“obj_Id”值(比如说是268478822),然后去“items”数据表中查询“owner_id = 268478822 AND item_id = 57”的数据记录,然后直接修改该纪录的“count”数值(这就是金币数量)。

现在,我们就来测试一下传送功能吧。

本章节涉及的内容均已上传百度网盘:

https://pan.baidu.com/s/1XdlcCFPvXnzfwFoVK7Sn7Q?pwd=avd4

欢迎加企鹅交流裙:874700842(裙文件里面也可以下载所有内容)。

你可能感兴趣的:(L2JMobius,L2JMobius,天堂2服务器端源码)