Loottable(可抢夺物品列表)是1.9+中的一个新特性,主要靠调用外置json文件实现对物品奖励获取的随机.
第二章内将会向各位介绍Loottable中的实例与详解
Chm版本:http://pan.baidu.com/s/1c1U4804 (若.chm遇到问题下载压缩文件)
全部章节总索引
人生第一个Loottable
看了之前结构与标签的基本介绍,我们现在就可以写一个简单的Loottable了:
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1
- }
- ]
- }
- ]
- }
首先随机池列表中只有一个随机池,这个随机池里的项目列表中只有一个项目——石头.
唯一的随机池只从它的项目列表中选取一次物品,并且项目列表中唯一的项目石头的权重为1.
所以实际效果就是该Loottable的结果必然是一个石头.
建立Loottable文件夹
如果我们要在游戏中调用Loottable,我们先必须学会如何建立一个Loottable文件夹,以便调用Loottable
首先我们需要找到存档的文件夹
进入存档文件中的data文件夹
新建一个名为“loot_tables”的文件夹
在其中创建一个子文件夹,在loot_tables文件夹里一个子文件夹就代表一个命名空间(此时命名空间为“test”)
在命名空间内新建一个json文件,并粘贴之前的Loottable作为内容.该json文件名是Loottable的名字(此时名字为“a”)
当然也可以在这个命名空间再建子文件夹,子文件夹中建立Loottable,也是允许的.
新建json文件可以靠代码编写软件,也可以直接新建一个文本文档并将.txt改成.json.
json可以直接靠打开方式选择记事本打开.
调用Loottable
进入该存档,接下来介绍如何调用Loottable
首先我们要知道Loottable路径表达式怎么写.
标准写法:
[命名空间]:[Loottable名] 或者 [命名空间]:[子文件夹名]/[Loottable名]
例如刚才的示例:
test:a
就是路径表达式.(当然这是第一种写法)
值得一提的是如果没有命名空间,默认命名空间就是minecraft.例如entities/creeper,代表默认的爬行者掉落物.
接下来我们可以靠NBT调用Loottable了.
有两个NBT:LootTable(string)和DeathLootTable(string)
第一个LootTable标签用于大部分容器,而第二个DeathLootTable标签用于实体.
后面的string处需要填写的就是Loottable路径表达式.
- /setblock ~ ~ ~ minecraft:chest 附加值 模式 {LootTable:"test:a"}
- /summon Zombie ~ ~ ~ {DeathLootTable:"test:a"}
Function 1 随机附魔/随机等级附魔/烤熟的物品
- enchant_randomly随机附魔
┕ enchantments(列表):能够附上的魔 (默认为能与对应物品匹配的附魔)
- <blockquote>{
- enchant_with_levels随机附魔的等级
┕ treasure(布尔):是否能随机到宝藏附魔(例如冰霜行者和修理)┕ levels(整型):随机附魔的等级┕ levels(列表):随机附魔的等级范围└ min(整型):随机附魔的最小级└ max(整型):随机附魔的最大等级
复制代码
- <blockquote>{
- furnace_smelt
无子项目,内容:将被烤熟的物品
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:fish",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:furnace_smelt"
- }
- ]
- }
- ]
- }
- ]
- }
- looting_enchant数量影响(适用于实体)
┕ limit(整型):抢夺附魔后额外最大掉落的数量┕ count(整型):抢夺附魔后额外掉落的数量┕ count(列表):抢夺附魔后额外掉落的数量范围└ min(整型):抢夺附魔后掉落最小的数量└ max(整型):抢夺附魔后掉落最大的数量
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:wool",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:looting_enchant",
- "count": 1,
- "limit": 3
- }
- ]
- }
- ]
- }
- ]
- }
掉落羊毛,初始1个,抢夺后额外1个,最大3个.
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:wool",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:looting_enchant",
- "count": {
- "min": 3,
- "max": 5
- }
- }
- ]
- }
- ]
- }
- ]
- }
掉落羊毛,初始1个,抢夺后额外3~5个,没有限制.
- set_attributes物品属性修改器
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:diamond_sword",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_attributes",
- "modifiers": [
- {
- "attribute": "generic.attackDamage",
- "name": "Damage",
- "amount": {
- "min": 1.0,
- "max": 1.5
- },
- "operation": "addition",
- "slot": [
- "mainhand",
- "offhand"
- ]"id": "00000000-0000-0001-0000-000000000001"
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }
NBT和具体效果就不讲解了,和原来的属性NBT相同,除了amount增加了最小和最大的选项.(详情站内本版内搜索物品属性)
Function 3 数量/工具损害值/物品附加值
- set_count数量
┕ count(整型):物品的具体数量┕ count(列表):物品的随机数量范围└ min(整型):物品最小的数量└ max(整型):物品最大的数量
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_count",
- "count": 10
- }
- ]
- }
- ]
- }
- ]
- }
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_count",
- "count": {
- "min": 10,
- "max": 20
- }
- }
- ]
- }
- ]
- }
- ]
- }
- set_damage损害
┕ damage(浮点):物品(工具)的剩余耐久的比率.也就是剩余的耐久/最大耐久.(1.0就是是没有损害,0.0就是没耐久了)┕ damage(列表):剩余耐久的比率的范围└ min(浮点):剩余耐久比率最小值└ max(浮点):剩余耐久比率最大值
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:iron_sword",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_damage",
- "damage": {
- "min": 0.5,
- "max": 1
- }
- }
- ]
- }
- ]
- }
- ]
- }
- set_data物品附加值
┕ data(整型):物品(非工具)的附加值┕ data(列表):附加值的范围└ min(整型):附加值的最小值└ max(整型):附加值的最大值
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:wool",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_data",
- "data": {
- "min": 0,
- "max": 15
- }
- }
- ]
- }
- ]
- }
- ]
- }
- set_nbt数据标签
┕ tag(字符串):物品的tag标签后的内容
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_nbt",
- "tag": "{display:{Name:"a",Lore:["b"]}}"
- }
- ]
- }
- ]
- }
- ]
- }
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_nbt",
- "tag": "{display:{Name:a,Lore:[b]}}"
- }
- ]
- }
- ]
- }
- ]
- }
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_nbt",
- "tag": "{display:{Name:a,Lore:[b]},a:1}"
- }
- ]
- }
- ]
- }
- ]
- }
- /testfor @e[type=Item,c=1] {Item:{tag:{a:1}}}
在了解Condition之前需要知道下面三个选择器:
this、killer和killer_player
this代表附上Loottable的实体,也就是死亡的实体;
killer就是杀死该实体的实体,不只是玩家;
killer_player必须是玩家.
(在Condition中不提供图片演示) (主要是条件不好模拟出来← ←)
- entity_properties死亡条件
┕ entity(字符串):选择器,选择实体┕ properties(复合):满足条件┕ on_fire(布尔):选择的实体是否着火
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_nbt",
- "tag": "{display:{Name:a,Lore:[b]}}"
- }
- ]
- }
- ],
- "conditions": [
- {
- "condition": "minecraft:entity_properties",
- "entity": "this",
- "properties": {
- "minecraft:on_fire": true
- }
- }
- ]
- }
- ]
- }
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_nbt",
- "tag": "{display:{Name:a,Lore:[b]}}"
- }
- ],
- "conditions": [
- {
- "condition": "minecraft:entity_properties",
- "entity": "killer",
- "properties": {
- "minecraft:on_fire": true
- }
- }
- ]
- }
- ]
- }
- ]
- }
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_nbt",
- "tag": "{display:{Name:a,Lore:[b]}}",
- "conditions": [
- {
- "condition": "minecraft:entity_properties",
- "entity": "killer_player",
- "properties": {
- "minecraft:on_fire": true
- }
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }
- entity_scores实体分数
┕ entity(字符串):选择器,选择实体┕ scores(复合):满足分数┕ A score(整型):一个具体分数,把'A score'改成计分板名.┕ A score(复合):一个范围分数,把'A score'改成计分板名.┕ min(整型):值域中最小值┕ min(整型):值域中最大值
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:cobblestone",
- "weight": 1,
- "conditions": [
- {
- "condition": "minecraft:entity_scores",
- "entity": "killer_player",
- "scores": {
- "b": 1,
- "a": {
- "min": 5,
- "max": 10
- }
- }
- }
- ]
- }
- ]
- }
- ]
- }
- killed_by_player被玩家杀死
┕ inverse(布尔):是否反向选择,判断不是被玩家杀死的
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:cobblestone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:furnace_smelt",
- "conditions": [
- {
- "condition": "minecraft:killed_by_player",
- "inverse": false
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }
判断是被玩家杀死的.
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:cobblestone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:furnace_smelt",
- "conditions": [
- {
- "condition": "minecraft:killed_by_player",
- "inverse": true
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }
判断不是被玩家杀死得,包括被其他实体杀死和自然死亡(摔死淹死等)
Condition 3 二次随机点数
- random_chance随机几率
┕ chance(浮点):此处填写一个0.0~1.0的数值(叫做点数).系统会生成一个0.0~1.0的随机数,与这里填写的数值比较.若小于该数值则成功.
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "quality": 3,
- "conditions": [
- {
- "condition": "minecraft:random_chance",
- "chance": 0.5
- }
- ]
- },
- {
- "type": "item",
- "name": "minecraft:diamond",
- "weight": 1
- }
- ]
- }
- ]
- }
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:furnace_smelt",
- "conditions": [
- {
- "condition": "minecraft:random_chance",
- "chance": 0.5
- }
- ]
- }
- ]
- },
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1
- }
- ]
- }
- ]
- }
在这个实例里,首先有一个石头,虽然权重为1,但只有50%几率获得.
- random_chance_with_looting抢夺影响判定
┕ chance(浮点):此处填写一个0.0~1.0的数值(叫做基础点数).┕ looting_multiplier:(浮点):抢夺等级的乘数
chance + looting_level * looting_multiplier
也就是:基础点数+抢夺附魔等级*等级乘数
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:furnace_smelt",
- "conditions": [
- {
- "condition": "minecraft:random_chance_with_looting",
- "chance": 0.2,
- "looting_multiplier": 0.1
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }
此处使用抢夺3附魔,掉落石头的概率就是:0.2+3*0.1=0.5
该condition也是稳定二次随机,相比之下引入了抢夺.
Entry 1 物品
作为随机项目,主要是针对物品。
事实上在前面我们已经举了很多例子,现在我们需要用上所有Entry中使用的结构来完整的呈现一个物品列表:
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "quality": 1,
- "functions": [
- {
- "function": "minecraft: set_count",
- "count": {
- "min": 0,
- "max": 1
- }
- }
- ],
- "conditions": [
- {
- "condition": "minecraft: killed_by_player"
- }
- ]
- },
- {
- "type": "item",
- "name": "minecraft: diamond",
- "weight": 1,
- "quality": 3,
- "functions": [
- {
- "function": "minecraft:set_count",
- "count": {
- "min": 0,
- "max": 1
- }
- }
- ],
- "conditions": [
- {
- "condition": "minecraft:killed_by_player"
- }
- ]
- }
- ]
- }
- ]
- }
下面来分析这个Loottable
首先只有一个随机池,随机池只会选择一次物品;
物品列表两个物品,一个是石头,一个是钻石;
石头的权重为1,权重增值为1;钻石权重为1,权重增值为3(也就是当你幸运2时,石头真实权重为3,钻石却变成了7)
两者获得条件都是被玩家击杀,而且两者都有50%数量为0(也就是无).
Entry 2 空
将项目设为空,可以帮助我们初步的稳定概率,所以可以说属于是稳定一次随机.
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "empty",
- "weight": 1
- },
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1
- }
- ]
- }
- ]
- }
这个实例里,我们抽中石头的几率只是50%,另外50%为空.
空,是Entry中一个补位,用于控制随机,可以结合后面的内容稳定概率.
比如实体如果要让物品随机掉落,请注意控制Entry适当为空的几率,否则将必然掉落物品;
Entry 3 随机概率计算
为了平衡物品,难免必须用到概率计算,在学习计算之前,再来总结总结一次随机和二次随机.
也许你还对之前提到的一次随机,二次随机不了解,下面就来总结总结:
- 一次随机
真实权重=(权重+权重增值*幸运值)
- 二次随机
下面进入正式计算阶段,来看两个例子:
- 抽中一个项目的概率
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:stone",
- "weight": 1,
- "quality": 3,
- "conditions": [
- {
- "condition": "minecraft:random_chance",
- "chance": 0.5
- }
- ]
- },
- {
- "type": "item",
- "name": "minecraft:diamond",
- "weight": 1
- }
- ]
- }
- ]
- }
如果你要计算抽中一个项目的概率,你可以使用下面的方法:
先来看一次随机,石头权重就是=(1+3*幸运值),而钻石始终为1,
那么一次随机中石头概率为(1+3*幸运值)/(2+3*幸运值)
接着来看二次随机,此处二次随机是随机点数,所以石头只有50%概率不为空.
那么总共石头的概率就是(1+3*幸运值)/(4+6*幸运值).
公式:
一个项目的真实权重=(该项目权重+该权重增值*幸运值)
random_chance = 随机点数【随机点数】或者(基础点数+抢夺附魔等级*等级乘数)【抢夺判定】
一个项目的概率=(一个项目真实权重/项目列表真实权重总和)* random_chance * (1-set_count中选中0的概率)
*注解:set_count选中0的概率靠这样计算:例如min:0,max:10,那么一共可能有11种数量结果,那么选中0的概率就是1/11.
当然,这种方法也可以用于三次随机(function中的condition),也就是继续在后面乘上随机点数:
带功能的一个项目的概率=(一个项目真实权重/项目列表真实权重总和)* random_chance【对于Entry】 * (1-set_count中选中0的概率) * random_chance【对于Function】
- 抽一个项目后某一个数量的概率
一个项目的概率=(一个项目真实权重/项目列表真实权重总和)* random_chance * (中选中n的概率)
带功能的一个项目的概率=(一个项目真实权重/项目列表真实权重总和)* random_chance【对于Entry】 * (set_count中选中n的概率) * random_chance【对于Function】
Pool 随机抽取原理
在一个随机池中,只能有一个项目列表,每次从项目列表中抽取一个项目.
roll的次数就是抽取次数.
而项目列表中项目的weight和quality决定了该项目抽到的几率.
结合function和condition,也许抽取的项目为空,或者貌似多个项目;或者下面讲到调用loottable,事实上都是一个项目.
一个项目≠一个物品,一个项目只是抽取的结果.
(每次抽取的项目也许包含n个子项目,也可能继续随机抽取)
所以打破该误区之后,将会在下面loottable一节中运用这种概念来完成更复杂的随机列表.
Pool 随机列表滚动值
你可以理解为一个骰子,每滚动一次最后随机抽取一个点数.
当然滚动值不是这个滚动所得点数,也不是权重,更不能理解成为项目中物品数量翻多少倍
滚动值就是投掷骰子的次数,近似的理解为抽取多少项目(可重复),
准确来说是抽取项目列表中一个项目的次数.
rolls:1
就是抽取一次(滚动值默认为0)
rolls:10
就是抽取十次
bonus_rolls就是幸运值对滚动值的影响
最终真实滚动值实际上是向下取整(rolls+bonus_rolls*幸运值)
rolls:3 本来抽取3次
bonus_rolls:1.5之后
如果幸运值=1,就是抽取4次。如果幸运值=2,就是抽取6次。
Loottable嵌套
- 一个标准嵌套实例
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "loot_table",
- "name": "test:b/a",
- "weight": 1
- },
- {
- "type": "loot_table",
- "name": "test:a",
- "weight": 1
- }
- ]
- }
- ]
- }
嵌套中调用的loottable分别是命名空间test中文件夹b的a和a
两者随机到的权重相同
- 意义
从技术上避免了冗杂的填写物品,可以将多物品进行打包(建立一个loottable)操作
- 嵌套解析
我们知道了loottable选取一个项目的步骤是:
Lootable→所有Pools→选取Entry
那么嵌套一个loottable,事实上就是将这个过程*2
Lootable1→所有loottable1的Pools→选取loottable2→所有loottable2的Pools→选取Entry
Loottable循环嵌套
既然Loottable支持嵌套,那么如果Loottable1套着Loottable2,而Loottable2又有Loottable1会怎么样呢:
以上所述的Loottable2都是:
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "loot_table",
- "name": "test:loottable1",
- "weight": 1
- }
- ]
- }
- ]
- }
有三种情况
- 项目无限循环
Loottable1:
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "loot_table",
- "name": "test:loottable2",
- "weight": 1
- }
- ]
- },
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:wool",
- "weight": 1
- }
- ]
- }
- ]
- }
那么Loottable1无限调用,直到溢出:(实体掉落未尝试,也许会崩,也许什么事也没发生)
- 普通调用
Loottable1:
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "loot_table",
- "name": "test:loottable2",
- "weight": 1
- },
- {
- "type": "item",
- "name": "minecraft:wool",
- "weight": 1
- }
- ]
- }
- ]
- }
那么在嵌套调用过程中,如果抽中了物品将会停止无限循环
也就是最后只有一个物品
- 容器
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:chest",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_nbt",
- "tag": "{LootTable:test:loottable2}"
- }
- ]
- }
- ]
- }
- ]
- }
那么容器会不断调用Loottable1,也就是无限箱子
Loottable与多个池与溢出
- 多个池
Pool在LootTable中是并列的,每个Pool必然会选中(若无条件)
Entry在Pool中是独立的,只能选中一个
多个池支持让Loottable更丰富
- Loottable嵌套与多个池
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "loot_table",
- "name": "test:b/a",
- "weight": 1
- },
- {
- "type": "loot_table",
- "name": "test:loottable3",
- "weight": 1
- }
- ]
- },
- {
- "rolls": 1,
- "entries": [
- {
- "type": "loot_table",
- "name": "test:loottable3",
- "weight": 1
- }
- ]
- }
- ]
- }
这样该loottable就调用了loottable2和3.
而如果Loottable1中有n个随机池,每个随机池中都有必然选中的Entry,且该项目是Loottable2,Loottable2中,那么就有了一个溢出的问题。
- 溢出(实体掉落无此问题)
那么总物品数量≥mn个,如果总物品超过容器容量上限,那么保留的物品有什么原则?
溢出后的物品只取Lootable中从上至下的顺序所选取的项目的物品.
因为每次选择项目时给其中每个物品都分配一个随机的slot,
从上至下顺序是读取json的顺序,那么每次读取一个项目,都有一个上面的分配过程,直到分配物品超过随机slot.
在写loottable中一定要留意父子级的调用造成的溢出给随机物品带来的影响,尤其是在一个loottable中出现总物品较多的情况下.
Loottable防溢出和分配物品
因为有溢出物品规则的存在,如果随机的物品总数大于了容器单元总数,所的物品仍旧不是随机的.
为了防止溢出,我们可以对Pools中随机池的总数,以及Pool中的Rolls进行控制,
首先我们需要检测是否存在溢出的可能:
Rolls总数=该Loottable或所有调用的底Loottable(最低级)的Rolls(Rolls_max)总数
如果一个Loottable的Rolls总数>容器单元总数,那么总有溢出的可能.
对于溢出,有两种方法分配物品:
1.将多个并列Pool中的Entry合并
2.减少Rolls次数
Loottable作为项目中物品的概率
计算概率是平衡物品一个十分重要的过程,再看本片之前首先要看前面的Entry3
事实上作为嵌套,随机概率的算法也是嵌套的.
公式:对于n个嵌套loottable
一个项目的真实权重[n]=(该项目权重+该权重增值*幸运值)
random_chance[n] = 随机点数【随机点数】或者(基础点数+抢夺附魔等级*等级乘数)【抢夺判定】
一个loottable的概率=(一个项目真实权重[n]/项目列表真实权重总和[n])* random_chance[n] * (1-set_count中选中0的概率[n])
*注解:set_count选中0的概率靠这样计算:例如min:0,max:10,那么一共可能有11种数量结果,那么选中0的概率就是1/11.
总的来说,概率的算法就是(loottable1中抽到loottable2的概率)*(loottable2中抽到loottable3的概率)*……*(loottablen-1中抽到loottablen的概率)
Loottable概率调整及平衡物品
如果一个物品破坏了地图的平衡性,我们可以通过调整概率来平衡物品.
比如以下三个Loottable嵌套关系:
- Loottable0
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "loot_table",
- "name": "test:loottable1",
- "weight": 1
- },
- {
- "type": "empty",
- "weight": 1
- }
- ]
- }
- ]
- }
- Loottable1
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "loot_table",
- "name": "test:loottable2",
- "weight": 1
- },
- {
- "type": "empty",
- "weight": 1
- }
- ]
- }
- ]
- }
- Loottable2
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:diamond",
- "weight": 1
- },
- {
- "type": "empty",
- "weight": 1
- }
- ]
- }
- ]
- }
这里随机到钻石的概率是0.125,如果我想时概率降低到0.1,先要计算出所有非底级Loottable中随机到该Loottable的概率:
0.25
接着通过理想概率/这个值的到该物品理想权重比例:
0.1/0.25=0.4
接着计算出项目列表中其他项目权重总和:
empty总和为1
接着用其他项目权重总和/(1-理想权重比例)*理想权重比例得出最后权重:
1/(1-0.4)*0.4≈0.67
Loottable文件夹管理
当你建立一个复杂的loottable体系时,嵌套是不可或缺的.
而Loottable文件夹的管理,关系到了往复调用中是否能够逻辑清晰:
地心之路中使用的物品loottable,由于loottable只能支持二级文件,路径不能无限子文件夹,因此你可以把文件夹分细一点.(地心之路loottable嵌套级别为3)(目前支持无限子文件夹了)
例如在此处我将每一种类物品都归纳进入一个命名空间,这样再调用的时候结构分明.
(每一个子loottable的内容都只有一个权重为1的对应物品)
做完了这个步骤,再可以写更高一级的loottable
Loottable父子调用与完整Loottable包的制作
拿地心之路作为例子;
子:
一把剑
- {
- "pools": [
- {
- "rolls": {
- "min": 1,
- "max": 1
- },
- "entries": [
- {
- "type": "item",
- "name": "minecraft:iron_sword",
- "weight": 1,
- "functions": [
- {
- "function": "set_damage",
- "damage": {
- "min": 0.02,
- "max": 0.02
- }
- },
- {
- "function": "set_nbt",
- "tag": "{Unbreakable:1,AttributeModifiers:[{Operation:0,UUIDLeast:1,UUIDMost:1,Amount:5.5,AttributeName:generic.attackDamage,Name:Attack},{Operation:0,UUIDLeast:1,UUIDMost:1,Amount:0,AttributeName:generic.attackSpeed,Name:Speed}],ench:[{id:16,lvl:1}],HideFlags:63,display:{Name:\u00a77\u00a7l\u94c1\u5251,Lore:[\u00a77\u00a7n\u524d\u4eba\u7684\u9057\u7269]}}"
- },
- {
- "function": "set_count",
- "count": {
- "min": 1,
- "max": 1
- }
- }
- ]
- }
- ]
- }
- ]
- }
必得物品.
父:
- {
- "pools": [
- {
- "rolls": {
- "min": 1,
- "max": 1
- },
- "entries": [
- {
- "type": "loot_table",
- "name": "supply_food:1",
- "weight": 1
- }
- ]
- },
- {
- "rolls": {
- "min": 1,
- "max": 1
- },
- "entries": [
- {
- "type": "loot_table",
- "name": "weapon_dagger:a",
- "weight": 6
- },
- {
- "type": "loot_table",
- "name": "weapon_sword:a",
- "weight": 3
- },
- {
- "type": "loot_table",
- "name": "weapon_gun:1",
- "weight": 1
- }
- ]
- },
- {
- "rolls": {
- "min": 1,
- "max": 1
- },
- "entries": [
- {
- "type": "loot_table",
- "name": "supply_medicine:1",
- "weight": 1
- }
- ]
- }
- ]
- }
随机中随机到的(weapon_sword:a)几率只有3/10
顶级:
- {
- "pools": [
- {
- "rolls": {
- "min": 1,
- "max": 1
- },
- "entries": [
- {
- "type": "loot_table",
- "name": "supply:a",
- "weight": 5
- },
- {
- "type": "loot_table",
- "name": "weapon:a",
- "weight": 4
- },
- {
- "type": "loot_table",
- "name": "ragbag:a",
- "weight": 2
- }
- ]
- }
- ]
- }
概率(weapon:a)是4/11
那么随机到该剑的概率只有:3/10*4/11=6/55
- 完整包的制作
如果需要平衡物品,结合前面的概率计算出所有物品的实际概率,接着改变顶级中的概率(如果改变底级的概率将会造成对于其他调用中波动很大)
关于Seed
如果你不想每一次更新Loottable都是随机的物品,那么你可以用一个Seed来规定调用loottable时的随机种子,让Loottable按相同种子随机.
也就是说每次随机的物品都是确定且相同的.
例如:
- setblock ~ ~1 ~ minecraft:chest 0 0 {LootTable:"minecraft:chests/jungle_temple",LootTableSeed:100L}
那么每次从jungle_temple中抽取物品不是随机的,而是依靠随机种子100L的物品.
下面分析以下两个标签:
LootTableSeed:长整型,是对于容器来说Loottable的随机种子.
DeathLootTableSeed:长整型,是对于实体来说Loottable的随机种子.
如果后面填0L,那么相当于没有种子,依旧是完全随机.
Seed的用途就是让随机产生的物品成为一个种子产生的特定物品,而不是每次更新了容器、实体都完全随机.
关于幸运值
幸运值由下面几个项目来呈现:
luck药水效果、unluck药水效果、物品属性generic.luck、海之眷属附魔.
最终幸运值公式:
Operation:2(属性的效果为提升百分比):(luck药水效果-unluck药水效果)*generic.luck+海之眷属附魔;
Operation:0(属性的效果为提升值):luck药水效果-unluck药水效果+generic.luck+海之眷属附魔;
*注:海之眷属附魔只适用于钓鱼机制.
结合指令1 实体抽奖机
顾名思义,通过Loottable的实体随机掉落来制作抽奖机.
尽管要调用外置资源,但是待抽取的物品十分丰富,只需要拟写一份Loottable即可.
Roll:
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "diamond",
- "weight": 5
- },
- {
- "type": "item",
- "name": "gold_ingot",
- "weight": 10
- },
- {
- "type": "item",
- "name": "iron_ingot",
- "weight": 25
- },
- {
- "type": "item",
- "name": "coal",
- "weight": 60
- }
- ]
- }
- ]
- }
接着
- /summon Zombie ~ ~ ~ {DeathLootTable:"Roll:Roll",CustomName:"Roll",Silent:1b}
按下一次按钮就
- /kill @e[type=Zombie,name=Roll]
即可
注意不要关闭实体掉落
结合指令2 随机器
刷怪笼拟写很麻烦,@r随机器需要进行实体列阵穷举,由于Loottable也是随机性,可以结合指令制作一个随机器
Roll:
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "diamond",
- "weight": 5
- },
- {
- "type": "item",
- "name": "gold_ingot",
- "weight": 10
- },
- {
- "type": "item",
- "name": "iron_ingot",
- "weight": 25
- },
- {
- "type": "item",
- "name": "coal",
- "weight": 60
- }
- ]
- }
- ]
- }
这个随机器就有四个穷举对象,物品:钻石,金锭,铁锭,煤.
概率分别是5% 10% 25% 60%
利用实体抽奖机的方法,
- /summon Zombie ~ ~ ~ {DeathLootTable:"Roll:Roll",CustomName:"Roll",Silent:1b}
随机一次就
- /kill @e[type=Zombie,name=Roll]
接着检测掉落物
然后产生输出
- /testfor @e[type=Item] {Item:{id:"minecraft:coal"}}
- cond:/execute @p say 1
结合指令3 判定条件死亡
因为有DeathLootTable,在实体死亡后可以调用Loottable产生掉落物,结合Conditions我们可以进行复杂的死亡条件检测.
- {
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "item",
- "name": "minecraft:potato",
- "weight": 1,
- "functions": [
- {
- "function": "minecraft:set_nbt",
- "tag": "{display:{Name:a,Lore:[b]}}"
- },
- {
- "function": "minecraft:furnace_smelt"
- }
- ],
- "conditions": [
- {
- "condition": "minecraft:killed_by_player",
- "inverse": false
- },
- {
- "condition": "minecraft:entity_properties",
- "entity": "this",
- "properties": {
- "minecraft:on_fire": true
- }
- }
- ]
- }
- ]
- }
- ]
- }
这样,只需要检测一个名为a,附注为b的烤土豆就能知道这个实体在着火的情况下被玩家杀死:
- /scoreboard players tag @e[type=Item] add tag {Item:{id:"baked_potato",tag:{display:{Name:a,Lore:[b]}}}}
- cond:操作
- /kill @e[tag=tag]
[groupid=546]Command Block Logic[/groupid]