[Minecraft/我的世界 1.16.x] 铁傀儡刷新机制代码解读

您所在的位置:网站首页 我的世界村民刷铁傀儡怎么刷 [Minecraft/我的世界 1.16.x] 铁傀儡刷新机制代码解读

[Minecraft/我的世界 1.16.x] 铁傀儡刷新机制代码解读

2024-05-31 05:51| 来源: 网络整理| 查看: 265

今天闲着无聊看了一下MC1.16.1的代码就顺便讲一下这个铁傀儡的刷新好了。部分函数并没有列出,纯口述,因为太多了。

开头先吐槽一下这个专栏编辑器,真的是魔鬼般难用,无奈直接截图。

Minecraft的循环程序是以每秒20周期的固定速度运行的,即tps: 20.0。因此每刻发生在每0.05秒。在游戏中的一天将正好为24000刻,或20分钟。但是这个速率也不是完全固定的。如果电脑的性能不足以跟上这个速度,一个游戏刻的运行时间就被延长,每秒的游戏刻就会变少。由于游戏中的绝大多数动作都是以游戏刻而不是真实世界的时钟作为时间基准,这意味着在较慢的电脑上很多事情都要花更长的时间来完成。

每过去一刻,游戏的各方面都会更新:移动的实体位置会发生变化,生物会检查周围环境并更新自身的行为,玩家的生命值和饥饿值会根据玩家的处境发生变化,等等。这些游戏的方面是服务端的行为,和负责渲染游戏本身的客户端的更新速度没有关系。也就是说,游戏的帧率(FPS)不影响TPS,电脑的图形性能不会影响到游戏机制。-Minecraft Wiki

村民会在两种情况下尝试生成铁傀儡,分别是:受到惊吓 和 与其他村民扯蛋(聊天)。

惊吓PanicTask 类

恐吓式铁傀儡生成由PanicTask类控制,这里截取了其中的两个方法:

keepRunning方法有三个参数,其中long l为当前时间。所以第八行的if语句的含义就是每100ticks尝试一次铁傀儡的生成,即真实时间5秒。(其实是要被100整除,但持续的恐吓的话,就不用在意了;但假如你要想用间断性攻击村民的方法,可能还是得考虑一下的。)

其中的villagerEntity.summonGolem方法的第二个参数为需要的有效村民数量,即3个。

shouldKeepRunning方法会调用里面的两个getter来查询村民的Brain对象中是否包含被恐吓或受伤的记忆,即MemoryModuleType.NEAREST_HOSTILE 和 MemoryModuleType.HURT_BY。这两个值会在对应的sensor类中被更新,并使用父类Sensor的默认sense间隔,每20tick更新一次,即每秒都更新。

这两个方法被Task父类中的tick方法调用,判断shouldKeepRunning为true之后,便会调用一次keepRunning来尝试生成铁傀儡。(更多的代码我没有去看了,应该就是每个tick都会被执行一次?)

聊天VillagerEntity.talkWithVillager

村民间靠互相吹牛逼()生成铁傀儡的方法比较简单,直接写在了村民自己的类里面。

在尝试生成铁傀儡前,游戏会判断这两个村民距上次聊天(尝试生成铁傀儡)是否已经过了1200ticks,即60秒。这意味着这两个村民嘴皮子说烂也就只能一分钟生成一次。

且通过这种方式生成铁傀儡需要至少5个有效的村民。

到此为止两个生成铁傀儡的方法已经讲完了,接下来会详细说明铁傀儡的生成。

村民生成铁傀儡的条件几个getter

首先是canSummonGolem,这个方法查询了这个村民是否具有生成铁傀儡的基本条件:即睡过觉,工作过,并且在过去的30秒内没有看见过铁傀儡。

hasRecentlyWorkedAndSlept方法查询了村民Brain对象中上一次睡觉时间,假如睡过觉,则将当前时间和上一次睡觉的时间相减法,假如间隔小于24000ticks,即20分钟,则返回true。也就是说村民至少在二十分钟内睡过觉,才具备生成铁傀儡的条件。

hasSeenGolemRecently方法查询了村民上一次看见铁傀儡的时间,假如查询不到,则直接返回false。如果查询的到,判断距离上一次看见铁傀儡,是否已经经过了600ticks,即30秒,如过小于30秒,则true。

LastSeenTime的记忆由GolemLastSeenSensor类更新,他每间隔200tick,即10秒查询一次村民Brain中看见的周围看见的活体的记忆(MemoryModuleType.MOBS)的列表,如果存在铁傀儡,就刷新LastSeenTime的时间(重置冷却时间)。

然而这并不意味着你有10秒钟的时间来移除铁傀儡,因为MOBS的列表由NearestLivingEntitiesSensor更新,而这个类继承了Sensor类默认构造的sense间隔,即每秒1次。

此外,由于NearestLivingEntitiesSensor侦测生物的范围为:从this对象的边框往外6个方向拓展16格。即对于村民来说,需要在33*34*33的空间内看不见铁傀儡。

生成铁傀儡的summonGolem方法VillagerEntity.summonGolem

