战利品修饰器

战利品修饰器只是描述了如何修改战利品表。你写好一个修饰器,还需要注册它,确定它会影响那些战利品表后才会生效!如何注册见后面的章节!

ILootModifier(战利品修饰器)(crafttweaker.api.loot.modifiers.ILootModifier) 是一个函数式接口,他有两个参数:

  • loots as List<IItemStack> 已经由战利品表抽奖出的结果

  • currentContext as LootContext 战利品表抽奖的当前背景

这个函数需要返回一个 List<IItemStack> 来确定实际的战利品表抽奖结果。

你可以对这个 List 进行删改,然后依旧返回这个 List。亦或是返回一个新的 List 从而完全接管这个战利品表。

// 这个修饰符由于直接返回了 loot list,而并没有修改,所以实际上没啥用
(loots, currentContext) => loots

(loots, currentContext) => {
    // 给 loot list 添加了铁锭
    // 相当于给战利品表抽奖结果额外添加了一个铁锭
    loots.add(<item:minecraft:iron_ingot>);
    return loots;
}

// 直接忽略原来的战利品抽奖结果,使实际上的抽奖结果固定为一个铁锭
// 数组可以自动转型为 List,这是没有问题的
(loots, currentContext) => [<item:minecraft:iron_ingot>]

CommonLootModifiers

写 lambda 表达式可能有些麻烦,CrT 提供了 CommonLootModifiers 工具类来快速构建所需的战利品修饰器。

导入

使用前最好先导入它:

import crafttweaker.api.loot.modifiers.CommonLootModifiers;

可用条件

import crafttweaker.api.loot.modifiers.CommonLootModifiers;
import crafttweaker.api.loot.modifiers.ILootModifier;

// 返回给战利品表抽奖结果添加一个指定物品的修饰器
// CommonLootModifiers.add(stack as IItemStack) as ILootModifier

val addIronIngot as ILootModifier = CommonLootModifiers.add(<item:minecraft:iron_ingot>);

// 返回给战利品表抽奖结果有几率添加一个指定物品的修饰器
// CommonLootModifiers.addWithChance(stack as MCWeightedItemStack) as ILootModifier
// 物品 % 几率
val addIronIngotHalfChance = CommonLootModifiers.addWithChance(<item:minecraft:iron_ingot> % 50);

// 返回给战利品表抽奖结果添加多种指定物品的修饰器
// CommonLootModifiers.addAll(stack as IItemStack[]) as ILootModifier

// 返回给战利品表抽奖结果添加多种指定物品与概率的修饰器
// CommonLootModifiers.addAllWithChance(stacks as MCWeightedItemStack[]) as ILootModifier
val foo = CommonLootModifiers.addAllWithChance([<item:minecraft:honey_bottle> % 50, <item:minecraft:dried_kelp> % 13]);

// 添加物品,数量为两个值之间,均匀分布
// CommonLootModifiers.addWithRandomAmount(stack as IItemStack, min as int, max as int) as ILootModifier
val abc = CommonLootModifiers.addWithRandomAmount(<item:minecraft:conduit>, 2, 9);

// 添加物品,但根据特定附魔等级,会额外再多掉落一些物品。如果你需要支持时运什么的,请用这个
// 物品数量与附魔等级的关系有三种算法
// 二项分布,原版用于煤矿石和红石矿石等
// 额外掉落数量为 附魔等级 + extra 和 p 的二项分布。
// CommonLootModifiers.addWithBinomialBonus(enchantment as MCEnchantment, extra as int, p as float, stack as IItemStack) as ILootModifier
val bar = CommonLootModifiers.addWithBinomialBonus(<enchantment:minecraft:fortune>, 3, 0.5714286, <item:minecraft:wheat_seeds>);
// 均匀分布
// 额外掉落数量为 0 至 附魔等级 × Multiplier 的均匀分布。
// CommonLootModifiers.addWithUniformBonus(enchantment as MCEnchantment, multiplier as int, stack as IItemStack) as ILootModifier
val xyz = CommonLootModifiers.addWithUniformBonus(<enchantment:minecraft:fortune>, 1, <item:minecraft:glowstone_dust>);
// 原版默认矿物掉落的分布,原版用于钻石矿石等
// 即有1/(附魔等级+2)几率数量改为原来的×(2至(附魔等级+1)),有2/(魔咒等级+2)几率不变。
val moreCoal = CommonLootModifiers.addWithOreDropsBonus(<enchantment:minecraft:fortune>, <item:minecraft:coal>);

