权重系统

简介

整个插件的概率系统由权重控制。什么是权重?权重表示获得特定物品的相对机会。例如,如果物品 A 的权重为 10,物品 B 的权重为 30,则获得物品 A 的概率为 25%,而获得物品 B 的概率为 75%。这是计算概率的最科学方法。

哪些地方可以使用权重?

权重可以在哪些地方使用?实际上,权重应用于插件的许多部分。例如,根据战利品的条件调整权重,在迷你游戏中使用权重,以及提供权重修改功能的物品效果(如钓鱼竿)。它们通常以列表格式配置,并遵循这种特定的配置格式。

通过权重修改,我们可以实现许多其他钓鱼插件无法实现的功能。例如,海洋中垃圾较少,但在河流中频繁出现。使用金色钓鱼竿的玩家有更高的机会捕获金质战利品。或者,要捕获一条凶猛的鲨鱼,玩家必须使用鲨鱼饵料。所有这些功能都可以通过权重系统实现。

权重操作

权重操作包括 +(加法)、-(减法)、*(乘法)、/(除法)、%(取模)和 =(自定义表达式)。

基本操作

我们先来看一些基本的权重操作表达式。对于操作符 +-*/%,只需在冒号后写上对应的操作符,然后在其后指定对应的值。这个值可以是一个已注册的占位符,也可以是一个固定的数字。

rubbish:+10
rubbish:-5.5
rubbish:/2
rubbish:%6
rubbish:*{placeholder}

自定义操作

rubbish:=100+sin(pi)
内置函数:
    abs: 绝对值
    acos: 反余弦
    asin: 反正弦
    atan: 反正切
    cbrt: 立方根
    ceil: 向上取整
    cos: 余弦
    cosh: 双曲余弦
    exp: 自然对数的底 e 的幂次方 (e^x)
    floor: 向下取整
    log: 自然对数 (以 e 为底)
    log10: 对数 (以 10 为底)
    log2: 对数 (以 2 为底)
    sin: 正弦
    sinh: 双曲正弦
    sqrt: 平方根
    tan: 正切
    tanh: 双曲正切
    signum: 正负号函数

你还可以使用 {0} 表示在计算此表达式时当前条目的权重,或使用 {1} 表示在计算此表达式时所有条目权重的总和(不包括权重小于或等于 0 的条目)。

在此示例中,“垃圾”的权重将相对于其之前的值翻倍。

rubbish:={0}*2

在此示例中,“垃圾”的权重将变为所有战利品总权重的 1%。

rubbish:={1}*0.01

配置 loot-conditions.yml 和 game-conditions.yml 文件

一些用户打开这个文件后可能会感到非常困惑。Custom Fishing 使用了一种其他插件从未尝试过的配置文件格式。与其他钓鱼插件不同,Custom Fishing 提供了一个树状的概率池,可以根据条件自由调整权重。现在我们将带您了解默认的配置文件,以便理解这个系统的工作原理。

请注意:这里的“组”(group)与物品中的组没有任何关系。这个“组”只是一个随机名称,用于帮助用户组织文件结构。

首先,我们看到一个名为“global group”的部分。

global-group:
  list: []
  conditions: {}
  sub-groups: {}

global-group 只是一个可以自由修改的随机名称,您可以随意添加任何您想要的组,例如:

river-group:
  list: []
  conditions: {}
  sub-groups: {}
ocean-group:
  list: []
  conditions: {}
  sub-groups: {}
nether-group:
  list: []
  conditions: {}
  sub-groups: {}
the-end-group:
  list: []
  conditions: {}
  sub-groups: {}

通过仔细观察,您会发现一个组由三个部分组成:list、conditions 和 sub-groups。

添加条目到列表

如果您希望某个战利品出现,只需将其添加到列表中,使用 =+。 如果文件是 loot-conditions.yml,您可以添加来自 item/entity/block 文件夹中的任何战利品 ID。 如果文件是 game-conditions.yml,您只能添加来自 minigame 文件夹中的游戏 ID。

global-group:
  list:
    - my_fish:+1 # 将 my_fish 添加到战利品表中。
  conditions: {}
  sub-groups: {}

在这个奇怪的配置中,my_fish 的最终权重是 ((0+6-4)*10/5)%3=1。有趣的是,它的权重兜兜转转了一圈之后又回到了 1。

global-group:
  list:
    - my_fish:=0   # 设定权重
    - my_fish:+6   # 加
    - my_fish:-4   # 减
    - my_fish:*10  # 乘
    - my_fish:/5   # 除
    - my_fish:%3   # 取模
  conditions: {}
  sub-groups: {}

条件

现在让我们继续看看条件部分。该部分影响列表中权重操作符是否执行。您可以使用条件系统提供的大多数条件。如果您仍然不知道什么是条件系统,请阅读

例如,如果我现在希望这条鱼出现在我的自定义生物群系中,我可以这样配置

global-group:
  list:
    - my_fish:+1
  conditions: 
    in-water: true
    biome:
      - my_namespace:my_custom_biome
  sub-groups: {}

非常好!您现在已经了解了条件系统的工作原理,我们接着来看子组是如何工作的。

