Skip to content

LootJs

LootJs 是一个KubeJS附属模组,它为KubeJS对于原版战利品列表修改进行了更方便的操作 KubeJS本身自带的修改 Loot 的方法过于繁琐,若要修改关于:

  • 方块
  • 实体
  • 战利品列表

内的 LootTable

推荐使用LootJs来实现

简介

Action 用于更改当前战利品池结果或触发效果。您可以简单地将多个 Action 串联在一起。对于每个 Loot Modification,您至少需要一个 Action。

操作(基础)

开始之前,请跳转来进行基本知识的了解

添加战利品

addLoot(...items)

将一个或多个添加items到当前战利品池中

以沙砾展开:

  • addBlockLootModifier语句对沙砾进行 LootTable 修改
  • addLoot对沙砾的 LootTable 进行添加

对于具体的 LootType,请使用ProbeJs来进行补全提示

js
LootJS.modifiers((event) => {
    // 修改方块
    event.addBlockLootModifier("minecraft:gravel").addLoot("minecraft:flint");
    // 修改实体
    event.addEntityLootModifier("minecraft:pig").addLoot("minecraft:diamond");
    // 修改原版战利品类型
    event.addLootTypeModifier("chest").addLoot("minecraft:bedrock");
});

官方示例

js
LootJS.modifiers((event) => {
    event.addBlockLootModifier("minecraft:oak_log").addLoot(
        /**
         * Creates a LootEntry with 50% chance of dropping a stick.
         */
        LootEntry.of("minecraft:stick").when((c) => c.randomChance(0.5)),
        /**
         * Creates a LootEntry with 50% chance of dropping a stick.
         */
        LootEntry.of("minecraft:apple").when((c) => c.randomChance(0.5))
    );
});

若要移除之前的掉落则加上 ↓ 这段代码在 addLoot 的上面

js
.removeLoot("minecraft:flint")

根据 Js 的代码执行顺序,若将这串代码放置在 addLoot 底下则不会生效

必须放在 addLoot 的上面

若一个方块/实体/战利品列表里面有多个 Loot 则可以使用

js
.removeloot(Ingredient.all)

来将该方块/实体/战利品列表的所有 Loot 全部移除

添加替代战利品

addAlternativesLoot(...items)

若要对一个方块添加多种 Loot,且有概率随机,这时候就要用到addAlternativesLoot

根据 Minecraft Wiki:只会将第一个成功(满足条件)的物品添加到战利品池中。如果没有物品成功,则不会添加任何物品

  • addBlockLootModifier语句进行对"minecraft:coal_ore"修改
  • removeLoot语句内使用Ingrediten.all删除"minecraft:coal_ore"的所有 Loot
  • addAlternativesLoot进行 LootTable 列表修改
js
LootJS.modifiers((event) => {
    event
        .addBlockLootModifier("minecraft:coal_ore")
        .removeLoot(Ingredient.all)
        .addAlternativesLoot(
            LootEntry.of("minecraft:apple").when((c) => c.randomChance(0.8)),
            LootEntry.of("minecraft:stick").when((c) => c.randomChance(0.3)),
            LootEntry.of("minecraft:diamond").when((c) => c.randomChance(0.7)),
            LootEntry.of("minecraft:coal").when((c) => c.randomChance(0.99)),
            LootEntry.of("minecraft:torch").when((c) => c.randomChance(0.2))
        );
});

相较于上方示例,直接在addLoot里面添加多种 Loot 有所区别

addLoot里面添加多种 Loot 以及概率的时候是所有 Loot 都会根据你所设置的概率来进行掉落

addAlternativesLoot是根据你设置的战利品条目,若一个条目的 Loot 触发后,则其他条目的 Loot 不会触发

相当于addLoot是所有 Loot 都会触发,addAlternativesLoot只会触发一个.

添加序列战利品

addSequenceLoot(...items)

相较于addAlternativesLoot,addSequenceLoot的区别是

  • 添加多个战利品列表,所有战利品列表都会生效
  • 若一个 Loot 不触发,则停止该 Loot 往下进行的修改

这里的所有列表都会生效的意思是,当一个条目的战利品列表停止触发后,接下来往下对 LootTable 的修改将不会再进行

