Skip to content

Commit

Permalink
Add LootEntry.of(tag/modid) and LootEntry.ofJson(json)
Browse files Browse the repository at this point in the history
  • Loading branch information
LLytho committed Feb 10, 2024
1 parent 81da022 commit 506b1fd
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning].
## [Unreleased]
- /

## [2.11.0] - 2023-02-11
### Added
- Added `LootEntry.of("#tag")`, `LootEntry.of("@modid")` to select a random entry from a tag or modid.
- Added `LootEntry.ofJson(json)` to create a loot entry from JSON to support custom entries from other mods

## [2.10.4] - 2023-12-07
### Fixed
- Crash with newest kubejs version
Expand Down
59 changes: 56 additions & 3 deletions Common/src/main/java/com/almostreliable/lootjs/core/LootEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import com.almostreliable.lootjs.loot.LootFunctionsContainer;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer;
import net.minecraft.world.level.storage.loot.functions.LootItemFunction;

import javax.annotation.Nullable;
Expand All @@ -14,17 +16,21 @@

public class LootEntry implements LootFunctionsContainer<LootEntry> {

private final ItemStack itemStack;
private final Generator generator;
private final List<LootItemFunction> postModifications = new ArrayList<>();
private final List<ILootCondition> conditions = new ArrayList<>();
private int weight = 1;

public LootEntry(Item item) {
this.itemStack = new ItemStack(item);
this.generator = new ItemGenerator(new ItemStack(item));
}

public LootEntry(ItemStack itemStack) {
this.itemStack = itemStack;
this.generator = new ItemGenerator(itemStack);
}

public LootEntry(Generator generator) {
this.generator = generator;
}

/**
Expand All @@ -39,6 +45,11 @@ public ItemStack createItem(LootContext context) {
return null;
}

ItemStack itemStack = generator.create(context);
if (itemStack == null) {
return null;
}

if (itemStack.isEmpty()) {
return ItemStack.EMPTY;
}
Expand Down Expand Up @@ -98,4 +109,46 @@ public LootConditionsContainer<?> addCondition(ILootCondition condition) {
this.conditions.addAll(conditions);
return this;
}

public interface Generator {

@Nullable
ItemStack create(LootContext context);
}

public record ItemGenerator(ItemStack item) implements Generator {
@Nullable
@Override
public ItemStack create(LootContext context) {
return item;
}
}

public record RandomIngredientGenerator(Ingredient ingredient) implements Generator {
@Nullable
@Override
public ItemStack create(LootContext context) {
ItemStack[] items = ingredient.getItems();
if (items.length == 0) {
return ItemStack.EMPTY;
}

int index = context.getRandom().nextInt(items.length);
return items[index];
}
}

public record VanillaWrappedLootEntry(LootPoolEntryContainer entry) implements Generator {
@Override
public ItemStack create(LootContext context) {
List<ItemStack> items = new ArrayList<>();
entry.expand(context, entry -> entry.createItemStack(items::add, context));

if (items.isEmpty()) {
return null;
}

return items.get(context.getRandom().nextInt(items.size()));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
package com.almostreliable.lootjs.kube;

import com.almostreliable.lootjs.LootJS;
import com.almostreliable.lootjs.core.LootEntry;
import dev.latvian.mods.kubejs.item.ItemStackJS;
import com.google.gson.JsonObject;
import dev.latvian.mods.kubejs.item.OutputItem;
import dev.latvian.mods.kubejs.item.ingredient.IngredientJS;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer;

public class LootEntryWrapper {
public static LootEntry of(Object o) {
if (o instanceof LootEntry entry) {
return entry;
}

if (o instanceof Ingredient ingredient) {
return new LootEntry(new LootEntry.RandomIngredientGenerator(ingredient));
}

if (o instanceof CharSequence cs) {
String string = cs.toString();
if (string.startsWith("#") || string.startsWith("@")) {
return of(IngredientJS.of(string));
}
}

OutputItem outputItem = OutputItem.of(o);
int weight = Double.isNaN(outputItem.getChance()) ? 1 : (int) outputItem.getChance();
int weight = Double.isNaN(outputItem.getChance()) ? 1 : (int) outputItem.getChance();
return new LootEntry(outputItem.item).withWeight(weight);
}

Expand All @@ -29,6 +44,16 @@ public static LootEntry of(ItemStack in, int count, CompoundTag nbt) {
return of(in.kjs$withCount(count).kjs$withNBT(nbt));
}

public static LootEntry ofJson(JsonObject json) {
try {
var container = LootJS.FUNCTION_GSON.fromJson(json, LootPoolEntryContainer.class);
return new LootEntry(new LootEntry.VanillaWrappedLootEntry(container));
} catch (Exception e) {
LootJS.LOG.error("Failed to parse loot entry: " + json);
return new LootEntry(ItemStack.EMPTY);
}
}

public static LootEntry withChance(Object o, int chance) {
return of(o).withChance(chance);
}
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ enableAccessWidener = true
modPackage = com.almostreliable.lootjs
modId = lootjs
modName = LootJS
modVersion = 2.10.4
modVersion = 2.11.0
modAuthor = AlmostReliable
modDescription = Modify global loot drops through KubeJS.

Expand Down

0 comments on commit 506b1fd

Please sign in to comment.