在此示例中,我创建了两个子组,其中一个无法执行,因为它违反了一个重要原则: 子组的条件不能与父组的条件冲突。 如果玩家很可爱的,那么最终他只能得到 cute_fish,因为我将 my_fish 的权重设置为 0。

global-group:
  list:
    - my_fish:+1
  conditions: 
    in-water: true
    biome:
      - my_namespace:my_custom_biome
  sub-groups:
    impossible_group:  # 这个组无法生效,因为在进入内部
      list:            # 子组部分之前,生物群系必须是
        - my_fish:+1   # my_namespace:my_custom_biome
      conditions:
        biome:
          - minecraft:plains 
    possible_group:
      list:
        - cute_fish:+1
        - my_fish:=0   
      conditions:
        equals:
          value1: '%cute_player%'  # 这只是一个虚构的占位符
          value2: 'true'

假设您有一个需求,无论战利品列表如何变化,获得箱子的概率始终应保持在约 2%。在这种情况下,您可以按以下方式配置:

global-group:
  list: []
  conditions:  {}
  sub-groups: 
    fishs:
      list: 
       - a:+5
       - b:+7
       - c:+19
      conditions:  {}
      sub-groups: {}
    chest:
      list: 
       - chest:={1}*0.02
      conditions:  {}
      sub-groups: {}

请记住,loot-conditions.yml 是从上到下、从外到内解析的。因此,您需要将箱子条件放在文件的末尾。

这里的示例不够现实,因为玩家持有的渔具通常会影响之后其他物品的权重,这可能导致 2% 的概率失效。因此,您可以使用 global-effects 并对单个战利品项目应用权重调整,因为 global-effects 总是最后处理。

不过,这个示例提供了足够的思路,并且在某些场景下可能会派上用场。

调试战利品表

权重对我来说不太直观。我如何将权重转换为百分比形式? 插件已经考虑到了这一点。您只需要使用命令 /customfishing debug loot <surroundings>。它将基于您当前持有的钓鱼竿、鱼饵和其他可能影响钓鱼结果的因素,计算所有潜在战利品的概率。

进阶教程

附加权重函数

除了基本的 id:操作 格式外,插件还提供了许多其他操作限定符。接下来,我将根据示例逐一解释每个功能。

group_for_each group_for_each 操作将对组内的每个成员应用权重操作。

global-group:
  list:
    - group_for_each:river:+10
  conditions:  {}
  sub-groups: {}

除了使用单个组(如 river)外,您还可以组合多个组。例如,river&silver_star 表示同时属于 riversilver_star 组的战利品。类似地,river|ocean 表示属于 riverocean 组的战利品。

global-group:
  list:
    - 'group_for_each:river&silver_star:+10'
  conditions:  {}
  sub-groups: {}

group_available_for_each

group_for_each 不同,group_available_for_each 影响的对象必须已经在之前出现过。

global-group:
  list:
    - gold_fish:=10
    - group_available_for_each:river:+10
  conditions:  {}
  sub-groups: {}

group_total

group_total 操作将把权重均匀分配给组内的每个成员,以确保组的总权重保持一致。

global-group:
  list:
    - group_total:ocean:+10
  conditions:  {}
  sub-groups: {}
global-group:
  list:
    - 'group_total:ocean&golden_star:+10'
  conditions:  {}
  sub-groups: {}

group_available_total

global-group:
  list:
    - tuna_fish:+10
    - group_available_total:ocean:+10
  conditions:  {}
  sub-groups: {}

loot_available

与常规的权重操作不同,这个操作只针对那些已经在之前出现过的条目。

global-group:
  list:
    - tuna_fish:+10
    - loot_available:tuna_fish:+10
  conditions:  {}
  sub-groups: {}
global-group:
  list:
    - gold_fish:+10
    - loot_available:tuna_fish:+10
  conditions:  {}
  sub-groups: {}

附加占位符

= 表达式中,您可以使用 {entry_xxx} 来获取之前出现的特定条目的权重,并使用 {group_xxx} 来获取所有符合组条件的条目权重的总和。

在此示例中,我首先为所有河流鱼类添加了 +10 的权重,然后将所有河流鱼类的总权重平均分配给所有海洋鱼类。

global-group:
  list:
    - group_for_each:ocean:+10
    - group_total:river:={group_ocean}
  conditions:  {}
  sub-groups: {}

在此示例中,我将 golden_starsilver_star 的权重分别设置为没有星级状态时的 10% 和 30%。

global-group:
  list:
    - tuna_fish:+10
    - 'tuna_fish_silver_star:={entry_tuna_fish}*0.3'
    - 'tuna_fish_golden_star:={entry_tuna_fish}*0.1'
  conditions:  {}
  sub-groups: {}

对于组,您还可以使用前面提到的 &| 操作符。& 操作符表示组的交集(属于两个组的物品),而 | 操作符表示组的并集(属于任意一个组的物品)。

global-group:
  list:
    - group_for_each:ocean:+10
    - 'rainbow_fish:={group_ocean&silver_star}*0.3'
  conditions:  {}
  sub-groups: {}

最后更新于