js
LootJS.modifiers((event) => {
    event
        .addBlockLootModifier("minecraft:coal_ore")
        .removeLoot(Ingredient.all)
        .addSequenceLoot(
            LootEntry.of("minecraft:apple").when((c) => c.randomChance(0.8)),
            LootEntry.of("minecraft:stick").when((c) => c.randomChance(0.3)),
            LootEntry.of("minecraft:diamond").when((c) => c.randomChance(0.7)),
            LootEntry.of("minecraft:coal").when((c) => c.randomChance(0.99)),
            LootEntry.of("minecraft:torch").when((c) => c.randomChance(0.2))
        );
});

例如上述例子所示,若minecraft:apple触发并掉落,则接着触发minecraft:stick的 Loot.

minecraft:stick的 Loot 未触发,则该 LootTable 就不会进行下去,终止在掉落一个苹果,以此类推

minecraft:stick触发,minecraft:diamond触发,minecraft:coal不触发则会掉落苹果,木棍,以及钻石(煤炭和火把则不会掉落)

以此类推

添加加权战利品

addWeightedLoot(NumberProvider, [...items])

可以对任意方块/生物/战利品列表对于的 Loot 进行权重修改

以下的示例对minecraft:creeper进行展开:

  • 使用removeLoot来删除原版所有的 Loot.
  • addWeightedLoot语句来添加加权战利品
js
LootJS.modifiers((event) => {
    event
        .addEntityLootModifier("minecraft:creeper")
        .removeLoot(Ingredient.all)
        .addWeightedLoot(
            [7, 8],
            [
                Item.of("minecraft:gunpowder").withChance(20),
                Item.of("minecraft:nether_star").withChance(80),
            ]
        );
});
js
LootJS.modifiers((event) => {
    event
        .addEntityLootModifier("minecraft:creeper")
        .addWeightedLoot(5, [
            Item.of("minecraft:gunpowder").withChance(50),
            Item.of("minecraft:nether_star").withChance(50),
        ]);
});
js
LootJS.modifiers((event) => {
    event
        .addEntityLootModifier("minecraft:creeper")
        .addWeightedLoot([
            Item.of("minecraft:gunpowder").withChance(50),
            Item.of("minecraft:nether_star").withChance(5),
        ]);
});

Example-1:[7,8]的意思是对于"minecraft:gunpowder"以及"minecraft:nether_star"两个物品合起来的的掉落数量最少为 7 个,最多为 8 个

withChance(50)规定在这 7 个或者 8 个掉落物当中各个物品的占比,上述示例的占比就各占了 50%.而掉落物品的数量是随机的,在[7,8]之间随机抽取一个数字

Example-2:对于掉落物品数量还有另一种写法,相较于使用集合表示,你可以直接填写数字,则两个物品的掉落物数量总和就是 5.两个物品掉落数量的权重依旧各占 50%

Example-3:如果在addWeightedLoot中未指定掉落物品数量的时候,掉落物数量总和始终为集合[1,1]

删除战利品列表

removeLoot(ItemFilter)

上述我们在演示的时候已经提及到关于删除战利品列表的代码

removeLoot语句中是一个物品选择器,即ItemFilter

例如:

  • removeLoot(ItemID) 删除对应 LootTable 的 ItemID
  • removeLoot(Ingredient.all) 删除对应 LootTable 的所有 Loot
js
LootJS.modifiers((event) => {
    event
        .addBlockLootModifier("minecraft:gravel")
        .removeLoot("minecraft:flint");
});

替换战利品

replaceLoot(ItemFilter, item)

replaceLoot(ItemFilter, item, preserveCount)

同样的在replaceLoot语句中也是一个 ItemFilter

  • replace(originItemID,replaceItemID)
  • replace(originItemID,replaceItemID,Boolean)

在这个例子中,我们用钻石代替沙砾 LootTable 中的燧石。

js
LootJS.modifiers((event) => {
    event
        .addBlockLootModifier("minecraft:gravel")
        .replaceLoot("minecraft:flint", "minecraft:diamond");
});
js
LootJS.modifiers((event) => {
    event
        .addBlockLootModifier("minecraft:gravel")
        .replaceLoot("minecraft:flint", "minecraft:diamond", true); //flase
});

经过测试后,在replaceLoot语句后加 Boolean 值没有任何变化

修改战利品

modifyLoot(ItemFilter, callback)

修改煤炭矿石的 LootTable 对于modifyLoot语句:

  • Ingredient.all是个ItemFilter,用于指定该物品/生物/战利品列表要修改的物品
  • 回调函数ItemStack修改ItemFilter的属性