经过第4行,即上一部分所讲的判断后,游戏创建了一个以村民为中心,向6个方向拓展10格的空间。考虑到村民尺寸,这个空间应该是21*22*21。

第6行获取了这个空间里所有的村民,并保存到一个列表中。第7行找出了这个列表中所有具备生成铁傀儡条件村民,即上文提到的基本条件。

接下来,游戏对比获取的村民数量和所需的数量,假如数量满足条件,则调用spawnIronGolem方法尝试生成铁傀儡。假如铁傀儡成功生成,即11行ironGolemEntity不为null,则更新这个村民上一次看见铁傀儡的时间。

尝试生成铁傀儡:spawnIronGolem

上文讲到,当这组村民具备生成铁傀儡的条件时,会调用spawnIronGolem进行生成尝试。这个尝试会进行10次,直到成功,或者次数用完为止。

游戏获取村民脚的位置(有点不太确定是脚的为止还是下面地板的为止,不过我后来看setPos的代码的时候发现,应该指的是脚的位置。),并赋给blockPos对象。接下来游戏会使用Java自带的随机数生成器生成一个[0, 16)的随机整数,并减掉8,这就是生成铁傀儡的x和z轴相较于村民的相对坐标,即(-8, -8)到(7, 7)的横向范围。

获取到x和z值后,游戏调用getLegitSpawningPos(这个方法的名字我瞎jb取的,原来没有命名)查找高度合法的坐标blockPos2。假如blockPos2不为空,即找到了合法的坐标,游戏会创建一个铁傀儡对象(代码30行)。(具体过程详见下一节)

然后游戏会调用铁傀儡对象的canSpawn方法(41行),先查询blockPos2下方一格(铁傀儡脚踩的方块),及其即上方2格(铁傀儡头和胸)方块是否符合刷新铁傀儡的条件。具体为:

blockPos2 - 1:顶面必须Solid

blockPos2 + i(i = 1, 2):不能是实心,释放红石信号,液体,具有阻止生物生成标签和能造成伤害的方块。

也就是说,他只要求1*3的空间里没有阻挡物。

然后,游戏判断blockPos2是否依旧具备生成条件(和上方两格相同的判断方法,唯一的区别是输入的参数里,液体属性是被设定为Empty的。),并查看在铁傀儡的碰撞体积内是否有某一些奇奇怪怪的实体(他写了一堆do-while,看得我头大,懒得看具体是啥了。),有的话会导致刷不出来。

在一切条件都满足的情况下,铁傀儡就会被成功生成。

获取合法的生成高度getLegitSpawningPos

这个方法接收了刚才随机生成的坐标blackPos,他的高度是村民脚的那一格!

接下来游戏直接把这个高度加了6,赋值给blockPos2。这是最高一层能刷新铁傀儡的高度,也就是铁傀儡的脚的位置。

然后游戏循环13次,向下逐层搜索合法的高度,直到可以刷铁傀儡为止。即从村民脚开始的为止,往上6格,往下6格,都是可以刷新铁傀儡的。

其中,铁傀儡脚的位置,即blockPos2,只能为空气或液体(岩浆也是液体,但是会在上文提到的canSpawn方法中被排除。这意味着,假如搜索到岩浆,且被认为是合法的话,铁傀儡就会尝试生成,而不会继续向下搜索,导致本次生成失败,即便下方有合法的生成空间。)。而铁傀儡脚下的方块,即blockPos,必须具有blocksLight的属性,也就是不能为透明方块,或者是一些杂七杂八的东西(我猜用minihud能显示光照亮度的方块应该才符合条件)。

假如13层都无法生成,则本次生成失败。

总结

空间 (这里为了方便,记村民脚的坐标为(0,0,0))

 铁傀儡生成空间为:(-8,-6,-8)到(7,6,7)

 侦测铁傀儡的范围为:(-16,-16,-16)到(16,17,16)

 一组村民的范围为:(-10,-10,-10)到(10,11,10)

 你给铁傀儡1*3的空间他一样会刷,就是比较看脸。

时间

 一旦村民探测到铁傀儡,冷却时间重置为30秒。

 某种意义上来说,村民每秒都能侦测是否有铁傀儡。

 村民在惊恐状态下每5秒尝试一次铁傀儡生成。

 村民互相吹逼,就算疯狂说话,也要60秒才能尝试一次生成。

 村民想刷铁傀儡,必须20分钟内有睡觉过,即游戏内一天。不然熬夜成仙了也不怕僵尸了(雾)。

数量

 恐吓式刷铁村民需要至少3只。

 普通唠嗑法需要5只。

失败的条件

 脚踩方块需要有blocksLight的属性,且上表面为Solid。

 脚的方块只能是空气或液体。岩浆也是,但是会和3冲突,导致直接失败,即便下方还有适宜的方块。

 脚踩的方块往上三格,不能是实心,释放红石信号,液体,具有阻止生物生成标签和能造成伤害的方块。然而脚的那一格可以为液体。

这也不完全算是个科普,有错误的话还请大佬指出2333

@Conn_Lost



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3