本文简单介绍如何自定义本模组下的袭击波次,主要参考本模组的wiki相关页面 http://coros.us/wiki/index.php?title=Hostile_Worlds_-_Invasions_-_Customizing

由于这个页面乃至整个wiki站经常性打不开基于身边统计学,所以提炼一下写到这里。本文基于mc版本1.12.2。


  • 准备工作

本模组对于袭击内容的设置写在json文件当中,而这些文件全部位于其前置模组CoroUtil的配置目录(.minecraft\config\CoroUtil\data\templates)

为了更有效率地进行修改,推荐使用专业的文本编辑器(例如notepad++)而非系统自带的记事本,以及准备一个json语法检查器(例如https://www.json.cn/)

由于mc在读取有语法错误的json文件时会直接跳过整个文件,等玩家意识到出错了整个游戏都加载完了,而这种语法错误绝大多数情况下都是多了少了一个逗号或者括号的事,所以找个程序帮你提前查错可以大幅减少在这个问题上浪费的时间。


  • 各配置文件的具体功能

本模组的袭击内容由三个文件控制:

templates/action/mob_spawns.json,控制每次袭击的阵容,包括生成什么怪物、生成多少、怪物携带怎样的装备、怪物的行为模式等等;

templates/cmods/invasions_cmods.json,记录怪物的行为模式、强化参数、装备模板等,mob_spawns在定义怪物的这些属性时会直接引用本文件写好的模板,两者的关系类似于武器与士兵:本文件定义什么是铁剑与盔甲,而mob_spawns定义什么是拿铁剑的步兵与穿盔甲的步兵;

templates/conditions/invasions_stages.json,决定每次袭击能够使用什么阵容,比如有些阵容在玩家较弱/较强时不会出现,有些阵容每经过多次袭击之后才会出现一次等等。但其实这些功能可以在mob_spawns里单独完成

每个文件各自所在的目录里还有一份写满了注释的模板文件,详细介绍了各种可用的配置项以及其作用,本文不多做叙述。


  • 如何创造新的袭击内容:一个简单的例子

首先打开游戏并输入指令:

/coroutil printEntities

该指令的作用是列出所有理论上可以添加到袭击当中的实体名称。在有很多其他模组的情况下返回的名单可能过长,此时可以打开游戏日志(.minecraft/logs/latest.log)浏览完整名单。

接下来假定要添加尸壳,尸壳的实体名称是minecraft:husk,那么可以先尝试生成一下看看:

/summon minecraft:husk
或者
/coroutil spawn minecraft:husk

之所以有这一步是因为有些模组的特定生物被绑定了事件或者别的什么稀奇古怪的玩意,如果强行生成的话游戏会直接出错崩溃,提前打开了config/forge.cfg里面的removeErroringEntities则不会崩溃,而是使生成的生物直接消失。无论是这里面哪种情况,都意味着这个生物不能加到袭击当中。此外,应该谨慎选择飞行的生物,因为原版mc截止1.12并不具有一个较好的飞行生物的行为逻辑标准,而各种加入了飞行生物的模组在这个问题上堪称八仙过海,因此本模组对飞行生物的支持具有很大的不确定性。

当然在这个例子里面尸壳不会有这些坏心思臭毛病潜在问题,所以召唤很成功,并且聊天栏会返回一条成功生成的信息记得别开和平

接下来打开mob_spawns.json,修改第一个袭击模板invasion_stage_1,这个模板是生成世界之后第一次袭击固定会采用的袭击阵容。如果不作其他修改的话

    {
      "name": "invasion_stage_1",
      "wave_message": "§cAn invasion has started! Zombie Miners!",
      "conditions": [
        {
          "condition": "invasion_number",
          "min": 1,
          "max": 1
        }
      ],
      "spawns": [
        {
          "entities": [
            "minecraft:zombie"
          ],
          "count": 3,
          "count_max": 5,
          "count_difficulty_multiplier": 2,
          "spawn_type": "ground",
          "cmods": [
            {
              "cmod": "template",
              "template": "invader_miner"
            },
            {
              "cmod": "template",
              "template": "inventory_all_scales"
            }
          ]
        },
        {
          "entities": [
            "minecraft:zombie"
          ],
          "count": 5,
          "count_max": 15,
          "count_difficulty_multiplier": 2,
          "spawn_type": "ground",
          "cmods": [
            {
              "cmod": "template",
              "template": "invader_soldier"
            },
            {
              "cmod": "template",
              "template": "inventory_all_scales"
            }
          ]
        }
      ]
    },

在这套模板的spawns属性里出现了两套设定,虽然两者的entities一项都是minecraft:zombie,即都会生成僵尸,但是两者有一个显著区别就是cmods这项当中,前者的属性里有一条invader_miner,这意味着这套设定生成的是僵尸矿工,具有挖掘方块的能力;而后者则是invader_soldier,生成的僵尸具有一些,呃,别的作战能力。

现在先放着前者不动,把上面这堆代码里第33行entities的内容改成"minecraft:husk",别忘了检查json语法,之后保存文件。

CoroUtil有热加载功能,所以无须重启游戏,回到游戏当中输入指令:

/coroutil reloadData

完成配置文件重载之后,可以输入一个指令来浏览具体某个袭击模板的设置内容:

/coroutil testProfile invasion_stage_1

上述指令就会打印出整个invasion_stage_1模板的内容,此时应该能看到尸壳士兵已经取代了僵尸士兵的位置。此外还有一个用于检查生成物的指令:

/coroutil testSpawn invasion_stage_1

这会从模板invasion_stage_1所记录的全部可能生成的怪物里随机生成一个,在这个例子当中会随机出现一个僵尸矿工或者尸壳士兵,多试几次总能两种都刷到。

最后,可以开始测试一次完整袭击的内容了。首先请在主世界找一片开阔平坦的露天区域,这样能更方便地找到袭击生成的怪物 还有人测试不开超平坦?

之后,由于修改的这个模板只会在第一次袭击时被使用,在默认设置下,玩家出生的第3天才可能出现袭击,而世界的第3个夜晚也恰恰是第一次袭击的时间,因此需要修改玩家的生存时间和整个世界的时间使得袭击立刻开始:

/hw_invasions setPlayerTime 62000
/time set 62000

如果修改过相关的设置,上述指令的具体参数需要相应进行改变。

一切正常的话,聊天栏应该会出现袭击开始的提醒,此时进入生存模式,让袭击的怪物成功索敌,之后就能看到僵尸矿工和尸壳步兵热情地来找你玩了。

至此就完成并测试了一次自定义袭击你已经学会了基本操作,接下来该打副本了,想设计内容更杂、规模更大的袭击,剩下的就是翻阅注释文档并反复修改和测试了。需要注意的是在一次袭击持续期间不能通过调整时间来引发更多的袭击,所以想测试新的袭击需要先结束目前正在进行的,方法也很简单,time set 0,看到左下角提示袭击结束就可以准备下一次了。


  • 动态难度

CoroUtil有一个动态评估玩家实力并据此额外设置游戏难度的机制,各评估项包括玩家的dps/距离出生点的距离/最大血量/护甲值/总游戏时间等等,可以在config/CoroUtil/DynamicDifficulty.cfg当中修改各项的计算方式以及权重。在游戏当中,使用如下指令可以查看当前CoroUtil为玩家设置的动态难度:

/coroutil difficulty

在默认设置下,如果玩家使用的是纯净版mc,那么动态难度会是一个0到1的值。超过1的动态难度意味着玩家使用了其他模组的内容或者使用了特殊的指令。

动态难度对袭击的影响是多方面的,包括怪物的装备质量、额外血量、额外攻击力、移动速度、掉落经验值以及生成数量。这些规则被记录在invasion_cmods.json当中。

这里值得一提的是玩家的dps,默认设置下其计算方式是检查玩家附近4个区块内怪物受到的以玩家为来源的伤害来计算dps,之后记录历史最高值用于评估难度。

这个过程里会忽略一些来自其他模组的设备,例如龙之研究的一些设备,但是显然总会有疏漏并导致计算出了一个异常高的dps,使得动态难度被瞬间拉高。

如果出现这种情况,可以使用如下指令以重置附近50个区块内的dps计算,重新获得一个合理的数值:

/coroutil resetDPS

如果这一问题反复出现,可以为dps计算设置一个可以接受的最大值。首先在config/CoroUtil/General.cfg当中将enableAdvancedDeveloperConfigFiles这一项开启,之后重启游戏,在同目录下就会生成高级配置文件Advanced.cfg,打开之后找到difficulty_MaxDPSRatingAllowed,这一项默认值为5,将其修改为一个自己能接受的数值。作为参考,纯净版mc正常游戏流程内的理论最大值是1。

除此之外,也可以考虑直接降低dps在动态难度计算当中的权重,甚至直接取消其参与难度计算。如果能够得知这种异常高伤害的伤害类型,也可以将其写进配置文件的黑名单列表里以解决这个问题。


  • 其他的实用指令

1. 上文提到CoroUtil支持热加载,那么顺理成章地,它也支持游戏内修改配置文件:

/config

如果仅安装了敌对世界入侵这个模组,通过这个方法可以在游戏内修改如下四个配置文件:

config/CoroUtil/General.cfg

config/CoroUtil/BlockDestruction.cfg

config/CoroUtil/DynamicDifficulty.cfg

config/HW_Invasions/InvasionConfig.cfg

在启用了高级测试项的情况下还可以额外修改两个文件:

config/CoroUtil/Advanced.cfg

config/HW_Monsters/Misc.cfg

所有的修改都是实时反映在游戏的,无需再使用前文所述的热加载指令。


2. 通过如下的游戏指令,可以直接获知在指定的动态难度和袭击波次下可能出现的袭击模板:

/hw_invasions testInvasion <难度> <波次>

其中难度和波次必须同时省略或者同时给定。省略的情况下,则会使用当前的难度和波次。举个例子,testInvasion 0.6 14将返回在动态难度0.6下生成第14次袭击时会使用的模板。

指令会返回可能的袭击模板下所有能够生成的怪物的具体参数,包括怪物是什么以及怪物在给定的难度下的实际攻击力/血量/速度/经验/装备/生成数量。

如果有多个满足条件的模板,那么只会随机出现其中一个,正如实际生成袭击的时候只会随机出现一个那样。所以如果想让这个指令必然返回自定义的那个模板,需要暂时为那个模板设计一个独一无二的满足条件,或者结合下面说的方法一起使用。


3. 在config/CoroUtil/Geneal.cfg当中,有一项mobSpawnsWaveToForceUse,将其设置为任意一个袭击模板的名称,即mob_spawns.cfg的任意一个name这项之后,游戏内接下来生成的所有袭击将强制变为这一模板。

这一全局设置不仅会改变实际袭击的内容,也会影响上面testInvasion指令的返回结果,此时这一指令将无视一切参数永远返回被指定的那个模板。