台服dnf吧 关注:120,903贴子:1,975,984
  • 6回复贴,共1

【教程贴】从0开始修复神迹字体

取消只看楼主收藏回复

鸽到了四月份,还是准备把之前说的nut终伤详解和神迹字体详解帖子写完。
吧里现在有一个非常优秀的楼主正在持续更新神迹的版本优化,参与一起优化的吧友也非常多,修复了很多细节方面的内容,那我之前的“从0开始优化版本”的帖子就不再更新了吧,有兴趣的可以直接出门右转他的帖子。
我还是做好自己的部分,把nut相关的问题修一修,讲一讲。
这次就以修复神迹字体的典型问题:异常伤害卡退,为例子带大家读懂神迹字体的工作流程并修复高频bug。
最终的修复方法非常简单(并不完美),不想看流程解读就直接跳到最后。


IP属地:广东1楼2022-04-10 02:40回复
    既然是从0开始分析,那么就要先搞明白几个问题,这个字体相关的nut功能在哪定义的?怎么调用的?搞明白这两个问题,基本也就搞明白整个工作流程了。
    首先找到最直观的三个nut文件sqr/ui/damagefont/下的cache,function,header
    根据名字判断类别并稍微浏览一下,function中是字体相关的函数功能实现,header定义了部分常量,cache声明了一个DamageFont的类。
    搞清楚门路之后就要决定从哪里入手,既然我们是要修复异常状态导致的高频卡退bug,自然是从异常相关的部分去入手。
    直接在function.nut中搜索一下异常状态的关键字“active”

    首先是两个create函数,分别创建异常伤害和异常附加伤害的ani
    也就是下图中的紫色和蓝色字体

    顺着这个函数,遍历一下sqr看看什么地方调用了这个函数,也就能找到创建ani的地方
    (贪图方便我这里随手拿python写了个遍历)

    发现除了function.nut中的定义,还在cache.nut中进行了调用(preload是预读,不管它)


    IP属地:广东4楼2022-04-10 03:03
    回复
      2025-08-20 01:18:22
      广告
      不感兴趣
      开通SVIP免广告
      转到cache.nut中定位调用createActiveNumberAni的函数

      写两句注释方便大家阅读
      可以看到,这个initDamageActiveCache函数直接把0-9的数字ani先给他全部创建出来,设置完颜色和大小之后存到DamgeFont这个自定义的类里边,最后统一存到DamageActiveCache这个总容器里边去,以供之后直接绘制。
      (没有面对对象编程经验的小伙伴可以不用深入去看DamgeFont这个类是如何定义的)
      这就好办了,我们已经知道新建的数字ani都存到这个容器里边去了,那么只需要继续去找是什么函数动了这个DamageActiveCache容器,就能找到绘制的部分。
      同样的,拿python遍历一下,找找什么地方用到了DamageActiveCache

      好家伙,又回到了function.nut


      IP属地:广东6楼2022-04-10 03:15
      回复
        回到function.nut中看看是什么函数用到了这个cache
        一共有两个函数用到了,第一个是applyActiveDamage

        稍微阅读一下,可以知道这是一个计算异常伤害加成的函数
        读取169号技能的静态数据然后加成到异常伤害中,好像跟我们要修的东西关系不大。
        继续看第二个函数drawActiveDamageNumber,看名字,异常伤害字体绘制

        其实里面有很多心思,感兴趣的可以自己去细读一下,需要结合cache.nut中的自定义类去解读
        找了半天,还是没找到问题所在啊,楼主你是不是在逗我?
        嘿嘿,就当学习了嘛,没有坏处!
        后来去看了一下header.nut中的一些常量名,然后顺着找到了真正的问题所在(运气也是实力的一部分!)


        IP属地:广东9楼2022-04-10 03:25
        回复
          看一看header.nut中的常量定义,发现有一个很显眼的名字

          启动异常伤害?抓紧遍历一下看看是啥用处

          豁然开朗,绘制相关的函数应该是正常运作的,实际的问题可能出在控制怪物的ap里边
          如此,慢慢挖掘到真正的问题所在是非常有成就感的,不知道大家是不是也这样觉得
          抓紧去看看ap_minster.nut中的相关函数

          芜湖,找到问题所在了,原来是这里在控制异常伤害的最终结果
          往下看,观察一下他的几个条件从句

          非常清晰的可以看到,当存在攻击者并且造成感电的时候,会调用applyActiveDamage函数,
          这个函数很巧妙的设计了两个功能,首先调用之后会根据参数绘制异常伤害字体,然后返回的结果是之前讲到的,计算了各种加成之后的异常伤害,然后再与原先要设置的hp做计算,就能得到最终要设置的hp。
          是不是都串起来了?现在应该都能明白神迹字体的工作原理了吧?
          说了这么多,问题到底出在哪里?怎么修复?
          可以发现,他将感电和中毒出血的判断分开来写了
          我们上游戏实验一下,发现通常都是感电的前提下,再中毒或者出血就会导致高频的伤害然后炸掉
          看了这段代码之后就大概就能明白是什么问题了
          感电之后再中其他的异常状态,就会无限进入第一个判断分支,然后无限计算加成后的异常状态伤害,并且没有计时器约束,伤害能跳多块就跳多块,左脚踩右脚,导致最终爆炸
          该怎么解决呢?非常简单,上述两端代码全部注释掉,然后重新写一个自己的判断函数

          333代表我想让他间隔多长时间跳一次异常数字,333也就大概是一秒三跳,帧数也算稳定,如果你电脑一般,设置成1000ms也就是一秒一跳也没问题,当然3090ti直接设置成100就行
          至此,我们修复了异常伤害的高频卡退bug,当然,细心的小伙伴也能发现,这个是一个“不完美”的办法
          它违背了作者的初衷,因为这里并没有再计算加成后的异常伤害,而是改为了不吃加成的异常伤害
          如果追求完美的小伙伴,想让异常状态也吃到属性加成,那建议根据上述函数稍微改改就行


          IP属地:广东11楼2022-04-10 03:53
          收起回复
            防止大家觉得异常字体失效我再说一句,如果你在修炼场里勾选了无限hp的沙袋,异常数字就不会正常跳出,因为长青修练场的这个无限hp也是给怪物上了ap然后调用了这个函数。
            正常刷图是没问题的(想在修练场测试效果,别选择无限hp就行)


            IP属地:广东29楼2022-04-10 14:00
            回复
              完整修复版 直接导入即可
              6ZO+5o6l77yaaHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMVlWZFZNZUp3aGpmRk14NU1aMGlacXc/cHdkPWFmaXQgCuaPkOWPluegge+8mmFmaXQ=


              IP属地:广东37楼2022-04-13 19:30
              收起回复