val addIronIngotAndApple as ILootModifier = CommonLootModifiers.add([<item:minecraft:iron_ingot>, <item:minecraft:apple>]);

// 和上面的相同,只不过可以一次添加多种物品
// CommonLootModifiers.addAllWithBinomialBonus(enchantment as MCEnchantment, extra as int, p as float, stacks as IItemStack[]) as ILootModifier
// CommonLootModifiers.addAllWithOreDropsBonus(enchantment as MCEnchantment, stacks as IItemStack[]) as ILootModifier
// CommonLootModifiers.addAllWithUniformBonus(enchantment as MCEnchantment, multiplier as int, stacks as IItemStack[]) as ILootModifier

// 返回删除所有战利品表抽奖结果的修饰器
// CommonLootModifiers.clearLoot() as ILootModifier

val clearLoot as ILootModifier = CommonLootModifiers.clearLoot();

// 返回删除指定物品的修饰器
// CommonLootModifiers.remove(target as IIngredient) as ILootModifier)
// 参数为 IIngredient,所以我们可以填物品标签进去
val removeRedstone as ILootModifier = CommonLootModifiers.remove(<tag:items:forge:dusts/redstone>);

// 返回删除多种物品的修饰器
// CommonLootModifiers.removeAll(targets as IIngredient[]) as ILootModifier
val removeIronIngotAndPoppy as ILootModifier = CommonLootModifiers.removeAll([<tag:items:forge:ingots/iron>, <item:minecraft:poppy>]);

// 返回将一种物品替换为另一种物品的修饰器
// 该修饰器会对物品数量进行匹配
// 对于将两个胡萝卜替换成一个马铃薯的修饰器,当它作用于结果为五个胡萝卜的战利品表,替换结果为
// 两个马铃薯和一个胡萝卜。
// 因为每两个胡萝卜被替换为一个马铃薯,剩余一个胡萝卜则没有替换
// CommonLootModifiers.replaceStackWith(target as IItemStack, replacement as IItemStack) as ILootModifier
val replaceTwoCarrotsWithOnePotato as ILootModifier = CommonLootModifiers.replaceStackWith(<item:minecraft:carrot> * 2, <item:minecraft:potato>);

// 返回将一种物品替换为另一种物品的修饰器
// 由于该修饰器使用 IIngredient,所以我们可以使用物品标签,但也没有了数量的指定,只会一换一
//CommonLootModifiers.replaceWith(target as IIngredient, replacement as IItemStack) as ILootModifier

val replaceCarrotWithPotato as ILootModifier = CommonLootModifiers.replaceWith(<item:minecraft:carrot>, <item:minecraft:potato>);

// 与前面的同名的方法功能一样,只不过参数是映射,表示了多个替换规则
// CommonLootModifiers.replaceAllStacksWith(replacementMap as IItemStack[IItemStack]) as ILootModifier
// CommonLootModifiers.replaceAllWith(replacementMap as IItemStack[IIngredient]) as ILootModifier

// 将多个修饰器连接起来组成一个新的修饰器
// CommonLootModifiers.chaining(modifiers as ILootModifier[]) as ILootModifier

// 例子调用了前面定义的修饰器,则为先删除全部再加个铁锭
val clearThenAddIronIngot as ILootModifier = CommonLootModifiers.chaining([clearLoot, addIronIngot]);

// 连接一个或多个修饰器,不过第一个已经确定好是清除原有物品的修饰器了
// CommonLootModifiers.clearing(modifiers as ILootModifier[]) as ILootModifier
// 这个和上面一个例子是等价的
val clearThenAddIronIngot2 as ILootModifier = CommonLootModifiers.clearing(addIronIngot);

LootContext

LootContext 包含了当前战利品表的当前背景,他有这些 Getter。注意不是有些 Getter 返回的可能是 null。这也很好理解,对于方块掉落时的战利品抽奖,你不可能获取表示实体伤害类型的 DamageSource。

例子

import crafttweaker.api.util.DamageSource;
import crafttweaker.api.loot.modifiers.ILootModifier;

val addGoldIngotWhenDiedByMagic as ILootModifier = (loots, currentContext) => {
    if (currentContext.damageSource != null) { // 确定非空
        val damageSource as DamageSource = currentContext.damageSource as DamageSource; // 获取当前 DamageSource,并强转为非空类型
        if (damageSource.magic) { // 如果是魔法
            loots.add(<item:minecraft:gold_ingot>);
        }
    }
    return loots; // 返回修改后的 loot list
};

最后更新于