码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 第十五章:L2JMobius学习 – 刷新NPC和对话


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

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

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

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

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

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

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

    我们简单翻译一下,

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

    接下来,当我们在对话框里面选择“传送”的时候,客户端会向服务器端发送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数据包中的代码处理。

    1. // 点击NPC后的反馈,就是返回NpcHtmlMessage数据包
    2. ((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中增加两种数据包的处理。

    1. case 4: { msg = new Action(); break; }
    2. 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(裙文件里面也可以下载所有内容)。

  • 相关阅读:
    Pointnet学习以及对代码的实现
    包机制、JavaDoc
    python 之运算符
    docker容器技术实战-4
    飞书小技巧:markdown导出
    Selenium 三种等待方式详解 (强制等待、隐式等待、显示等待)
    nvm常用命令
    networking /etc/network/interfaces 笔记221104
    tensorflow之TFRcords文件读取
    cefsharp 最新稳定版104.4.240 (chromium-104.0.5112.102)
  • 原文地址:https://blog.csdn.net/konkon2012/article/details/134045229
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号