下面的示例修改了煤矿所有的战利品列表(Ingredient.all),回调函数 ItemStack 获取战利品列表里面的物品,设置了掉落物数量为 2,返回新的 ItemStack 到煤炭矿石的战利品列表

js
LootJS.modifiers((event) => {
    event
        .addBlockLootModifier("minecraft:coal_ore")
        .modifyLoot(Ingredient.all, (itemStack) => {
            itemStack.setCount(itemStack.getCount() * 2);
            return itemStack;
        });
});

触发爆炸

triggerExplosion(radius, destroy, fire)

注意:该示例仅适用于1.19.2,对于1.20.1不兼容

在战利品生成的位置触发爆炸triggerExplosion()

item不会被摧毁,radius可以是任意的数字floatdestory以及fire传入的参数都是boolean

js
LootJS.modifiers((event) => {
    event
        .addBlockLootModifier("minecraft:gravel")
        .triggerExplosion(1, false, false);
});

对于 1.20.1,triggerExplosion()的第二个传参变成了$Explosion$BlockInteraction$Type,不再是 boolean.

Logo

下面是一个 1.20.1 的示例

js
LootJS.modifiers((event) => {
    event
        .addBlockLootModifier("minecraft:coal_ore")
        .triggerExplosion(1, "destory", false);
});

触发雷电

triggerLightningStrike(shouldDamage)

在战利品生成的位置触发雷电triggerLightningStrike()

对于此方法,1.19.2 以及 1.20.1 传入的参数都是boolean

js
LootJS.modifiers((event) => {
    event.addBlockLootModifier("minecraft:gravel").triggerLightningStrike(true);
});

掉落经验值

dropExperience(amount)

在战利品生成的位置会掉落对应的经验值dropExperience()

这里掉落的经验值是按points计算,而不是level

js
LootJS.modifiers((event) => {
    event.addBlockLootModifier("minecraft:gravel").dropExperience(10);
});

战利品池修改

pool(callback)

针对某一生物/方块/战利品列表的战利品池进行修改

minecraft:creeper的战利品池进行修改:

  • 添加一个新的战利品池pool回调函数
  • rolls()设置这个池子的掉落次数为 1 到 3 次(随机掉落,在集合[1,3]之间掉落)
  • randomChance()设置一个 30% 的概率来触发这个掉落。
  • or(() => { })来进行添加额外的条件,下列示例中使用回调函数or来进行修改
  • anyBiome()满足条件在指定的生物群系中
  • lightLevel()满足光照等级在0-7之间
  • 若上述所有条件满足,使用addLoot()进行战利品池内物品添加

我们未对原版minecraft:creeper的战利品(火药)进行删除

最终我们会看到,在丛林生物群系中,或者光照等级为 0-7 之间的地方击杀minecraft:creeper后会掉落火药,以及 1-3 个不等的钻石(触发概率为 30%)

or()语句的回调函数只要满足一个条件为真即可触发战利品的修改

js
LootJS.modifiers((event) => {
    event.addEntityLootModifier("minecraft:creeper").pool((pool) => {
        pool.rolls([1, 3]);
        pool.randomChance(0.3)
            .or((or) => {
                or.anyBiome("minecraft:jungle");
                or.lightLevel(0, 7);
            })
            .addLoot("minecraft:diamond");
    });
});

更多的方法请使用ProbeJs进行查询

玩家 Action

playerAction(callback)

在进行战利品修改后可以对玩家的Action进行一些修改,例如:

  • 给予玩家经验值
  • 给予玩家物品

这里的回调函数是LootJs本身提供针对于player的类,而不是KubeJSplayer

js
LootJS.modifiers((event) => {
    event
        .addBlockLootModifier("minecraft:diamond_block")
        .playerAction((player) => {
            player.giveExperiencePoints(100);
            player.give("acacia_boat");
        });
});

上述代码中针对于minecraft:diamond_block进行了Action修改,玩家破坏钻石块生成了战利品后给予玩家 100 points 的经验值以及一个金合欢木船

apply 应用

apply(callback)

对应的回调函数是LootJs提供的类$LootContextJS

更多关于$LootContextJS的方法请使用ProbeJs进行查看

下面的示例代码是在minecraft:gravel的战利品生成后获取该方块的BlockPos,最后在控制台的日志输出中打印出来

js
LootJS.modifiers((event) => {
    event.addBlockLootModifier("minecraft:gravel").apply((context) => {
        let BlockPos = context.getBlockPos();
        console.log(BlockPos);
    });
});

输出的内容请见logs/kubejs/server.log