From af6e84822746f6eff5b20b045e08ffa2f4ab0d82 Mon Sep 17 00:00:00 2001
From: LexManos
Date: Wed, 20 Sep 2023 15:24:46 -0700
Subject: [PATCH] Global Loot Modifiers
---
build.gradle | 3 +-
.../advancements/Advancement.java.patch | 13 ++
.../resources/DelegatingOps.java.patch | 36 ++++
.../resources/RegistryDataLoader.java.patch | 24 ++-
.../resources/RegistryOps.java.patch | 37 +++-
.../ServerGamePacketListenerImpl.java.patch | 2 +-
.../world/entity/LivingEntity.java.patch | 4 +-
.../PersistentEntitySectionManager.java.patch | 2 +-
.../TransientEntitySectionManager.java.patch | 2 +-
.../level/storage/loot/LootContext.java.patch | 4 +-
.../storage/loot/LootDataType.java.patch | 14 ++
.../level/storage/loot/LootPool.java.patch | 95 ++++++++++
.../level/storage/loot/LootTable.java.patch | 41 ++++-
.../loot_modifiers/global_loot_modifiers.json | 9 +
.../loot_modifiers/bamboo_silk.json | 13 ++
.../loot_modifiers/dungeon_loot.json | 9 +
.../loot_modifiers/smelting.json | 18 ++
.../loot_modifiers/wheat_harvest.json | 20 +++
src/generated_test/resources/pack.mcmeta | 8 +
.../net/minecraftforge/common/ForgeHooks.java | 133 +++-----------
.../common/ForgeInternalHandler.java | 5 +-
.../net/minecraftforge/common/ForgeMod.java | 46 +++--
.../net/minecraftforge/common/ToolAction.java | 22 +--
.../common/crafting/AbstractIngredient.java | 94 ----------
.../common/crafting/CompoundIngredient.java | 88 ++-------
.../common/crafting/CraftingHelper.java | 38 +---
.../crafting/IIngredientSerializer.java | 22 ---
.../common/crafting/MultiItemValue.java | 57 ------
.../common/crafting/StrictNBTIngredient.java | 72 ++------
.../crafting/VanillaIngredientSerializer.java | 39 ----
.../crafting/conditions/AndCondition.java | 82 ++-------
.../crafting/conditions/ConditionCodec.java | 66 +++++++
.../crafting/conditions/ConditionContext.java | 44 ++---
.../crafting/conditions/FalseCondition.java | 43 +----
.../crafting/conditions/ICondition.java | 47 +++--
.../conditions/IConditionBuilder.java | 38 ++--
.../conditions/IConditionSerializer.java | 27 ---
.../conditions/ItemExistsCondition.java | 63 ++-----
.../conditions/ModLoadedCondition.java | 55 ++----
.../crafting/conditions/NotCondition.java | 55 ++----
.../crafting/conditions/OrCondition.java | 81 ++-------
.../conditions/TagEmptyCondition.java | 63 ++-----
.../crafting/conditions/TrueCondition.java | 42 +----
.../data/GlobalLootModifierProvider.java | 11 +-
.../common/loot/CanToolPerformAction.java | 54 ++----
.../common/loot/IGlobalLootModifier.java | 48 ++---
.../common/loot/LootModifier.java | 26 ++-
.../common/loot/LootModifierManager.java | 88 +++++----
.../common/loot/LootTableIdCondition.java | 76 +++-----
.../common/util/FakePlayer.java | 4 +-
.../common/util/FakePlayerFactory.java | 15 +-
.../event/ForgeEventFactory.java | 21 ++-
.../ForgeDeferredRegistriesSetup.java | 3 +-
.../registries/ForgeRegistries.java | 18 +-
.../minecraftforge/registries/GameData.java | 22 ++-
.../debug/CreativeModeTabTest.java | 102 +++++------
.../loot/GlobalLootModifiersTest.java | 169 ++++++++++--------
.../java/net/minecraftforge/test/Empty.java | 57 +++++-
src/test/resources/META-INF/mods.toml | 16 +-
.../debug/DataGeneratorTest.java | 73 +++-----
.../debug/fluid/NewFluidTest.java | 60 +++----
.../debug/gameplay/loot/package-info.java | 11 --
src/test_old/resources/META-INF/mods.toml | 10 --
63 files changed, 1058 insertions(+), 1502 deletions(-)
create mode 100644 patches/minecraft/net/minecraft/resources/DelegatingOps.java.patch
create mode 100644 patches/minecraft/net/minecraft/world/level/storage/loot/LootDataType.java.patch
create mode 100644 patches/minecraft/net/minecraft/world/level/storage/loot/LootPool.java.patch
create mode 100644 src/generated_test/resources/data/forge/loot_modifiers/global_loot_modifiers.json
create mode 100644 src/generated_test/resources/data/global_loot_test/loot_modifiers/bamboo_silk.json
create mode 100644 src/generated_test/resources/data/global_loot_test/loot_modifiers/dungeon_loot.json
create mode 100644 src/generated_test/resources/data/global_loot_test/loot_modifiers/smelting.json
create mode 100644 src/generated_test/resources/data/global_loot_test/loot_modifiers/wheat_harvest.json
create mode 100644 src/generated_test/resources/pack.mcmeta
delete mode 100644 src/main/java/net/minecraftforge/common/crafting/AbstractIngredient.java
delete mode 100644 src/main/java/net/minecraftforge/common/crafting/IIngredientSerializer.java
delete mode 100644 src/main/java/net/minecraftforge/common/crafting/MultiItemValue.java
delete mode 100644 src/main/java/net/minecraftforge/common/crafting/VanillaIngredientSerializer.java
create mode 100644 src/main/java/net/minecraftforge/common/crafting/conditions/ConditionCodec.java
delete mode 100644 src/main/java/net/minecraftforge/common/crafting/conditions/IConditionSerializer.java
rename src/{test_old => test}/java/net/minecraftforge/debug/CreativeModeTabTest.java (67%)
rename src/{test_old => test}/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java (63%)
delete mode 100644 src/test_old/java/net/minecraftforge/debug/gameplay/loot/package-info.java
diff --git a/build.gradle b/build.gradle
index 091273d996..7a7ab560e9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -769,9 +769,10 @@ project(':forge') {
}
args '--flat', '--all', '--validate',
+ '--mod', 'empty',
//'--mod', 'data_gen_test',
//'--mod', 'piston_event_test',
- //'--mod', 'global_loot_test',
+ '--mod', 'global_loot_test',
//'--mod', 'scaffolding_test',
//'--mod', 'custom_tag_types_test',
//'--mod', 'new_model_loader_test',
diff --git a/patches/minecraft/net/minecraft/advancements/Advancement.java.patch b/patches/minecraft/net/minecraft/advancements/Advancement.java.patch
index 9288588edd..7a25438646 100644
--- a/patches/minecraft/net/minecraft/advancements/Advancement.java.patch
+++ b/patches/minecraft/net/minecraft/advancements/Advancement.java.patch
@@ -15,3 +15,16 @@
Optional optional = p_300691_.has("parent") ? Optional.of(new ResourceLocation(GsonHelper.getAsString(p_300691_, "parent"))) : Optional.empty();
Optional optional1 = p_300691_.has("display") ? Optional.of(DisplayInfo.fromJson(GsonHelper.getAsJsonObject(p_300691_, "display"))) : Optional.empty();
AdvancementRewards advancementrewards = p_300691_.has("rewards") ? AdvancementRewards.deserialize(GsonHelper.getAsJsonObject(p_300691_, "rewards")) : AdvancementRewards.EMPTY;
+@@ -182,7 +_,11 @@
+ }
+
+ public AdvancementHolder save(Consumer p_138390_, String p_138391_) {
+- AdvancementHolder advancementholder = this.build(new ResourceLocation(p_138391_));
++ return save(p_138390_, new ResourceLocation(p_138391_));
++ }
++
++ public AdvancementHolder save(Consumer p_138390_, ResourceLocation id) {
++ AdvancementHolder advancementholder = this.build(id);
+ p_138390_.accept(advancementholder);
+ return advancementholder;
+ }
diff --git a/patches/minecraft/net/minecraft/resources/DelegatingOps.java.patch b/patches/minecraft/net/minecraft/resources/DelegatingOps.java.patch
new file mode 100644
index 0000000000..8818b2dae0
--- /dev/null
+++ b/patches/minecraft/net/minecraft/resources/DelegatingOps.java.patch
@@ -0,0 +1,36 @@
+--- a/net/minecraft/resources/DelegatingOps.java
++++ b/net/minecraft/resources/DelegatingOps.java
+@@ -160,4 +_,33 @@
+ public RecordBuilder mapBuilder() {
+ return new RecordBuilder.MapBuilder<>(this);
+ }
++
++ java.util.Map ctx;
++ public R getContext(ResourceLocation rl) {
++ return (R)this.ctx.get(rl);
++ }
++
++ public static > Builder builder(java.util.function.Supplier root) {
++ return new Builder(root);
++ }
++
++ public static class Builder> {
++ private final java.util.function.Supplier func;
++ private final java.util.Map ctx = new java.util.HashMap<>();
++
++ private Builder(java.util.function.Supplier func) {
++ this.func = func;
++ }
++
++ public Builder with(ResourceLocation key, Object ctx) {
++ this.ctx.put(key, ctx);
++ return this;
++ }
++
++ public R build() {
++ var ret = this.func.get();
++ ret.ctx = this.ctx;
++ return ret;
++ }
++ }
+ }
diff --git a/patches/minecraft/net/minecraft/resources/RegistryDataLoader.java.patch b/patches/minecraft/net/minecraft/resources/RegistryDataLoader.java.patch
index e4406c5e63..b99e5c0aee 100644
--- a/patches/minecraft/net/minecraft/resources/RegistryDataLoader.java.patch
+++ b/patches/minecraft/net/minecraft/resources/RegistryDataLoader.java.patch
@@ -1,6 +1,6 @@
--- a/net/minecraft/resources/RegistryDataLoader.java
+++ b/net/minecraft/resources/RegistryDataLoader.java
-@@ -123,7 +_,7 @@
+@@ -123,13 +_,16 @@
}
private static String registryDirPath(ResourceLocation p_252033_) {
@@ -9,11 +9,27 @@
}
static void loadRegistryContents(RegistryOps.RegistryInfoLookup p_256369_, ResourceManager p_256349_, ResourceKey extends Registry> p_255792_, WritableRegistry p_256211_, Decoder p_256232_, Map, Exception> p_255884_) {
-@@ -139,6 +_,7 @@
+ String s = registryDirPath(p_255792_.location());
+ FileToIdConverter filetoidconverter = FileToIdConverter.json(s);
+- RegistryOps registryops = RegistryOps.create(JsonOps.INSTANCE, p_256369_);
++ RegistryOps registryops = RegistryOps.builder(JsonOps.INSTANCE, p_256369_)
++ .with(net.minecraftforge.common.crafting.conditions.ICondition.IContext.KEY, net.minecraftforge.common.crafting.conditions.ICondition.IContext.TAGS_INVALID)
++ .build();
++ Decoder> conditional = net.minecraftforge.common.crafting.conditions.ConditionCodec.wrap(p_256232_);
+
+ for(Map.Entry entry : filetoidconverter.listMatchingResources(p_256349_).entrySet()) {
+ ResourceLocation resourcelocation = entry.getKey();
+@@ -138,7 +_,12 @@
+
try (Reader reader = resource.openAsReader()) {
JsonElement jsonelement = JsonParser.parseReader(reader);
- DataResult dataresult = p_256232_.parse(registryops, jsonelement);
-+ if (!net.minecraftforge.common.crafting.conditions.ICondition.shouldRegisterEntry(jsonelement)) continue;
+- DataResult dataresult = p_256232_.parse(registryops, jsonelement);
++ var result = conditional.decode(registryops, jsonelement);
++ if (result.result().map(p -> p.getFirst()).isEmpty()) {
++ LOGGER.debug("Skipping {} conditions not met", resourcelocation);
++ continue;
++ }
++ DataResult dataresult = result.map(p -> p.mapFirst(Optional::get)).map(p -> p.getFirst());
E e = dataresult.getOrThrow(false, (p_248715_) -> {
});
p_256211_.register(resourcekey, e, resource.isBuiltin() ? Lifecycle.stable() : dataresult.lifecycle());
diff --git a/patches/minecraft/net/minecraft/resources/RegistryOps.java.patch b/patches/minecraft/net/minecraft/resources/RegistryOps.java.patch
index 93c5fa962c..222bc00484 100644
--- a/patches/minecraft/net/minecraft/resources/RegistryOps.java.patch
+++ b/patches/minecraft/net/minecraft/resources/RegistryOps.java.patch
@@ -1,9 +1,33 @@
--- a/net/minecraft/resources/RegistryOps.java
+++ b/net/minecraft/resources/RegistryOps.java
-@@ -74,6 +_,20 @@
- });
+@@ -41,11 +_,20 @@
+ return new RegistryOps<>(p_256278_, p_256479_);
}
++ public static DelegatingOps.Builder> builder(DynamicOps parent, RegistryOps.RegistryInfoLookup lookup) {
++ return DelegatingOps.builder(() -> create(parent, lookup));
++ }
++
+ private RegistryOps(DynamicOps p_256313_, RegistryOps.RegistryInfoLookup p_255799_) {
+ super(p_256313_);
+ this.lookupProvider = p_255799_;
+ }
+
++ public RegistryOps(RegistryOps parent) {
++ super(parent);
++ this.lookupProvider = parent.lookupProvider;
++ }
++
+ public Optional> owner(ResourceKey extends Registry extends E>> p_255757_) {
+ return this.lookupProvider.lookup(p_255757_).map(RegistryOps.RegistryInfo::owner);
+ }
+@@ -71,6 +_,20 @@
+ }
+ }).forGetter((p_255526_) -> {
+ return null;
++ });
++ }
++
+ public static com.mojang.serialization.MapCodec> retrieveRegistryLookup(ResourceKey extends Registry extends E>> resourceKey) {
+ return ExtraCodecs.retrieveContext(ops -> {
+ if (!(ops instanceof RegistryOps> registryOps))
@@ -15,9 +39,6 @@
+
+ return DataResult.success(registryLookup, registryInfo.elementsLifecycle());
+ }).orElseGet(() -> DataResult.error(() -> "Unknown registry: " + resourceKey));
-+ });
-+ }
-+
- public static RecordCodecBuilder> retrieveElement(ResourceKey p_256347_) {
- ResourceKey extends Registry> resourcekey = ResourceKey.createRegistryKey(p_256347_.registry());
- return ExtraCodecs.retrieveContext((p_274808_) -> {
+ });
+ }
+
diff --git a/patches/minecraft/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/patches/minecraft/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch
index 85a03518a6..8b60027ed8 100644
--- a/patches/minecraft/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch
+++ b/patches/minecraft/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch
@@ -31,7 +31,7 @@
ItemStack itemstack = this.player.getItemInHand(InteractionHand.OFF_HAND);
- this.player.setItemInHand(InteractionHand.OFF_HAND, this.player.getItemInHand(InteractionHand.MAIN_HAND));
- this.player.setItemInHand(InteractionHand.MAIN_HAND, itemstack);
-+ var event = net.minecraftforge.common.ForgeHooks.onLivingSwapHandItems(this.player);
++ var event = net.minecraftforge.event.ForgeEventFactory.onLivingSwapHandItems(this.player);
+ if (event.isCanceled()) return;
+ this.player.setItemInHand(InteractionHand.OFF_HAND, event.getItemSwappedToOffHand());
+ this.player.setItemInHand(InteractionHand.MAIN_HAND, event.getItemSwappedToMainHand());
diff --git a/patches/minecraft/net/minecraft/world/entity/LivingEntity.java.patch b/patches/minecraft/net/minecraft/world/entity/LivingEntity.java.patch
index 5179826f84..e73b998e7d 100644
--- a/patches/minecraft/net/minecraft/world/entity/LivingEntity.java.patch
+++ b/patches/minecraft/net/minecraft/world/entity/LivingEntity.java.patch
@@ -173,7 +173,7 @@
- this.hurtCurrentlyUsedShield(p_21017_);
- f1 = p_21017_;
- p_21017_ = 0.0F;
-+ var ev = net.minecraftforge.common.ForgeHooks.onShieldBlock(this, p_21016_, p_21017_);
++ var ev = net.minecraftforge.event.ForgeEventFactory.onShieldBlock(this, p_21016_, p_21017_);
+ if(!ev.isCanceled()) {
+ if(ev.shieldTakesDamage()) this.hurtCurrentlyUsedShield(p_21017_);
+ f1 = ev.getBlockedDamage();
@@ -391,7 +391,7 @@
ItemStack itemstack = this.getItemBySlot(EquipmentSlot.OFFHAND);
- this.setItemSlot(EquipmentSlot.OFFHAND, this.getItemBySlot(EquipmentSlot.MAINHAND));
- this.setItemSlot(EquipmentSlot.MAINHAND, itemstack);
-+ var event = net.minecraftforge.common.ForgeHooks.onLivingSwapHandItems(this);
++ var event = net.minecraftforge.event.ForgeEventFactory.onLivingSwapHandItems(this);
+ if (event.isCanceled()) return;
+ this.setItemSlot(EquipmentSlot.OFFHAND, event.getItemSwappedToOffHand());
+ this.setItemSlot(EquipmentSlot.MAINHAND, event.getItemSwappedToMainHand());
diff --git a/patches/minecraft/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch b/patches/minecraft/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch
index f0c81f8db5..5c0e2bf1f6 100644
--- a/patches/minecraft/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch
+++ b/patches/minecraft/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch
@@ -62,7 +62,7 @@
this.currentSection = entitysection;
this.currentSectionKey = i;
this.updateStatus(visibility, entitysection.getStatus());
-+ if (this.realEntity != null) net.minecraftforge.common.ForgeHooks.onEntityEnterSection(this.realEntity, oldSectionKey, i);
++ if (this.realEntity != null) net.minecraftforge.event.ForgeEventFactory.onEntityEnterSection(this.realEntity, oldSectionKey, i);
}
}
diff --git a/patches/minecraft/net/minecraft/world/level/entity/TransientEntitySectionManager.java.patch b/patches/minecraft/net/minecraft/world/level/entity/TransientEntitySectionManager.java.patch
index 39578727b1..c9421c9469 100644
--- a/patches/minecraft/net/minecraft/world/level/entity/TransientEntitySectionManager.java.patch
+++ b/patches/minecraft/net/minecraft/world/level/entity/TransientEntitySectionManager.java.patch
@@ -26,7 +26,7 @@
TransientEntitySectionManager.this.callbacks.onTickingStart(this.entity);
}
}
-+ if (this.realEntity != null) net.minecraftforge.common.ForgeHooks.onEntityEnterSection(this.realEntity, oldSectionKey, i);
++ if (this.realEntity != null) net.minecraftforge.event.ForgeEventFactory.onEntityEnterSection(this.realEntity, oldSectionKey, i);
}
}
diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/LootContext.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/LootContext.java.patch
index 8bef637a74..084a075280 100644
--- a/patches/minecraft/net/minecraft/world/level/storage/loot/LootContext.java.patch
+++ b/patches/minecraft/net/minecraft/world/level/storage/loot/LootContext.java.patch
@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/storage/loot/LootContext.java
+++ b/net/minecraft/world/level/storage/loot/LootContext.java
-@@ -86,15 +_,45 @@
+@@ -86,15 +_,43 @@
return new LootContext.VisitedEntry<>(LootDataType.MODIFIER, p_279163_);
}
@@ -16,7 +16,6 @@
+ this.queriedLootTableId = queriedLootTableId;
+ }
+
-+ /*
+ public void setQueriedLootTableId(ResourceLocation queriedLootTableId) {
+ if (this.queriedLootTableId == null && queriedLootTableId != null) this.queriedLootTableId = queriedLootTableId;
+ }
@@ -24,7 +23,6 @@
+ public ResourceLocation getQueriedLootTableId() {
+ return this.queriedLootTableId == null ? net.minecraftforge.common.loot.LootTableIdCondition.UNKNOWN_LOOT_TABLE : this.queriedLootTableId;
+ }
-+ */
+ // =============================== FORGE END ===============================
+
public static class Builder {
diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/LootDataType.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/LootDataType.java.patch
new file mode 100644
index 0000000000..0ee807b4c6
--- /dev/null
+++ b/patches/minecraft/net/minecraft/world/level/storage/loot/LootDataType.java.patch
@@ -0,0 +1,14 @@
+--- a/net/minecraft/world/level/storage/loot/LootDataType.java
++++ b/net/minecraft/world/level/storage/loot/LootDataType.java
+@@ -42,7 +_,10 @@
+ dataresult.error().ifPresent((p_297003_) -> {
+ LOGGER.error("Couldn't parse element {}:{} - {}", this.directory, p_279253_, p_297003_.message());
+ });
+- return dataresult.result();
++ var ret = dataresult.result();
++ if (this == TABLE && ret.isPresent())
++ ret = Optional.ofNullable((T)net.minecraftforge.event.ForgeEventFactory.onLoadLootTable(p_279253_, (LootTable)ret.get()));
++ return ret;
+ }
+
+ public static Stream> values() {
diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/LootPool.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/LootPool.java.patch
new file mode 100644
index 0000000000..a100d96c48
--- /dev/null
+++ b/patches/minecraft/net/minecraft/world/level/storage/loot/LootPool.java.patch
@@ -0,0 +1,95 @@
+--- a/net/minecraft/world/level/storage/loot/LootPool.java
++++ b/net/minecraft/world/level/storage/loot/LootPool.java
+@@ -38,8 +_,12 @@
+ return p_297004_.rolls;
+ }), NumberProviders.CODEC.fieldOf("bonus_rolls").orElse(ConstantValue.exactly(0.0F)).forGetter((p_297006_) -> {
+ return p_297006_.bonusRolls;
+- })).apply(p_297005_, LootPool::new);
++ }),
++ Codec.STRING.optionalFieldOf("name").forGetter(p -> p.name.filter(n -> !n.startsWith("custom#"))),
++ net.minecraftforge.common.crafting.conditions.ICondition.OPTIONAL_FEILD_CODEC.forGetter(p -> p.forge_condition)
++ ).apply(p_297005_, LootPool::new);
+ });
++ public static final Codec CONDITIONAL_CODEC = net.minecraftforge.common.crafting.conditions.ConditionCodec.checkingDecode(CODEC);
+ private final List entries;
+ private final List conditions;
+ private final Predicate compositeCondition;
+@@ -47,8 +_,13 @@
+ private final BiFunction compositeFunction;
+ private NumberProvider rolls;
+ private NumberProvider bonusRolls;
++ private java.util.Optional name;
++ private java.util.Optional forge_condition;
+
+ LootPool(List p_298341_, List p_297697_, List p_299722_, NumberProvider p_165131_, NumberProvider p_165132_) {
++ this(p_298341_, p_297697_, p_299722_, p_165131_, p_165132_, java.util.Optional.empty(), java.util.Optional.empty());
++ }
++ LootPool(List p_298341_, List p_297697_, List p_299722_, NumberProvider p_165131_, NumberProvider p_165132_, java.util.Optional name, java.util.Optional forge_conditions) {
+ this.entries = p_298341_;
+ this.conditions = p_297697_;
+ this.compositeCondition = LootItemConditions.andConditions(p_297697_);
+@@ -56,6 +_,8 @@
+ this.compositeFunction = LootItemFunctions.compose(p_299722_);
+ this.rolls = p_165131_;
+ this.bonusRolls = p_165132_;
++ this.name = name;
++ this.forge_condition = forge_conditions;
+ }
+
+ private void addRandomItem(Consumer p_79059_, LootContext p_79060_) {
+@@ -126,12 +_,35 @@
+ return new LootPool.Builder();
+ }
+
++ private boolean isFrozen = false;
++ public void freeze() { this.isFrozen = true; }
++ public boolean isFrozen(){ return this.isFrozen; }
++ private void checkFrozen() {
++ if (this.isFrozen())
++ throw new RuntimeException("Attempted to modify LootPool after being frozen!");
++ }
++ @org.jetbrains.annotations.Nullable
++ public String getName() { return this.name.orElse(null); }
++ void setName(final String name) {
++ if (this.name.isPresent())
++ throw new UnsupportedOperationException("Cannot change the name of a pool when it has a name set!");
++ this.name = java.util.Optional.of(name);
++ }
++ public NumberProvider getRolls() { return this.rolls; }
++ public NumberProvider getBonusRolls() { return this.bonusRolls; }
++ public void setRolls (NumberProvider v){ checkFrozen(); this.rolls = v; }
++ public void setBonusRolls(NumberProvider v){ checkFrozen(); this.bonusRolls = v; }
++
+ public static class Builder implements FunctionUserBuilder, ConditionUserBuilder {
+ private final ImmutableList.Builder entries = ImmutableList.builder();
+ private final ImmutableList.Builder conditions = ImmutableList.builder();
+ private final ImmutableList.Builder functions = ImmutableList.builder();
+ private NumberProvider rolls = ConstantValue.exactly(1.0F);
+ private NumberProvider bonusRolls = ConstantValue.exactly(0.0F);
++ @org.jetbrains.annotations.Nullable
++ private String name;
++ @org.jetbrains.annotations.Nullable
++ private net.minecraftforge.common.crafting.conditions.ICondition forge_condition;
+
+ public LootPool.Builder setRolls(NumberProvider p_165134_) {
+ this.rolls = p_165134_;
+@@ -162,8 +_,18 @@
+ return this;
+ }
+
++ public LootPool.Builder name(String name) {
++ this.name = name;
++ return this;
++ }
++
++ public LootPool.Builder when(net.minecraftforge.common.crafting.conditions.ICondition value) {
++ this.forge_condition = value;
++ return this;
++ }
++
+ public LootPool build() {
+- return new LootPool(this.entries.build(), this.conditions.build(), this.functions.build(), this.rolls, this.bonusRolls);
++ return new LootPool(this.entries.build(), this.conditions.build(), this.functions.build(), this.rolls, this.bonusRolls, java.util.Optional.ofNullable(this.name), java.util.Optional.ofNullable(forge_condition));
+ }
+ }
+ }
diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/LootTable.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/LootTable.java.patch
index d4e3a37e58..24251e173f 100644
--- a/patches/minecraft/net/minecraft/world/level/storage/loot/LootTable.java.patch
+++ b/patches/minecraft/net/minecraft/world/level/storage/loot/LootTable.java.patch
@@ -1,5 +1,14 @@
--- a/net/minecraft/world/level/storage/loot/LootTable.java
+++ b/net/minecraft/world/level/storage/loot/LootTable.java
+@@ -35,7 +_,7 @@
+ return p_297013_.paramSet;
+ }), ExtraCodecs.strictOptionalField(ResourceLocation.CODEC, "random_sequence").forGetter((p_297014_) -> {
+ return p_297014_.randomSequence;
+- }), ExtraCodecs.strictOptionalField(LootPool.CODEC.listOf(), "pools", List.of()).forGetter((p_297012_) -> {
++ }), ExtraCodecs.strictOptionalField(LootPool.CONDITIONAL_CODEC.listOf(), "pools", List.of()).forGetter((p_297012_) -> {
+ return p_297012_.pools;
+ }), ExtraCodecs.strictOptionalField(LootItemFunctions.CODEC.listOf(), "functions", List.of()).forGetter((p_297010_) -> {
+ return p_297010_.functions;
@@ -50,7 +_,7 @@
LootTable(LootContextParamSet p_287716_, Optional p_298628_, List p_298771_, List p_301234_) {
this.paramSet = p_287716_;
@@ -47,11 +56,11 @@
ObjectArrayList objectarraylist = new ObjectArrayList<>();
- this.getRandomItems(p_230923_, objectarraylist::add);
+ this.getRandomItemsRaw(p_230923_, createStackSplitter(p_230923_.getLevel(), objectarraylist::add));
-+ //objectarraylist = net.minecraftforge.common.ForgeHooks.modifyLoot(this.getLootTableId(), objectarraylist, p_230923_); //TODO: GLM
++ objectarraylist = net.minecraftforge.common.ForgeHooks.modifyLoot(this.getLootTableId(), objectarraylist, p_230923_);
return objectarraylist;
}
-@@ -207,6 +_,23 @@
+@@ -207,6 +_,51 @@
public static LootTable.Builder lootTable() {
return new LootTable.Builder();
@@ -68,10 +77,38 @@
+ return this.lootTableId;
+ }
+
++ @org.jetbrains.annotations.Nullable
++ public LootPool removePool(String name) {
++ checkFrozen();
++ for (var pool : this.pools) {
++ if (name.equals(pool.getName())) {
++ this.pools.remove(pool);
++ return pool;
++ }
++ }
++ return null;
++ }
++
+ public void addPool(LootPool pool) {
++ checkFrozen();
+ if (pools.stream().anyMatch(e -> e == pool))
+ throw new RuntimeException("Attempted to add a duplicate pool to loot table: " + pool);
+ this.pools.add(pool);
++ }
++
++ private boolean isFrozen = false;
++ public void freeze() {
++ this.isFrozen = true;
++ this.pools.forEach(LootPool::freeze);
++ }
++
++ public boolean isFrozen() {
++ return this.isFrozen;
++ }
++
++ private void checkFrozen() {
++ if (this.isFrozen())
++ throw new RuntimeException("Attempted to modify LootTable after being finalized!");
}
public static class Builder implements FunctionUserBuilder {
diff --git a/src/generated_test/resources/data/forge/loot_modifiers/global_loot_modifiers.json b/src/generated_test/resources/data/forge/loot_modifiers/global_loot_modifiers.json
new file mode 100644
index 0000000000..86a059a62d
--- /dev/null
+++ b/src/generated_test/resources/data/forge/loot_modifiers/global_loot_modifiers.json
@@ -0,0 +1,9 @@
+{
+ "entries": [
+ "global_loot_test:dungeon_loot",
+ "global_loot_test:bamboo_silk",
+ "global_loot_test:wheat_harvest",
+ "global_loot_test:smelting"
+ ],
+ "replace": false
+}
\ No newline at end of file
diff --git a/src/generated_test/resources/data/global_loot_test/loot_modifiers/bamboo_silk.json b/src/generated_test/resources/data/global_loot_test/loot_modifiers/bamboo_silk.json
new file mode 100644
index 0000000000..09924fa32e
--- /dev/null
+++ b/src/generated_test/resources/data/global_loot_test/loot_modifiers/bamboo_silk.json
@@ -0,0 +1,13 @@
+{
+ "type": "global_loot_test:silk_touch_bamboo",
+ "conditions": [
+ {
+ "condition": "minecraft:match_tool",
+ "predicate": {
+ "items": [
+ "minecraft:bamboo"
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated_test/resources/data/global_loot_test/loot_modifiers/dungeon_loot.json b/src/generated_test/resources/data/global_loot_test/loot_modifiers/dungeon_loot.json
new file mode 100644
index 0000000000..5dba5b78d3
--- /dev/null
+++ b/src/generated_test/resources/data/global_loot_test/loot_modifiers/dungeon_loot.json
@@ -0,0 +1,9 @@
+{
+ "type": "global_loot_test:dungeon_loot",
+ "conditions": [
+ {
+ "condition": "forge:loot_table_id",
+ "loot_table_id": "minecraft:chests/simple_dungeon"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated_test/resources/data/global_loot_test/loot_modifiers/smelting.json b/src/generated_test/resources/data/global_loot_test/loot_modifiers/smelting.json
new file mode 100644
index 0000000000..09b17fd901
--- /dev/null
+++ b/src/generated_test/resources/data/global_loot_test/loot_modifiers/smelting.json
@@ -0,0 +1,18 @@
+{
+ "type": "global_loot_test:smelting",
+ "conditions": [
+ {
+ "condition": "minecraft:match_tool",
+ "predicate": {
+ "enchantments": [
+ {
+ "enchantment": "global_loot_test:smelt",
+ "levels": {
+ "min": 1
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated_test/resources/data/global_loot_test/loot_modifiers/wheat_harvest.json b/src/generated_test/resources/data/global_loot_test/loot_modifiers/wheat_harvest.json
new file mode 100644
index 0000000000..e2cdba2d4d
--- /dev/null
+++ b/src/generated_test/resources/data/global_loot_test/loot_modifiers/wheat_harvest.json
@@ -0,0 +1,20 @@
+{
+ "type": "global_loot_test:wheat_harvest",
+ "conditions": [
+ {
+ "condition": "minecraft:match_tool",
+ "predicate": {
+ "items": [
+ "minecraft:shears"
+ ]
+ }
+ },
+ {
+ "block": "minecraft:wheat",
+ "condition": "minecraft:block_state_property"
+ }
+ ],
+ "numSeeds": 3,
+ "replacement": "minecraft:wheat",
+ "seedItem": "minecraft:wheat_seeds"
+}
\ No newline at end of file
diff --git a/src/generated_test/resources/pack.mcmeta b/src/generated_test/resources/pack.mcmeta
new file mode 100644
index 0000000000..ca02aa7f6f
--- /dev/null
+++ b/src/generated_test/resources/pack.mcmeta
@@ -0,0 +1,8 @@
+{
+ "pack": {
+ "description": {
+ "text": "Forge tests resource pack"
+ },
+ "pack_format": 18
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java
index f6592705fa..e8ea1ce802 100644
--- a/src/main/java/net/minecraftforge/common/ForgeHooks.java
+++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java
@@ -22,9 +22,15 @@ import java.util.stream.Stream;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
+import com.mojang.datafixers.util.Pair;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.DataResult;
+import com.mojang.serialization.Decoder;
import com.mojang.serialization.Dynamic;
+import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.Lifecycle;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.SharedSuggestionProvider;
@@ -76,6 +82,8 @@ import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.WorldData;
+import net.minecraft.world.level.storage.loot.LootContext;
+import net.minecraft.world.level.storage.loot.LootPool;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.entity.item.ItemEntity;
@@ -121,7 +129,6 @@ import net.minecraftforge.event.RegisterStructureConversionsEvent;
import net.minecraftforge.event.VanillaGameEvent;
import net.minecraftforge.event.entity.EntityAttributeCreationEvent;
import net.minecraftforge.event.entity.EntityAttributeModificationEvent;
-import net.minecraftforge.event.entity.EntityEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent;
import net.minecraftforge.event.entity.living.EnderManAngerEvent;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
@@ -139,10 +146,8 @@ import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.living.LivingKnockBackEvent;
import net.minecraftforge.event.entity.living.LivingMakeBrainEvent;
-import net.minecraftforge.event.entity.living.LivingSwapItemsEvent;
import net.minecraftforge.event.entity.living.LivingUseTotemEvent;
import net.minecraftforge.event.entity.living.LootingLevelEvent;
-import net.minecraftforge.event.entity.living.ShieldBlockEvent;
import net.minecraftforge.event.entity.player.AnvilRepairEvent;
import net.minecraftforge.event.entity.player.AttackEntityEvent;
import net.minecraftforge.event.entity.player.CriticalHitEvent;
@@ -188,6 +193,8 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+/** FOR INTERNAL USE ONLY, DO NOT CALL DIRECTLY */
+@ApiStatus.Internal
public class ForgeHooks {
private static final Logger LOGGER = LogManager.getLogger();
@SuppressWarnings("unused")
@@ -648,14 +655,6 @@ public class ForgeHooks {
return evt.isCanceled() ? evt.getCancellationResult() : null;
}
- /**
- * @deprecated Use {@link #onLeftClickBlock(Player, BlockPos, Direction, ServerboundPlayerActionPacket.Action)} instead
- */
- @Deprecated(since = "1.20.1", forRemoval = true)
- public static PlayerInteractEvent.LeftClickBlock onLeftClickBlock(Player player, BlockPos pos, Direction face) {
- return onLeftClickBlock(player, pos, face, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK);
- }
-
public static PlayerInteractEvent.LeftClickBlock onLeftClickBlock(Player player, BlockPos pos, Direction face, ServerboundPlayerActionPacket.Action action) {
PlayerInteractEvent.LeftClickBlock evt = new PlayerInteractEvent.LeftClickBlock(player, pos, face, PlayerInteractEvent.LeftClickBlock.Action.convert(action));
MinecraftForge.EVENT_BUS.post(evt);
@@ -693,85 +692,23 @@ public class ForgeHooks {
return evt.getNewGameMode();
}
- /* TODO: GLM
- private static final ThreadLocal> lootContext = new ThreadLocal<>();
- private static LootTableContext getLootTableContext() {
- LootTableContext ctx = lootContext.get().peek();
+ public static Codec> createLootTablePoolCodec(Codec vanilla) {
+ var list = vanilla.listOf();
+ Decoder> decoder = new Decoder<>() {
+ @Override
+ public DataResult, T>> decode(DynamicOps ops, T input) {
+ return list.decode(ops, input).map(p -> {
+ var decoded = p.getFirst();
+ for (int x = 0; x < decoded.size(); x++)
+ decoded.get(x);
- if (ctx == null)
- throw new JsonParseException("Invalid call stack, could not grab json context!"); // Should I throw this? Do we care about custom deserializers outside the manager?
-
- return ctx;
- }
-
- public static TriFunction> getLootTableDeserializer(Gson gson, String directory) {
- return (location, data, resourceManager) -> {
- try {
- Resource resource = resourceManager.getResource(location.withPath(directory + "/" + location.getPath() + ".json")).orElse(null);
- boolean custom = resource == null || !resource.isBuiltin();
- return Optional.ofNullable(loadLootTable(gson, location, data, custom));
- } catch (Exception exception) {
- LOGGER.error("Couldn't parse element {}:{}", directory, location, exception);
- return Optional.empty();
+ return p;
+ });
}
};
+ return Codec.of(list, decoder);
}
- public static LootTable loadLootTable(Gson gson, ResourceLocation name, JsonElement data, boolean custom) {
- Deque que = lootContext.get();
- if (que == null) {
- que = Queues.newArrayDeque();
- lootContext.set(que);
- }
-
- LootTable ret;
- try {
- que.push(new LootTableContext(name, custom));
- ret = gson.fromJson(data, LootTable.class);
- ret.setLootTableId(name);
- } catch (JsonParseException e) {
- throw e;
- } finally {
- que.pop();
- }
-
- if (!custom)
- ret = ForgeEventFactory.loadLootTable(name, ret);
-
- if (ret != null)
- ret.freeze();
-
- return ret;
- }
-
- private static class LootTableContext {
- public final ResourceLocation name;
- public final boolean vanilla;
- public final boolean custom;
- public int poolCount = 0;
-
- private LootTableContext(ResourceLocation name, boolean custom) {
- this.name = name;
- this.custom = custom;
- this.vanilla = "minecraft".equals(this.name.getNamespace());
- }
- }
-
- public static String readPoolName(JsonObject json) {
- LootTableContext ctx = getLootTableContext();
-
- if (json.has("name"))
- return GsonHelper.getAsString(json, "name");
-
- if (ctx.custom)
- return "custom#" + json.hashCode(); //We don't care about custom ones modders shouldn't be editing them!
-
- ctx.poolCount++;
-
- return ctx.poolCount == 1 ? "main" : "pool" + (ctx.poolCount - 1);
- }
- */
-
/**
* Returns a vanilla fluid type for the given fluid.
*
@@ -953,7 +890,6 @@ public class ForgeHooks {
FurnaceBlockEntity.getFuel().entrySet().forEach(e -> VANILLA_BURNS.put(ForgeRegistries.ITEMS.getDelegateOrThrow(e.getKey()), e.getValue()));
}
- // TODO: GLM
/**
* Handles the modification of loot table drops via the registered Global Loot Modifiers,
* so that custom effects can be processed.
@@ -967,16 +903,13 @@ public class ForgeHooks {
*
* @apiNote The given context will be modified by this method to also store the ID of the
* loot table being queried.
- * /
+ */
public static ObjectArrayList modifyLoot(ResourceLocation lootTableId, ObjectArrayList generatedLoot, LootContext context) {
context.setQueriedLootTableId(lootTableId); // In case the ID was set via copy constructor, this will be ignored: intended
- LootModifierManager man = ForgeInternalHandler.getLootModifierManager();
- for (IGlobalLootModifier mod : man.getAllLootMods()) {
+ for (var mod : ForgeInternalHandler.getLootModifierManager().getAllLootMods())
generatedLoot = mod.apply(generatedLoot, context);
- }
return generatedLoot;
}
- */
public static List getModPacks() {
List modpacks = ResourcePackLoader.getPackNames();
@@ -992,13 +925,11 @@ public class ForgeHooks {
}
private static final Map, AttributeSupplier> FORGE_ATTRIBUTES = new HashMap<>();
- /** FOR INTERNAL USE ONLY, DO NOT CALL DIRECTLY */
@Deprecated
public static Map, AttributeSupplier> getAttributesView() {
return Collections.unmodifiableMap(FORGE_ATTRIBUTES);
}
- /** FOR INTERNAL USE ONLY, DO NOT CALL DIRECTLY */
@Deprecated
public static void modifyAttributes() {
ModLoader.get().postEvent(new EntityAttributeCreationEvent(FORGE_ATTRIBUTES));
@@ -1013,22 +944,6 @@ public class ForgeHooks {
});
}
- public static void onEntityEnterSection(Entity entity, long packedOldPos, long packedNewPos) {
- MinecraftForge.EVENT_BUS.post(new EntityEvent.EnteringSection(entity, packedOldPos, packedNewPos));
- }
-
- public static ShieldBlockEvent onShieldBlock(LivingEntity blocker, DamageSource source, float blocked) {
- ShieldBlockEvent e = new ShieldBlockEvent(blocker, source, blocked);
- MinecraftForge.EVENT_BUS.post(e);
- return e;
- }
-
- public static LivingSwapItemsEvent.Hands onLivingSwapHandItems(LivingEntity livingEntity) {
- LivingSwapItemsEvent.Hands event = new LivingSwapItemsEvent.Hands(livingEntity);
- MinecraftForge.EVENT_BUS.post(event);
- return event;
- }
-
public static void writeAdditionalLevelSaveData(WorldData worldData, CompoundTag levelTag) {
CompoundTag fmlData = new CompoundTag();
ListTag modList = new ListTag();
diff --git a/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java b/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java
index ad0e5b5fa5..718fab7011 100644
--- a/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java
+++ b/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java
@@ -12,6 +12,7 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.server.TickTask;
import net.minecraft.server.level.ServerLevel;
+import net.minecraftforge.common.loot.LootModifierManager;
import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.event.AddReloadListenerEvent;
import net.minecraftforge.event.RegisterCommandsEvent;
@@ -101,7 +102,6 @@ public class ForgeInternalHandler {
ConfigCommand.register(event.getDispatcher());
}
- /*
private static LootModifierManager INSTANCE;
@SubscribeEvent
@@ -111,11 +111,10 @@ public class ForgeInternalHandler {
}
static LootModifierManager getLootModifierManager() {
- if(INSTANCE == null)
+ if (INSTANCE == null)
throw new IllegalStateException("Can not retrieve LootModifierManager until resources have loaded once.");
return INSTANCE;
}
- */
@SubscribeEvent
public void resourceReloadListeners(AddReloadListenerEvent event) {
diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java
index b14373f339..7071f1df09 100644
--- a/src/main/java/net/minecraftforge/common/ForgeMod.java
+++ b/src/main/java/net/minecraftforge/common/ForgeMod.java
@@ -41,6 +41,7 @@ import net.minecraft.util.ExtraCodecs;
import net.minecraft.core.RegistryCodecs;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.pathfinder.BlockPathTypes;
+import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
import net.minecraftforge.common.data.ExistingFileHelper;
@@ -50,6 +51,8 @@ import net.minecraftforge.common.data.ForgeSpriteSourceProvider;
import net.minecraftforge.common.data.VanillaSoundDefinitionsProvider;
import net.minecraftforge.common.extensions.IForgeEntity;
import net.minecraftforge.common.extensions.IForgePlayer;
+import net.minecraftforge.common.loot.CanToolPerformAction;
+import net.minecraftforge.common.loot.LootTableIdCondition;
import net.minecraftforge.common.world.BiomeModifier;
import net.minecraftforge.common.world.ForgeBiomeModifiers.AddFeaturesBiomeModifier;
import net.minecraftforge.common.world.ForgeBiomeModifiers.AddSpawnsBiomeModifier;
@@ -89,9 +92,9 @@ import org.apache.logging.log4j.Logger;
import net.minecraft.data.DataGenerator;
import net.minecraft.resources.ResourceLocation;
-import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.common.crafting.conditions.AndCondition;
import net.minecraftforge.common.crafting.conditions.FalseCondition;
+import net.minecraftforge.common.crafting.conditions.ICondition;
import net.minecraftforge.common.crafting.conditions.ItemExistsCondition;
import net.minecraftforge.common.crafting.conditions.ModLoadedCondition;
import net.minecraftforge.common.crafting.conditions.NotCondition;
@@ -129,9 +132,10 @@ public class ForgeMod {
private static final DeferredRegister> STRUCTURE_MODIFIER_SERIALIZERS = DeferredRegister.create(ForgeRegistries.Keys.STRUCTURE_MODIFIER_SERIALIZERS, "forge");
private static final DeferredRegister HOLDER_SET_TYPES = DeferredRegister.create(ForgeRegistries.Keys.HOLDER_SET_TYPES, "forge");
- @SuppressWarnings({ "unchecked", "rawtypes" })
+ @SuppressWarnings({ "unchecked", "rawtypes", "unused" })
private static final RegistryObject ENUM_COMMAND_ARGUMENT_TYPE = COMMAND_ARGUMENT_TYPES.register("enum", () ->
ArgumentTypeInfos.registerByClass(EnumArgument.class, new EnumArgument.Info()));
+ @SuppressWarnings("unused")
private static final RegistryObject> MODID_COMMAND_ARGUMENT_TYPE = COMMAND_ARGUMENT_TYPES.register("modid", () ->
ArgumentTypeInfos.registerByClass(ModIdArgument.class,
SingletonArgumentInfo.contextFree(ModIdArgument::modIdArgument)));
@@ -367,6 +371,25 @@ public class ForgeMod {
}
});
+ private static final DeferredRegister LOOT_CONDITION_TYPES = DeferredRegister.create(Registries.LOOT_CONDITION_TYPE, "forge");
+ static {
+ LOOT_CONDITION_TYPES.register("loot_table_id", () -> LootTableIdCondition.TYPE);
+ LOOT_CONDITION_TYPES.register("can_tool_perform_action", () -> CanToolPerformAction.TYPE);
+ }
+
+ private static final DeferredRegister> CONDITION_SERIALIZERS = DeferredRegister.create(ForgeRegistries.Keys.CONDITION_SERIALIZERS, "forge");
+ static {
+ CONDITION_SERIALIZERS.register("and", () -> AndCondition.CODEC);
+ CONDITION_SERIALIZERS.register("false", () -> FalseCondition.CODEC);
+ CONDITION_SERIALIZERS.register("item_exists", () -> ItemExistsCondition.CODEC);
+ CONDITION_SERIALIZERS.register("mod_loaded", () -> ModLoadedCondition.CODEC);
+ CONDITION_SERIALIZERS.register("not", () -> NotCondition.CODEC);
+ CONDITION_SERIALIZERS.register("or", () -> OrCondition.CODEC);
+ CONDITION_SERIALIZERS.register("true", () -> TrueCondition.CODEC);
+ CONDITION_SERIALIZERS.register("tag_empty", () -> TagEmptyCondition.CODEC);
+ }
+
+
private static boolean enableMilkFluid = false;
public static final RegistryObject BUCKET_EMPTY_MILK = RegistryObject.create(new ResourceLocation("item.bucket.empty_milk"), ForgeRegistries.SOUND_EVENTS);
public static final RegistryObject BUCKET_FILL_MILK = RegistryObject.create(new ResourceLocation("item.bucket.fill_milk"), ForgeRegistries.SOUND_EVENTS);
@@ -414,7 +437,6 @@ public class ForgeMod {
modEventBus.addListener(this::registerFluids);
modEventBus.addListener(this::registerVanillaDisplayContexts);
modEventBus.addListener(this::registerRecipeSerializers);
- modEventBus.addListener(this::registerLootData);
modEventBus.register(this);
ATTRIBUTES.register(modEventBus);
COMMAND_ARGUMENT_TYPES.register(modEventBus);
@@ -422,6 +444,8 @@ public class ForgeMod {
STRUCTURE_MODIFIER_SERIALIZERS.register(modEventBus);
HOLDER_SET_TYPES.register(modEventBus);
VANILLA_FLUID_TYPES.register(modEventBus);
+ LOOT_CONDITION_TYPES.register(modEventBus);
+ CONDITION_SERIALIZERS.register(modEventBus);
MinecraftForge.EVENT_BUS.addListener(this::serverStopping);
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ForgeConfig.clientSpec);
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, ForgeConfig.serverSpec);
@@ -546,14 +570,6 @@ public class ForgeMod {
public void registerRecipeSerializers(RegisterEvent event) {
if (event.getRegistryKey().equals(ForgeRegistries.Keys.RECIPE_SERIALIZERS)) {
- CraftingHelper.register(AndCondition.Serializer.INSTANCE);
- CraftingHelper.register(FalseCondition.Serializer.INSTANCE);
- CraftingHelper.register(ItemExistsCondition.Serializer.INSTANCE);
- CraftingHelper.register(ModLoadedCondition.Serializer.INSTANCE);
- CraftingHelper.register(NotCondition.Serializer.INSTANCE);
- CraftingHelper.register(OrCondition.Serializer.INSTANCE);
- CraftingHelper.register(TrueCondition.Serializer.INSTANCE);
- CraftingHelper.register(TagEmptyCondition.Serializer.INSTANCE);
/*
CraftingHelper.register(new ResourceLocation("forge", "compound"), CompoundIngredient.Serializer.INSTANCE);
@@ -568,14 +584,6 @@ public class ForgeMod {
}
}
- public void registerLootData(RegisterEvent event) {
- if (!event.getRegistryKey().equals(Registries.LOOT_CONDITION_TYPE))
- return;
-
- //event.register(Registries.LOOT_CONDITION_TYPE, new ResourceLocation("forge:loot_table_id"), () -> LootTableIdCondition.LOOT_TABLE_ID);
- //event.register(Registries.LOOT_CONDITION_TYPE, new ResourceLocation("forge:can_tool_perform_action"), () -> CanToolPerformAction.LOOT_CONDITION_TYPE);
- }
-
public static final PermissionNode USE_SELECTORS_PERMISSION = new PermissionNode<>("forge", "use_entity_selectors",
PermissionTypes.BOOLEAN, (player, uuid, contexts) -> player != null && player.hasPermissions(Commands.LEVEL_GAMEMASTERS));
diff --git a/src/main/java/net/minecraftforge/common/ToolAction.java b/src/main/java/net/minecraftforge/common/ToolAction.java
index 030f3b00ae..96cca64475 100644
--- a/src/main/java/net/minecraftforge/common/ToolAction.java
+++ b/src/main/java/net/minecraftforge/common/ToolAction.java
@@ -10,9 +10,10 @@ import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-@SuppressWarnings("ClassCanBeRecord")
-public final class ToolAction
-{
+import com.mojang.serialization.Codec;
+
+public final class ToolAction {
+ public static final Codec CODEC = Codec.STRING.xmap(ToolAction::get, ToolAction::name).stable();
private static final Map actions = new ConcurrentHashMap<>();
/**
@@ -20,30 +21,26 @@ public final class ToolAction
* This collection can be kept around, and will update itself in response to changes to the map.
* See {@link ConcurrentHashMap#values()} for details.
*/
- public static Collection getActions()
- {
+ public static Collection getActions() {
return Collections.unmodifiableCollection(actions.values());
}
/**
* Gets or creates a new ToolAction for the given name.
*/
- public static ToolAction get(String name)
- {
+ public static ToolAction get(String name) {
return actions.computeIfAbsent(name, ToolAction::new);
}
/**
* Returns the name of this tool action
*/
- public String name()
- {
+ public String name() {
return name;
}
@Override
- public String toString()
- {
+ public String toString() {
return "ToolAction[" + name + "]";
}
@@ -52,8 +49,7 @@ public final class ToolAction
/**
* Use {@link #get(String)} to get or create a ToolAction
*/
- private ToolAction(String name)
- {
+ private ToolAction(String name) {
this.name = name;
}
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/AbstractIngredient.java b/src/main/java/net/minecraftforge/common/crafting/AbstractIngredient.java
deleted file mode 100644
index 865713fa47..0000000000
--- a/src/main/java/net/minecraftforge/common/crafting/AbstractIngredient.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) Forge Development LLC and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-package net.minecraftforge.common.crafting;
-/*
-import com.google.gson.JsonElement;
-import net.minecraft.network.FriendlyByteBuf;
-import net.minecraft.tags.TagKey;
-import net.minecraft.world.item.Item;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.Ingredient;
-import net.minecraft.world.level.ItemLike;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.stream.Stream;
-
-/**
- * Extension of {@link Ingredient} which makes most methods custom ingredients need to implement abstract, and removes the static constructors
- * Mods are encouraged to extend this class for their custom ingredients
- * /
-public abstract class AbstractIngredient extends Ingredient {
- /** Empty constructor, for the sake of dynamic ingredients * /
- protected AbstractIngredient() {
- super(Stream.of());
- }
-
- /** Value constructor, for ingredients that have some vanilla representation * /
- protected AbstractIngredient(Stream extends Value> values) {
- super(values);
- }
-
- @Override
- public abstract boolean isSimple();
-
- @Override
- public abstract IIngredientSerializer extends Ingredient> getSerializer();
-
- @Override
- public abstract JsonElement toJson(boolean allowEmpty);
-
-
- /* Hide vanilla ingredient static constructors to reduce errors with constructing custom ingredients * /
-
- /** @deprecated use {@link Ingredient#fromValues(Stream)} * /
- @Deprecated
- public static Ingredient fromValues(Stream extends Ingredient.Value> values) {
- throw new UnsupportedOperationException("Use Ingredient.fromValues()");
- }
-
- /** @deprecated use {@link Ingredient#of()} * /
- @Deprecated
- public static Ingredient of() {
- throw new UnsupportedOperationException("Use Ingredient.of()");
- }
-
- /** @deprecated use {@link Ingredient#of(ItemLike...)} (Stream)} * /
- @Deprecated
- public static Ingredient of(ItemLike... items) {
- throw new UnsupportedOperationException("Use Ingredient.of()");
- }
-
- /** @deprecated use {@link Ingredient#of(ItemStack...)} (Stream)} * /
- @Deprecated
- public static Ingredient of(ItemStack... stacks) {
- throw new UnsupportedOperationException("Use Ingredient.of()");
- }
-
- /** @deprecated use {@link Ingredient#of(Stream)} (Stream)} * /
- @Deprecated
- public static Ingredient of(Stream stacks) {
- throw new UnsupportedOperationException("Use Ingredient.of()");
- }
-
- /** @deprecated use {@link Ingredient#of(TagKey)} (Stream)} * /
- @Deprecated
- public static Ingredient of(TagKey- tag) {
- throw new UnsupportedOperationException("Use Ingredient.of()");
- }
-
- /** @deprecated use {@link Ingredient#fromNetwork(FriendlyByteBuf)} * /
- @Deprecated
- public static Ingredient fromNetwork(FriendlyByteBuf buffer) {
- throw new UnsupportedOperationException("Use Ingredient.fromNetwork()");
- }
-
- /** @deprecated use {@link Ingredient#fromJson(JsonElement)} (Stream)} * /
- @Deprecated
- public static Ingredient fromJson(@Nullable JsonElement json) {
- throw new UnsupportedOperationException("Use Ingredient.fromJson()");
- }
-}
-*/
diff --git a/src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java b/src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java
index edff16b5bd..10aa0273f8 100644
--- a/src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java
+++ b/src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java
@@ -27,9 +27,9 @@ import net.minecraft.network.FriendlyByteBuf;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-/** Ingredient that matches if any of the child ingredients match * /
-public class CompoundIngredient extends AbstractIngredient
-{
+/** Ingredient that matches if any of the child ingredients match */
+/*
+public class CompoundIngredient extends Ingredient {
private List children;
private ItemStack[] stacks;
private IntList itemIds;
@@ -41,7 +41,8 @@ public class CompoundIngredient extends AbstractIngredient
this.isSimple = children.stream().allMatch(Ingredient::isSimple);
}
- /** Creates a compound ingredient from the given list of ingredients * /
+ /** Creates a compound ingredient from the given list of ingredients */
+/*
public static Ingredient of(Ingredient... children)
{
// if 0 or 1 ingredient, can save effort
@@ -68,10 +69,8 @@ public class CompoundIngredient extends AbstractIngredient
@Override
@NotNull
- public ItemStack[] getItems()
- {
- if (stacks == null)
- {
+ public ItemStack[] getItems() {
+ if (stacks == null) {
List tmp = Lists.newArrayList();
for (Ingredient child : children)
Collections.addAll(tmp, child.getItems());
@@ -83,15 +82,11 @@ public class CompoundIngredient extends AbstractIngredient
@Override
@NotNull
- public IntList getStackingIds()
- {
+ public IntList getStackingIds() {
boolean childrenNeedInvalidation = false;
for (Ingredient child : children)
- {
childrenNeedInvalidation |= child.checkInvalidation();
- }
- if (childrenNeedInvalidation || this.itemIds == null || checkInvalidation())
- {
+ if (childrenNeedInvalidation || this.itemIds == null || checkInvalidation()) {
this.markValid();
this.itemIds = new IntArrayList();
for (Ingredient child : children)
@@ -103,8 +98,7 @@ public class CompoundIngredient extends AbstractIngredient
}
@Override
- public boolean test(@Nullable ItemStack target)
- {
+ public boolean test(@Nullable ItemStack target) {
if (target == null)
return false;
@@ -112,74 +106,18 @@ public class CompoundIngredient extends AbstractIngredient
}
@Override
- protected void invalidate()
- {
- this.itemIds = null;
- this.stacks = null;
- }
-
- @Override
- public boolean isSimple()
- {
+ public boolean isSimple() {
return isSimple;
}
- @Override
- public IIngredientSerializer extends Ingredient> getSerializer()
- {
- return Serializer.INSTANCE;
- }
-
@NotNull
- public Collection getChildren()
- {
+ public Collection getChildren() {
return this.children;
}
@Override
- public JsonElement toJson()
- {
- if (this.children.size() == 1)
- {
- return this.children.get(0).toJson();
- }
- else
- {
- JsonArray json = new JsonArray();
- this.children.stream().forEach(e -> json.add(e.toJson()));
- return json;
- }
- }
-
- @Override
- public boolean isEmpty()
- {
+ public boolean isEmpty() {
return children.stream().allMatch(Ingredient::isEmpty);
}
-
- public static class Serializer implements IIngredientSerializer
- {
- public static final Serializer INSTANCE = new Serializer();
-
- @Override
- public CompoundIngredient parse(FriendlyByteBuf buffer)
- {
- return new CompoundIngredient(Stream.generate(() -> Ingredient.fromNetwork(buffer)).limit(buffer.readVarInt()).collect(Collectors.toList()));
- }
-
- @Override
- public CompoundIngredient parse(JsonObject json)
- {
- throw new JsonSyntaxException("CompoundIngredient should not be directly referenced in json, just use an array of ingredients.");
- }
-
- @Override
- public void write(FriendlyByteBuf buffer, CompoundIngredient ingredient)
- {
- buffer.writeVarInt(ingredient.children.size());
- ingredient.children.forEach(c -> c.toNetwork(buffer));
- }
-
- }
}
*/
diff --git a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java
index 63a88b2976..f2db032539 100644
--- a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java
+++ b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java
@@ -16,12 +16,12 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import com.mojang.serialization.Codec;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraftforge.common.crafting.conditions.ICondition;
-import net.minecraftforge.common.crafting.conditions.IConditionSerializer;
import net.minecraft.nbt.TagParser;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.GsonHelper;
@@ -173,13 +173,11 @@ public class CraftingHelper {
}
// CONDITIONS
- private static final Map> conditions = new HashMap<>();
- public static IConditionSerializer> register(IConditionSerializer> serializer) {
- ResourceLocation key = serializer.getID();
+ private static final Map> conditions = new HashMap<>();
+ public static void register(ResourceLocation key, Codec extends ICondition> codec) {
if (conditions.containsKey(key))
throw new IllegalStateException("Duplicate recipe condition serializer: " + key);
- conditions.put(key, serializer);
- return serializer;
+ conditions.put(key, codec);
}
public static boolean processConditions(JsonObject json, String memberName, ICondition.IContext context) {
@@ -187,38 +185,16 @@ public class CraftingHelper {
}
public static boolean processConditions(JsonArray conditions, ICondition.IContext context) {
- for (int x = 0; x < conditions.size(); x++)
- {
+ for (int x = 0; x < conditions.size(); x++) {
if (!conditions.get(x).isJsonObject())
throw new JsonSyntaxException("Conditions must be an array of JsonObjects");
JsonObject json = conditions.get(x).getAsJsonObject();
+ /*
if (!CraftingHelper.getCondition(json).test(context))
return false;
+ */
}
return true;
}
-
- public static ICondition getCondition(JsonObject json) {
- ResourceLocation type = new ResourceLocation(GsonHelper.getAsString(json, "type"));
- IConditionSerializer> serializer = conditions.get(type);
- if (serializer == null)
- throw new JsonSyntaxException("Unknown condition type: " + type.toString());
- return serializer.read(json);
- }
-
- public static JsonObject serialize(T condition) {
- @SuppressWarnings("unchecked")
- IConditionSerializer serializer = (IConditionSerializer)conditions.get(condition.getID());
- if (serializer == null)
- throw new JsonSyntaxException("Unknown condition type: " + condition.getID().toString());
- return serializer.getJson(condition);
- }
-
- public static JsonArray serialize(ICondition... conditions) {
- JsonArray arr = new JsonArray();
- for(ICondition iCond : conditions)
- arr.add(serialize(iCond));
- return arr;
- }
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/IIngredientSerializer.java b/src/main/java/net/minecraftforge/common/crafting/IIngredientSerializer.java
deleted file mode 100644
index 5bc1dd5d46..0000000000
--- a/src/main/java/net/minecraftforge/common/crafting/IIngredientSerializer.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) Forge Development LLC and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-package net.minecraftforge.common.crafting;
-
-// TODO: Ingredient Serializers
-/*
-import com.google.gson.JsonObject;
-
-import net.minecraft.world.item.crafting.Ingredient;
-import net.minecraft.network.FriendlyByteBuf;
-
-public interface IIngredientSerializer {
- T parse(FriendlyByteBuf buffer);
-
- T parse(JsonObject json);
-
- void write(FriendlyByteBuf buffer, T ingredient);
-}
-*/
\ No newline at end of file
diff --git a/src/main/java/net/minecraftforge/common/crafting/MultiItemValue.java b/src/main/java/net/minecraftforge/common/crafting/MultiItemValue.java
deleted file mode 100644
index db242478e4..0000000000
--- a/src/main/java/net/minecraftforge/common/crafting/MultiItemValue.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) Forge Development LLC and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-package net.minecraftforge.common.crafting;
-/*
-import java.util.Collection;
-import java.util.Collections;
-
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
-
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.Ingredient.Value;
-import net.minecraftforge.registries.ForgeRegistries;
-
-public class MultiItemValue implements Value
-{
- private Collection items;
- public MultiItemValue(Collection items)
- {
- this.items = Collections.unmodifiableCollection(items);
- }
-
- @Override
- public Collection getItems()
- {
- return items;
- }
-
- @Override
- public JsonObject serialize()
- {
- if (items.size() == 1)
- return toJson(items.iterator().next());
-
- JsonObject ret = new JsonObject();
- JsonArray array = new JsonArray();
- items.forEach(stack -> array.add(toJson(stack)));
- ret.add("items", array);
- return ret;
- }
-
- private JsonObject toJson(ItemStack stack)
- {
- JsonObject ret = new JsonObject();
- ret.addProperty("item", ForgeRegistries.ITEMS.getKey(stack.getItem()).toString());
- if (stack.getCount() != 1)
- ret.addProperty("count", stack.getCount());
- if (stack.getTag() != null)
- ret.addProperty("nbt", stack.getTag().toString()); //TODO: Better serialization?
- return ret;
- }
-
-}
-*/
diff --git a/src/main/java/net/minecraftforge/common/crafting/StrictNBTIngredient.java b/src/main/java/net/minecraftforge/common/crafting/StrictNBTIngredient.java
index f9d836ff4d..7cf7705503 100644
--- a/src/main/java/net/minecraftforge/common/crafting/StrictNBTIngredient.java
+++ b/src/main/java/net/minecraftforge/common/crafting/StrictNBTIngredient.java
@@ -4,37 +4,35 @@
*/
package net.minecraftforge.common.crafting;
-/*
-import java.util.stream.Stream;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
+import java.util.stream.Stream;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
-import net.minecraft.network.FriendlyByteBuf;
-import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.Nullable;
-/** Ingredient that matches the given stack, performing an exact NBT match. Use {@link PartialNBTIngredient} if you need partial match. * /
-public class StrictNBTIngredient extends AbstractIngredient
-{
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
+
+/** Ingredient that matches the given stack, performing an exact NBT match. Use {@link PartialNBTIngredient} if you need partial match. */
+public class StrictNBTIngredient extends Ingredient {
+ public static final Codec CODEC = RecordCodecBuilder.create(b -> b.group(
+ ItemStack.CODEC.fieldOf("stack").forGetter(i -> i.stack)
+ ).apply(b, StrictNBTIngredient::new));
+
private final ItemStack stack;
- protected StrictNBTIngredient(ItemStack stack)
- {
+ protected StrictNBTIngredient(ItemStack stack) {
super(Stream.of(new Ingredient.ItemValue(stack)));
this.stack = stack;
}
- /** Creates a new ingredient matching the given stack and tag * /
- public static StrictNBTIngredient of(ItemStack stack)
- {
+ /** Creates a new ingredient matching the given stack and tag */
+ public static StrictNBTIngredient of(ItemStack stack) {
return new StrictNBTIngredient(stack);
}
@Override
- public boolean test(@Nullable ItemStack input)
- {
+ public boolean test(@Nullable ItemStack input) {
if (input == null)
return false;
//Can't use areItemStacksEqualUsingNBTShareTag because it compares stack size as well
@@ -42,47 +40,7 @@ public class StrictNBTIngredient extends AbstractIngredient
}
@Override
- public boolean isSimple()
- {
+ public boolean isSimple() {
return false;
}
-
- @Override
- public IIngredientSerializer extends Ingredient> getSerializer()
- {
- return Serializer.INSTANCE;
- }
-
- @Override
- public JsonElement toJson()
- {
- JsonObject json = new JsonObject();
- json.addProperty("type", CraftingHelper.getID(Serializer.INSTANCE).toString());
- json.addProperty("item", ForgeRegistries.ITEMS.getKey(stack.getItem()).toString());
- json.addProperty("count", stack.getCount());
- if (stack.hasTag())
- json.addProperty("nbt", stack.getTag().toString());
- return json;
- }
-
- public static class Serializer implements IIngredientSerializer
- {
- public static final Serializer INSTANCE = new Serializer();
-
- @Override
- public StrictNBTIngredient parse(FriendlyByteBuf buffer) {
- return new StrictNBTIngredient(buffer.readItem());
- }
-
- @Override
- public StrictNBTIngredient parse(JsonObject json) {
- return new StrictNBTIngredient(CraftingHelper.getItemStack(json, true));
- }
-
- @Override
- public void write(FriendlyByteBuf buffer, StrictNBTIngredient ingredient) {
- buffer.writeItem(ingredient.stack);
- }
- }
}
-*/
diff --git a/src/main/java/net/minecraftforge/common/crafting/VanillaIngredientSerializer.java b/src/main/java/net/minecraftforge/common/crafting/VanillaIngredientSerializer.java
deleted file mode 100644
index 7fe2419111..0000000000
--- a/src/main/java/net/minecraftforge/common/crafting/VanillaIngredientSerializer.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) Forge Development LLC and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-package net.minecraftforge.common.crafting;
-/*
-import java.util.stream.Stream;
-
-import com.google.gson.JsonObject;
-
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.Ingredient;
-import net.minecraft.network.FriendlyByteBuf;
-
-public class VanillaIngredientSerializer implements IIngredientSerializer
-{
- public static final VanillaIngredientSerializer INSTANCE = new VanillaIngredientSerializer();
-
- public Ingredient parse(FriendlyByteBuf buffer)
- {
- return Ingredient.fromValues(Stream.generate(() -> new Ingredient.ItemValue(buffer.readItem())).limit(buffer.readVarInt()));
- }
-
- public Ingredient parse(JsonObject json)
- {
- return Ingredient.fromValues(Stream.of(Ingredient.valueFromJson(json)));
- }
-
- public void write(FriendlyByteBuf buffer, Ingredient ingredient)
- {
- ItemStack[] items = ingredient.getItems();
- buffer.writeVarInt(items.length);
-
- for (ItemStack stack : items)
- buffer.writeItem(stack);
- }
-}
-*/
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/AndCondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/AndCondition.java
index adf0ff9400..07fd147898 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/AndCondition.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/AndCondition.java
@@ -5,49 +5,20 @@
package net.minecraftforge.common.crafting.conditions;
-import java.util.ArrayList;
import java.util.List;
import com.google.common.base.Joiner;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonSyntaxException;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
-import net.minecraft.util.GsonHelper;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraftforge.common.crafting.CraftingHelper;
-
-public class AndCondition implements ICondition
-{
- private static final ResourceLocation NAME = new ResourceLocation("forge", "and");
- private final ICondition[] children;
-
- public AndCondition(ICondition... values)
- {
- if (values == null || values.length == 0)
- throw new IllegalArgumentException("Values must not be empty");
-
- for (ICondition child : values)
- {
- if (child == null)
- throw new IllegalArgumentException("Value must not be null");
- }
-
- this.children = values;
- }
+public record AndCondition(List children) implements ICondition {
+ public static final Codec CODEC = RecordCodecBuilder.create(b -> b.group(
+ ICondition.CODEC.listOf().fieldOf("values").forGetter(AndCondition::children)
+ ).apply(b, AndCondition::new));
@Override
- public ResourceLocation getID()
- {
- return NAME;
- }
-
- @Override
- public boolean test(IContext context)
- {
- for (ICondition child : children)
- {
+ public boolean test(IContext context) {
+ for (ICondition child : children) {
if (!child.test(context))
return false;
}
@@ -55,41 +26,12 @@ public class AndCondition implements ICondition
}
@Override
- public String toString()
- {
+ public String toString() {
return Joiner.on(" && ").join(children);
}
- public static class Serializer implements IConditionSerializer
- {
- public static final Serializer INSTANCE = new Serializer();
-
- @Override
- public void write(JsonObject json, AndCondition value)
- {
- JsonArray values = new JsonArray();
- for (ICondition child : value.children)
- values.add(CraftingHelper.serialize(child));
- json.add("values", values);
- }
-
- @Override
- public AndCondition read(JsonObject json)
- {
- List children = new ArrayList<>();
- for (JsonElement j : GsonHelper.getAsJsonArray(json, "values"))
- {
- if (!j.isJsonObject())
- throw new JsonSyntaxException("And condition values must be an array of JsonObjects");
- children.add(CraftingHelper.getCondition(j.getAsJsonObject()));
- }
- return new AndCondition(children.toArray(new ICondition[children.size()]));
- }
-
- @Override
- public ResourceLocation getID()
- {
- return AndCondition.NAME;
- }
+ @Override
+ public Codec extends ICondition> codec() {
+ return CODEC;
}
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/ConditionCodec.java b/src/main/java/net/minecraftforge/common/crafting/conditions/ConditionCodec.java
new file mode 100644
index 0000000000..51f311b46d
--- /dev/null
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/ConditionCodec.java
@@ -0,0 +1,66 @@
+package net.minecraftforge.common.crafting.conditions;
+
+import java.util.Optional;
+import java.util.function.Supplier;
+
+import com.mojang.datafixers.util.Pair;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.DataResult;
+import com.mojang.serialization.Decoder;
+import com.mojang.serialization.DynamicOps;
+import net.minecraft.resources.DelegatingOps;
+import net.minecraftforge.common.crafting.conditions.ICondition.IContext;
+
+public class ConditionCodec {
+ public static Codec checkingDecode(Codec normal, Supplier _default) {
+ return checkingDecode(normal, _default, ICondition.DEFAULT_FIELD);
+ }
+
+ public static Codec checkingDecode(Codec normal, Supplier _default, String key) {
+ return Codec.of(normal, new UnwrapDecoder<>(wrap(normal, key), _default));
+ }
+
+ public static Decoder> wrap(Decoder normal) {
+ return wrap(normal, ICondition.DEFAULT_FIELD);
+ }
+
+ public static Decoder> wrap(Decoder normal, String key) {
+ return new OptionalConditionalDecoder<>(normal, key);
+ }
+
+ public static IContext getContext(DynamicOps ops) {
+ IContext ret = null;
+ if (ops instanceof DelegatingOps> dele)
+ ret = dele.getContext(ICondition.IContext.KEY);
+ return ret == null ? IContext.EMPTY : ret;
+ }
+
+ private static record UnwrapDecoder(Decoder> normal, Supplier _default) implements Decoder {
+ @Override
+ public DataResult> decode(DynamicOps ops, T input) {
+ var ret = normal.decode(ops, input);
+ if (!ret.result().isPresent() || !ret.result().get().getFirst().isPresent())
+ return ret.map(p -> p.mapFirst(e -> _default.get()));
+ return ret.map(p -> p.mapFirst(Optional::get));
+ }
+ }
+
+ private static record OptionalConditionalDecoder(Decoder normal, String key) implements Decoder> {
+ @Override
+ public DataResult, T>> decode(DynamicOps ops, T input) {
+ var conditionRaw = ops.get(input, key);
+ if (conditionRaw.error().isPresent() || !conditionRaw.result().isPresent())
+ return normal.decode(ops, input).map(p -> p.mapFirst(Optional::of));
+
+ var conditionDecoded = ICondition.CODEC.parse(ops, conditionRaw.result().get());
+ if (conditionDecoded.error().isPresent())
+ return DataResult.error(() -> conditionDecoded.error().get().message());
+
+ var condition = conditionDecoded.result().get();
+ if (condition.test(getContext(ops)))
+ return DataResult.success(Pair.of(Optional.empty(), null));
+
+ return normal.decode(ops, input).map(p -> p.mapFirst(Optional::of));
+ }
+ }
+}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/ConditionContext.java b/src/main/java/net/minecraftforge/common/crafting/conditions/ConditionContext.java
index 7cfe212368..7a4310d75e 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/ConditionContext.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/ConditionContext.java
@@ -6,7 +6,6 @@
package net.minecraftforge.common.crafting.conditions;
import net.minecraft.core.Holder;
-import net.minecraft.core.HolderSet;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
@@ -17,32 +16,27 @@ import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Map;
-public class ConditionContext implements ICondition.IContext
-{
- private final TagManager tagManager;
- private Map, Map>>> loadedTags = null;
+public class ConditionContext implements ICondition.IContext {
+ private final TagManager tagManager;
+ private Map, Map>>> loadedTags = null;
- public ConditionContext(TagManager tagManager)
- {
- this.tagManager = tagManager;
- }
+ public ConditionContext(TagManager tagManager) {
+ this.tagManager = tagManager;
+ }
- @SuppressWarnings({ "unchecked", "rawtypes" })
+ @SuppressWarnings({ "unchecked", "rawtypes" })
@Override
- public Map>> getAllTags(ResourceKey extends Registry> registry)
- {
- if (loadedTags == null)
- {
- var tags = tagManager.getResult();
- if (tags.isEmpty()) throw new IllegalStateException("Tags have not been loaded yet.");
+ public Map>> getAllTags(ResourceKey extends Registry> registry) {
+ if (loadedTags == null) {
+ var tags = tagManager.getResult();
+ if (tags.isEmpty()) throw new IllegalStateException("Tags have not been loaded yet.");
- loadedTags = new IdentityHashMap<>();
- for (var loadResult : tags)
- {
- Map>> map = Collections.unmodifiableMap(loadResult.tags());
- loadedTags.put(loadResult.key(), (Map) map);
- }
- }
- return (Map) loadedTags.getOrDefault(registry, Collections.emptyMap());
- }
+ loadedTags = new IdentityHashMap<>();
+ for (var loadResult : tags) {
+ var map = Collections.unmodifiableMap(loadResult.tags());
+ loadedTags.put(loadResult.key(), (Map)map);
+ }
+ }
+ return (Map)loadedTags.getOrDefault(registry, Collections.emptyMap());
+ }
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/FalseCondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/FalseCondition.java
index 2277af5c27..b003d080e3 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/FalseCondition.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/FalseCondition.java
@@ -5,51 +5,26 @@
package net.minecraftforge.common.crafting.conditions;
-import com.google.gson.JsonObject;
-import net.minecraft.resources.ResourceLocation;
+import com.mojang.serialization.Codec;
-public final class FalseCondition implements ICondition
-{
+public final class FalseCondition implements ICondition {
public static final FalseCondition INSTANCE = new FalseCondition();
- private static final ResourceLocation NAME = new ResourceLocation("forge", "false");
+ public static final Codec CODEC = Codec.unit(INSTANCE).stable();
- private FalseCondition() {}
+ private FalseCondition() { }
@Override
- public ResourceLocation getID()
- {
- return NAME;
- }
-
- @Override
- public boolean test(IContext condition)
- {
+ public boolean test(IContext condition) {
return false;
}
@Override
- public String toString()
- {
+ public String toString() {
return "false";
}
- public static class Serializer implements IConditionSerializer
- {
- public static final Serializer INSTANCE = new Serializer();
-
- @Override
- public void write(JsonObject json, FalseCondition value) { }
-
- @Override
- public FalseCondition read(JsonObject json)
- {
- return FalseCondition.INSTANCE;
- }
-
- @Override
- public ResourceLocation getID()
- {
- return FalseCondition.NAME;
- }
+ @Override
+ public Codec extends ICondition> codec() {
+ return CODEC;
}
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/ICondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/ICondition.java
index 5a6f5e9946..89b8ed67bf 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/ICondition.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/ICondition.java
@@ -5,50 +5,46 @@
package net.minecraftforge.common.crafting.conditions;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
+
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
-import net.minecraftforge.common.crafting.CraftingHelper;
+import net.minecraft.util.ExtraCodecs;
+import net.minecraftforge.registries.ForgeRegistries;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
+import java.util.function.Function;
-public interface ICondition
-{
- static boolean shouldRegisterEntry(JsonElement json)
- {
- if (!(json instanceof JsonObject obj) || !obj.has("forge:conditions"))
- return true;
-
- return CraftingHelper.processConditions(obj, "forge:conditions", IContext.TAGS_INVALID);
- }
-
- ResourceLocation getID();
+public interface ICondition {
+ Codec CODEC = ExtraCodecs.lazyInitializedCodec(() -> ForgeRegistries.CONDITION_SERIALIZERS.get().getCodec().dispatch(ICondition::codec, Function.identity()));
+ String DEFAULT_FIELD = "forge:condition";
+ MapCodec> OPTIONAL_FEILD_CODEC = CODEC.optionalFieldOf(DEFAULT_FIELD);
boolean test(IContext context);
- interface IContext
- {
- IContext EMPTY = new IContext()
- {
+ Codec extends ICondition> codec();
+
+ interface IContext {
+ public static ResourceLocation KEY = new ResourceLocation("forge", "condition_context");
+
+ IContext EMPTY = new IContext() {
@Override
- public Map>> getAllTags(ResourceKey extends Registry> registry)
- {
+ public Map>> getAllTags(ResourceKey extends Registry> registry) {
return Collections.emptyMap();
}
};
- IContext TAGS_INVALID = new IContext()
- {
+ IContext TAGS_INVALID = new IContext() {
@Override
- public Map>> getAllTags(ResourceKey extends Registry> registry)
- {
+ public Map>> getAllTags(ResourceKey extends Registry> registry) {
throw new UnsupportedOperationException("Usage of tag-based conditions is not permitted in this context!");
}
};
@@ -56,8 +52,7 @@ public interface ICondition
/**
* Return the requested tag if available, or an empty tag otherwise.
*/
- default Collection> getTag(TagKey key)
- {
+ default Collection> getTag(TagKey key) {
return getAllTags(key.registry()).getOrDefault(key.location(), Set.of());
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/IConditionBuilder.java b/src/main/java/net/minecraftforge/common/crafting/conditions/IConditionBuilder.java
index 18391e8d5a..5080c8a25c 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/IConditionBuilder.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/IConditionBuilder.java
@@ -5,48 +5,42 @@
package net.minecraftforge.common.crafting.conditions;
+import java.util.List;
+
+import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
-public interface IConditionBuilder
-{
- default ICondition and(ICondition... values)
- {
- return new AndCondition(values);
+public interface IConditionBuilder {
+ default ICondition and(ICondition... values) {
+ return new AndCondition(List.of(values));
}
- default ICondition FALSE()
- {
+ default ICondition FALSE() {
return FalseCondition.INSTANCE;
}
- default ICondition TRUE()
- {
+ default ICondition TRUE() {
return TrueCondition.INSTANCE;
}
- default ICondition not(ICondition value)
- {
+ default ICondition not(ICondition value) {
return new NotCondition(value);
}
- default ICondition or(ICondition... values)
- {
- return new OrCondition(values);
+ default ICondition or(ICondition... values) {
+ return new OrCondition(List.of(values));
}
- default ICondition itemExists(String namespace, String path)
- {
- return new ItemExistsCondition(namespace, path);
+ default ICondition itemExists(String namespace, String path) {
+ return new ItemExistsCondition(new ResourceLocation(namespace, path));
}
- default ICondition modLoaded(String modid)
- {
+ default ICondition modLoaded(String modid) {
return new ModLoadedCondition(modid);
}
- default ICondition tagEmpty(TagKey
- tag)
- {
- return new TagEmptyCondition(tag.location());
+ default ICondition tagEmpty(TagKey
- tag) {
+ return new TagEmptyCondition(tag);
}
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/IConditionSerializer.java b/src/main/java/net/minecraftforge/common/crafting/conditions/IConditionSerializer.java
deleted file mode 100644
index 1b95445cb5..0000000000
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/IConditionSerializer.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) Forge Development LLC and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-package net.minecraftforge.common.crafting.conditions;
-
-import com.google.gson.JsonObject;
-
-import net.minecraft.resources.ResourceLocation;
-
-public interface IConditionSerializer
-{
- void write(JsonObject json, T value);
-
- T read(JsonObject json);
-
- ResourceLocation getID();
-
- default JsonObject getJson(T value)
- {
- JsonObject json = new JsonObject();
- this.write(json, value);
- json.addProperty("type", value.getID().toString());
- return json;
- }
-}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/ItemExistsCondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/ItemExistsCondition.java
index 445a5c5928..841f65724a 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/ItemExistsCondition.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/ItemExistsCondition.java
@@ -5,70 +5,29 @@
package net.minecraftforge.common.crafting.conditions;
-import com.google.gson.JsonObject;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
-import net.minecraft.util.GsonHelper;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.registries.ForgeRegistries;
-public class ItemExistsCondition implements ICondition
-{
- private static final ResourceLocation NAME = new ResourceLocation("forge", "item_exists");
- private final ResourceLocation item;
-
- public ItemExistsCondition(String location)
- {
- this(new ResourceLocation(location));
- }
-
- public ItemExistsCondition(String namespace, String path)
- {
- this(new ResourceLocation(namespace, path));
- }
-
- public ItemExistsCondition(ResourceLocation item)
- {
- this.item = item;
- }
+public record ItemExistsCondition(ResourceLocation item) implements ICondition {
+ public static Codec CODEC = RecordCodecBuilder.create(b -> b.group(
+ ResourceLocation.CODEC.fieldOf("item").forGetter(ItemExistsCondition::item)
+ ).apply(b, ItemExistsCondition::new));
@Override
- public ResourceLocation getID()
- {
- return NAME;
- }
-
- @Override
- public boolean test(IContext context)
- {
+ public boolean test(IContext context) {
return ForgeRegistries.ITEMS.containsKey(item);
}
@Override
- public String toString()
- {
+ public String toString() {
return "item_exists(\"" + item + "\")";
}
- public static class Serializer implements IConditionSerializer
- {
- public static final Serializer INSTANCE = new Serializer();
-
- @Override
- public void write(JsonObject json, ItemExistsCondition value)
- {
- json.addProperty("item", value.item.toString());
- }
-
- @Override
- public ItemExistsCondition read(JsonObject json)
- {
- return new ItemExistsCondition(new ResourceLocation(GsonHelper.getAsString(json, "item")));
- }
-
- @Override
- public ResourceLocation getID()
- {
- return ItemExistsCondition.NAME;
- }
+ @Override
+ public Codec extends ICondition> codec() {
+ return CODEC;
}
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/ModLoadedCondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/ModLoadedCondition.java
index a724213eef..c30623b14d 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/ModLoadedCondition.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/ModLoadedCondition.java
@@ -5,60 +5,29 @@
package net.minecraftforge.common.crafting.conditions;
-import com.google.gson.JsonObject;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
-import net.minecraft.util.GsonHelper;
-import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.fml.ModList;
-public class ModLoadedCondition implements ICondition
-{
- private static final ResourceLocation NAME = new ResourceLocation("forge", "mod_loaded");
- private final String modid;
-
- public ModLoadedCondition(String modid)
- {
- this.modid = modid;
- }
+public record ModLoadedCondition(String modid) implements ICondition {
+ public static final Codec CODEC = RecordCodecBuilder.create(b -> b.group(
+ Codec.STRING.fieldOf("modid").forGetter(ModLoadedCondition::modid)
+ ).apply(b, ModLoadedCondition::new));
@Override
- public ResourceLocation getID()
- {
- return NAME;
- }
-
- @Override
- public boolean test(IContext context)
- {
+ public boolean test(IContext context) {
return ModList.get().isLoaded(modid);
}
@Override
- public String toString()
- {
+ public String toString() {
return "mod_loaded(\"" + modid + "\")";
}
- public static class Serializer implements IConditionSerializer
- {
- public static final Serializer INSTANCE = new Serializer();
-
- @Override
- public void write(JsonObject json, ModLoadedCondition value)
- {
- json.addProperty("modid", value.modid);
- }
-
- @Override
- public ModLoadedCondition read(JsonObject json)
- {
- return new ModLoadedCondition(GsonHelper.getAsString(json, "modid"));
- }
-
- @Override
- public ResourceLocation getID()
- {
- return ModLoadedCondition.NAME;
- }
+ @Override
+ public Codec extends ICondition> codec() {
+ return CODEC;
}
+
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/NotCondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/NotCondition.java
index 4b6a90198e..a324ef6ce3 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/NotCondition.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/NotCondition.java
@@ -5,59 +5,26 @@
package net.minecraftforge.common.crafting.conditions;
-import com.google.gson.JsonObject;
-import net.minecraft.util.GsonHelper;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraftforge.common.crafting.CraftingHelper;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
-public class NotCondition implements ICondition
-{
- private static final ResourceLocation NAME = new ResourceLocation("forge", "not");
- private final ICondition child;
-
- public NotCondition(ICondition child)
- {
- this.child = child;
- }
+public record NotCondition(ICondition child) implements ICondition {
+ public static Codec CODEC = RecordCodecBuilder.create(b -> b.group(
+ ICondition.CODEC.fieldOf("value").forGetter(NotCondition::child)
+ ).apply(b, NotCondition::new));
@Override
- public ResourceLocation getID()
- {
- return NAME;
- }
-
- @Override
- public boolean test(IContext context)
- {
+ public boolean test(IContext context) {
return !child.test(context);
}
@Override
- public String toString()
- {
+ public String toString() {
return "!" + child;
}
- public static class Serializer implements IConditionSerializer
- {
- public static final Serializer INSTANCE = new Serializer();
-
- @Override
- public void write(JsonObject json, NotCondition value)
- {
- json.add("value", CraftingHelper.serialize(value.child));
- }
-
- @Override
- public NotCondition read(JsonObject json)
- {
- return new NotCondition(CraftingHelper.getCondition(GsonHelper.getAsJsonObject(json, "value")));
- }
-
- @Override
- public ResourceLocation getID()
- {
- return NotCondition.NAME;
- }
+ @Override
+ public Codec extends ICondition> codec() {
+ return CODEC;
}
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/OrCondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/OrCondition.java
index 107895f200..86a9dee36d 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/OrCondition.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/OrCondition.java
@@ -5,49 +5,21 @@
package net.minecraftforge.common.crafting.conditions;
-import java.util.ArrayList;
import java.util.List;
import com.google.common.base.Joiner;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonSyntaxException;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
-import net.minecraft.util.GsonHelper;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraftforge.common.crafting.CraftingHelper;
+public record OrCondition(List children) implements ICondition {
+ public static final Codec CODEC = RecordCodecBuilder.create(b -> b.group(
+ ICondition.CODEC.listOf().fieldOf("values").forGetter(AndCondition::children)
+ ).apply(b, AndCondition::new));
-public class OrCondition implements ICondition
-{
- private static final ResourceLocation NAME = new ResourceLocation("forge", "or");
- private final ICondition[] children;
-
- public OrCondition(ICondition... values)
- {
- if (values == null || values.length == 0)
- throw new IllegalArgumentException("Values must not be empty");
-
- for (ICondition child : values)
- {
- if (child == null)
- throw new IllegalArgumentException("Value must not be null");
- }
-
- this.children = values;
- }
@Override
- public ResourceLocation getID()
- {
- return NAME;
- }
-
- @Override
- public boolean test(IContext context)
- {
- for (ICondition child : children)
- {
+ public boolean test(IContext context) {
+ for (ICondition child : children) {
if (child.test(context))
return true;
}
@@ -56,41 +28,12 @@ public class OrCondition implements ICondition
}
@Override
- public String toString()
- {
+ public String toString() {
return Joiner.on(" || ").join(children);
}
- public static class Serializer implements IConditionSerializer
- {
- public static final Serializer INSTANCE = new Serializer();
-
- @Override
- public void write(JsonObject json, OrCondition value)
- {
- JsonArray values = new JsonArray();
- for (ICondition child : value.children)
- values.add(CraftingHelper.serialize(child));
- json.add("values", values);
- }
-
- @Override
- public OrCondition read(JsonObject json)
- {
- List children = new ArrayList<>();
- for (JsonElement j : GsonHelper.getAsJsonArray(json, "values"))
- {
- if (!j.isJsonObject())
- throw new JsonSyntaxException("Or condition values must be an array of JsonObjects");
- children.add(CraftingHelper.getCondition(j.getAsJsonObject()));
- }
- return new OrCondition(children.toArray(new ICondition[children.size()]));
- }
-
- @Override
- public ResourceLocation getID()
- {
- return OrCondition.NAME;
- }
+ @Override
+ public Codec extends ICondition> codec() {
+ return CODEC;
}
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/TagEmptyCondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/TagEmptyCondition.java
index 1ceb158a89..a6ba226f12 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/TagEmptyCondition.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/TagEmptyCondition.java
@@ -5,73 +5,32 @@
package net.minecraftforge.common.crafting.conditions;
-import com.google.gson.JsonObject;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
-import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
-import net.minecraft.util.GsonHelper;
import net.minecraft.resources.ResourceLocation;
-public class TagEmptyCondition implements ICondition
-{
- private static final ResourceLocation NAME = new ResourceLocation("forge", "tag_empty");
- private final TagKey
- tag;
+public record TagEmptyCondition(TagKey
- tag) implements ICondition {
+ public static final Codec CODEC = RecordCodecBuilder.create(b -> b.group(
+ ResourceLocation.CODEC.xmap(loc -> TagKey.create(Registries.ITEM, loc), TagKey::location).fieldOf("tag").forGetter(TagEmptyCondition::tag)
+ ).apply(b, TagEmptyCondition::new));
- public TagEmptyCondition(String location)
- {
- this(new ResourceLocation(location));
- }
-
- public TagEmptyCondition(String namespace, String path)
- {
- this(new ResourceLocation(namespace, path));
- }
-
- public TagEmptyCondition(ResourceLocation tag)
- {
- this.tag = TagKey.create(Registries.ITEM, tag);
- }
@Override
- public ResourceLocation getID()
- {
- return NAME;
- }
-
- @Override
- public boolean test(ICondition.IContext context)
- {
+ public boolean test(ICondition.IContext context) {
return context.getTag(tag).isEmpty();
}
@Override
- public String toString()
- {
+ public String toString() {
return "tag_empty(\"" + tag.location() + "\")";
}
- public static class Serializer implements IConditionSerializer
- {
- public static final Serializer INSTANCE = new Serializer();
-
- @Override
- public void write(JsonObject json, TagEmptyCondition value)
- {
- json.addProperty("tag", value.tag.location().toString());
- }
-
- @Override
- public TagEmptyCondition read(JsonObject json)
- {
- return new TagEmptyCondition(new ResourceLocation(GsonHelper.getAsString(json, "tag")));
- }
-
- @Override
- public ResourceLocation getID()
- {
- return TagEmptyCondition.NAME;
- }
+ @Override
+ public Codec extends ICondition> codec() {
+ return CODEC;
}
}
diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/TrueCondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/TrueCondition.java
index 51ae173038..0ae9a7b533 100644
--- a/src/main/java/net/minecraftforge/common/crafting/conditions/TrueCondition.java
+++ b/src/main/java/net/minecraftforge/common/crafting/conditions/TrueCondition.java
@@ -5,52 +5,26 @@
package net.minecraftforge.common.crafting.conditions;
-import com.google.gson.JsonObject;
+import com.mojang.serialization.Codec;
-import net.minecraft.resources.ResourceLocation;
-
-public final class TrueCondition implements ICondition
-{
+public final class TrueCondition implements ICondition {
public static final TrueCondition INSTANCE = new TrueCondition();
- private static final ResourceLocation NAME = new ResourceLocation("forge", "true");
+ public static Codec CODEC = Codec.unit(INSTANCE).stable();
private TrueCondition() {}
@Override
- public ResourceLocation getID()
- {
- return NAME;
- }
-
- @Override
- public boolean test(IContext context)
- {
+ public boolean test(IContext context) {
return true;
}
@Override
- public String toString()
- {
+ public String toString() {
return "true";
}
- public static class Serializer implements IConditionSerializer
- {
- public static final Serializer INSTANCE = new Serializer();
-
- @Override
- public void write(JsonObject json, TrueCondition value) { }
-
- @Override
- public TrueCondition read(JsonObject json)
- {
- return TrueCondition.INSTANCE;
- }
-
- @Override
- public ResourceLocation getID()
- {
- return TrueCondition.NAME;
- }
+ @Override
+ public Codec extends ICondition> codec() {
+ return CODEC;
}
}
diff --git a/src/main/java/net/minecraftforge/common/data/GlobalLootModifierProvider.java b/src/main/java/net/minecraftforge/common/data/GlobalLootModifierProvider.java
index e533e77e3a..bc63f6115c 100644
--- a/src/main/java/net/minecraftforge/common/data/GlobalLootModifierProvider.java
+++ b/src/main/java/net/minecraftforge/common/data/GlobalLootModifierProvider.java
@@ -4,7 +4,7 @@
*/
package net.minecraftforge.common.data;
-/*
+
import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -31,7 +31,7 @@ import java.util.stream.Collectors;
* Provider for forge's GlobalLootModifier system. See {@link LootModifier}
*
* This provider only requires implementing {@link #start()} and calling {@link #add} from it.
- * /
+ */
public abstract class GlobalLootModifierProvider implements DataProvider
{
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
@@ -48,7 +48,7 @@ public abstract class GlobalLootModifierProvider implements DataProvider
/**
* Sets the "replace" key in global_loot_modifiers to true.
- * /
+ */
protected void replacing()
{
this.replace = true;
@@ -56,7 +56,7 @@ public abstract class GlobalLootModifierProvider implements DataProvider
/**
* Call {@link #add} here, which will pass in the necessary information to write the jsons.
- * /
+ */
protected abstract void start();
@Override
@@ -91,7 +91,7 @@ public abstract class GlobalLootModifierProvider implements DataProvider
*
* @param modifier The name of the modifier, which will be the file name.
* @param instance The instance to serialize
- * /
+ */
public void add(String modifier, T instance)
{
JsonElement json = IGlobalLootModifier.DIRECT_CODEC.encodeStart(JsonOps.INSTANCE, instance).getOrThrow(false, s -> {});
@@ -104,4 +104,3 @@ public abstract class GlobalLootModifierProvider implements DataProvider
return "Global Loot Modifiers : " + modid;
}
}
-*/
diff --git a/src/main/java/net/minecraftforge/common/loot/CanToolPerformAction.java b/src/main/java/net/minecraftforge/common/loot/CanToolPerformAction.java
index 3deec52fe6..52a0047438 100644
--- a/src/main/java/net/minecraftforge/common/loot/CanToolPerformAction.java
+++ b/src/main/java/net/minecraftforge/common/loot/CanToolPerformAction.java
@@ -4,11 +4,11 @@
*/
package net.minecraftforge.common.loot;
-/*
+
import com.google.common.collect.ImmutableSet;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonSerializationContext;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
+
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParam;
@@ -22,46 +22,30 @@ import java.util.Set;
/**
* This LootItemCondition "forge:can_tool_perform_action" can be used to check if a tool can perform a given ToolAction.
- * /
-public class CanToolPerformAction implements LootItemCondition {
+ */
+public record CanToolPerformAction(ToolAction action) implements LootItemCondition {
+ public static final Codec CODEC = RecordCodecBuilder.create(b -> b.group(
+ ToolAction.CODEC.fieldOf("action").forGetter(CanToolPerformAction::action)
+ ).apply(b, CanToolPerformAction::new));
+ public static final LootItemConditionType TYPE = new LootItemConditionType(CODEC);
- public static final LootItemConditionType LOOT_CONDITION_TYPE = new LootItemConditionType(new CanToolPerformAction.Serializer());
-
- final ToolAction action;
-
- public CanToolPerformAction(ToolAction action) {
- this.action = action;
+ @Override
+ public @NotNull LootItemConditionType getType() {
+ return TYPE;
}
- @NotNull
- public LootItemConditionType getType() {
- return LOOT_CONDITION_TYPE;
- }
-
- @NotNull
- public Set> getReferencedContextParams() {
+ @Override
+ public @NotNull Set> getReferencedContextParams() {
return ImmutableSet.of(LootContextParams.TOOL);
}
- public boolean test(LootContext lootContext) {
- ItemStack itemstack = lootContext.getParamOrNull(LootContextParams.TOOL);
+ @Override
+ public boolean test(LootContext ctx) {
+ ItemStack itemstack = ctx.getParamOrNull(LootContextParams.TOOL);
return itemstack != null && itemstack.canPerformAction(this.action);
}
public static LootItemCondition.Builder canToolPerformAction(ToolAction action) {
return () -> new CanToolPerformAction(action);
}
-
- public static class Serializer implements net.minecraft.world.level.storage.loot.Serializer {
- public void serialize(JsonObject json, CanToolPerformAction itemCondition, @NotNull JsonSerializationContext context) {
- json.addProperty("action", itemCondition.action.name());
- }
-
- @NotNull
- public CanToolPerformAction deserialize(JsonObject json, @NotNull JsonDeserializationContext context) {
- return new CanToolPerformAction(ToolAction.get(json.get("action").getAsString()));
- }
- }
-
-}
-*/
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraftforge/common/loot/IGlobalLootModifier.java b/src/main/java/net/minecraftforge/common/loot/IGlobalLootModifier.java
index 12b12ea6ba..3def7a1d4f 100644
--- a/src/main/java/net/minecraftforge/common/loot/IGlobalLootModifier.java
+++ b/src/main/java/net/minecraftforge/common/loot/IGlobalLootModifier.java
@@ -4,11 +4,9 @@
*/
package net.minecraftforge.common.loot;
-/*
+
import com.google.gson.JsonElement;
-import com.google.gson.JsonSyntaxException;
import com.mojang.serialization.Codec;
-import com.mojang.serialization.DataResult;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.JsonOps;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@@ -16,9 +14,11 @@ import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
+import net.minecraft.world.level.storage.loot.predicates.LootItemConditions;
import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.NotNull;
+import java.util.List;
import java.util.function.Function;
/**
@@ -26,46 +26,19 @@ import java.util.function.Function;
* {@link LootModifier} Supplies base functionality; most modders should only need to extend that.
* Requires a {@link Codec} to be registered: {@link ForgeRegistries#GLOBAL_LOOT_MODIFIER_SERIALIZERS}, and returned in {@link #codec()}
* Individual instances of modifiers must be registered via json, see forge:loot_modifiers/global_loot_modifiers
- * /
+ */
public interface IGlobalLootModifier {
Codec DIRECT_CODEC = ExtraCodecs.lazyInitializedCodec(() -> ForgeRegistries.GLOBAL_LOOT_MODIFIER_SERIALIZERS.get().getCodec())
.dispatch(IGlobalLootModifier::codec, Function.identity());
- Codec LOOT_CONDITIONS_CODEC = Codec.PASSTHROUGH.flatXmap(
- d ->
- {
- try
- {
- LootItemCondition[] conditions = LootModifierManager.GSON_INSTANCE.fromJson(getJson(d), LootItemCondition[].class);
- return DataResult.success(conditions);
- }
- catch (JsonSyntaxException e)
- {
- LootModifierManager.LOGGER.warn("Unable to decode loot conditions", e);
- return DataResult.error(e::getMessage);
- }
- },
- conditions ->
- {
- try
- {
- JsonElement element = LootModifierManager.GSON_INSTANCE.toJsonTree(conditions);
- return DataResult.success(new Dynamic<>(JsonOps.INSTANCE, element));
- }
- catch (JsonSyntaxException e)
- {
- LootModifierManager.LOGGER.warn("Unable to encode loot conditions", e);
- return DataResult.error(e::getMessage);
- }
- }
- );
+ Codec LOOT_CONDITIONS_CODEC = LootItemConditions.CODEC.listOf().xmap(list -> list.toArray(LootItemCondition[]::new), List::of);
@SuppressWarnings("unchecked")
static JsonElement getJson(Dynamic> dynamic) {
Dynamic typed = (Dynamic) dynamic;
- return typed.getValue() instanceof JsonElement ?
- (JsonElement) typed.getValue() :
- typed.getOps().convertTo(JsonOps.INSTANCE, typed.getValue());
+ return typed.getValue() instanceof JsonElement element ?
+ element :
+ typed.getOps().convertTo(JsonOps.INSTANCE, typed.getValue());
}
/**
@@ -74,13 +47,12 @@ public interface IGlobalLootModifier {
* @param generatedLoot the list of ItemStacks that will be dropped, generated by loot tables
* @param context the LootContext, identical to what is passed to loot tables
* @return modified loot drops
- * /
+ */
@NotNull
ObjectArrayList apply(ObjectArrayList generatedLoot, LootContext context);
/**
* Returns the registered codec for this modifier
- * /
+ */
Codec extends IGlobalLootModifier> codec();
}
-*/
diff --git a/src/main/java/net/minecraftforge/common/loot/LootModifier.java b/src/main/java/net/minecraftforge/common/loot/LootModifier.java
index 3e136973c5..8f3efc79cf 100644
--- a/src/main/java/net/minecraftforge/common/loot/LootModifier.java
+++ b/src/main/java/net/minecraftforge/common/loot/LootModifier.java
@@ -4,7 +4,8 @@
*/
package net.minecraftforge.common.loot;
-/*
+
+import java.util.Arrays;
import java.util.function.Predicate;
import com.mojang.datafixers.Products;
@@ -20,9 +21,8 @@ import org.jetbrains.annotations.NotNull;
/**
* A base implementation of a Global Loot Modifier for modders to extend.
* Takes care of ILootCondition matching and comes with the base codec to extend.
- * /
-public abstract class LootModifier implements IGlobalLootModifier
-{
+ */
+public abstract class LootModifier implements IGlobalLootModifier {
protected final LootItemCondition[] conditions;
private final Predicate combinedConditions;
@@ -35,26 +35,23 @@ public abstract class LootModifier implements IGlobalLootModifier
*
* Otherwise can follow this with #and() to add more fields.
* Examples: Forge Test Subclasses or {@link BendingTrunkPlacer#CODEC}
- * /
- protected static Products.P1, LootItemCondition[]> codecStart(RecordCodecBuilder.Instance instance)
- {
+ */
+ protected static Products.P1, LootItemCondition[]> codecStart(RecordCodecBuilder.Instance instance) {
return instance.group(LOOT_CONDITIONS_CODEC.fieldOf("conditions").forGetter(lm -> lm.conditions));
}
/**
* Constructs a LootModifier.
* @param conditionsIn the ILootConditions that need to be matched before the loot is modified.
- * /
- protected LootModifier(LootItemCondition[] conditionsIn)
- {
+ */
+ protected LootModifier(LootItemCondition[] conditionsIn) {
this.conditions = conditionsIn;
- this.combinedConditions = LootItemConditions.andConditions(conditionsIn);
+ this.combinedConditions = LootItemConditions.andConditions(Arrays.asList(conditionsIn));
}
@NotNull
@Override
- public final ObjectArrayList apply(ObjectArrayList generatedLoot, LootContext context)
- {
+ public final ObjectArrayList apply(ObjectArrayList generatedLoot, LootContext context) {
return this.combinedConditions.test(context) ? this.doApply(generatedLoot, context) : generatedLoot;
}
@@ -64,8 +61,7 @@ public abstract class LootModifier implements IGlobalLootModifier
* @param generatedLoot the list of ItemStacks that will be dropped, generated by loot tables
* @param context the LootContext, identical to what is passed to loot tables
* @return modified loot drops
- * /
+ */
@NotNull
protected abstract ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context);
}
-*/
diff --git a/src/main/java/net/minecraftforge/common/loot/LootModifierManager.java b/src/main/java/net/minecraftforge/common/loot/LootModifierManager.java
index e80737a560..edef6697e1 100644
--- a/src/main/java/net/minecraftforge/common/loot/LootModifierManager.java
+++ b/src/main/java/net/minecraftforge/common/loot/LootModifierManager.java
@@ -4,17 +4,10 @@
*/
package net.minecraftforge.common.loot;
-/*
-import java.io.BufferedReader;
+
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.nio.charset.StandardCharsets;
import java.util.*;
-import com.mojang.datafixers.util.Pair;
-import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -22,74 +15,73 @@ import org.apache.logging.log4j.Logger;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.gson.Gson;
-import com.google.gson.JsonArray;
+import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
import net.minecraft.util.profiling.ProfilerFiller;
-import net.minecraft.server.packs.resources.Resource;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.util.GsonHelper;
import net.minecraft.resources.ResourceLocation;
-import net.minecraftforge.registries.ForgeRegistries;
public class LootModifierManager extends SimpleJsonResourceReloadListener {
- public static final Logger LOGGER = LogManager.getLogger();
- public static final Gson GSON_INSTANCE = Deserializers.createFunctionSerializer().create();
+ private static final Logger LOGGER = LogManager.getLogger();
+ private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
+ private static final String FOLDER = "loot_modifiers";
- private Map registeredLootModifiers = ImmutableMap.of();
- private static final String folder = "loot_modifiers";
+ private Map modifiers = ImmutableMap.of();
public LootModifierManager() {
- super(GSON_INSTANCE, folder);
+ super(GSON, FOLDER);
}
@Override
- protected void apply(Map resourceList, ResourceManager resourceManagerIn, ProfilerFiller profilerIn) {
- Builder builder = ImmutableMap.builder();
- List finalLocations = new ArrayList<>();
- ResourceLocation resourcelocation = new ResourceLocation("forge","loot_modifiers/global_loot_modifiers.json");
- //read in all data files from forge:loot_modifiers/global_loot_modifiers in order to do layering
- for(Resource iresource : resourceManagerIn.getResourceStack(resourcelocation)) {
- try ( InputStream inputstream = iresource.open();
- Reader reader = new BufferedReader(new InputStreamReader(inputstream, StandardCharsets.UTF_8));
- ) {
- JsonObject jsonobject = GsonHelper.fromJson(GSON_INSTANCE, reader, JsonObject.class);
- boolean replace = jsonobject.get("replace").getAsBoolean();
- if (replace)
- finalLocations.clear();
- JsonArray entryList = jsonobject.get("entries").getAsJsonArray();
- for(JsonElement entry : entryList) {
- ResourceLocation loc = new ResourceLocation(entry.getAsString());
- finalLocations.remove(loc); //remove and re-add if needed, to update the ordering.
- finalLocations.add(loc);
- }
- }
+ protected Map prepare(ResourceManager resources, ProfilerFiller profilerFiller) {
+ var path = new ResourceLocation("forge", FOLDER + "/global_loot_modifiers.json");
- catch (RuntimeException | IOException ioexception) {
- LOGGER.error("Couldn't read global loot modifier list {} in data pack {}", resourcelocation, iresource.sourcePackId(), ioexception);
+ List toLoad = new ArrayList<>();
+ //read in all data files from forge:loot_modifiers/global_loot_modifiers in order to do layering
+ for (var resource : resources.getResourceStack(path)) {
+ try (var reader = resource.openAsReader()) {
+ var json = GsonHelper.fromJson(GSON, reader, JsonObject.class);
+
+ if (GsonHelper.getAsBoolean(json, "replace", false))
+ toLoad.clear();
+
+ for(var entry : GsonHelper.getAsJsonArray(json, "entries")) {
+ ResourceLocation loc = new ResourceLocation(entry.getAsString());
+ toLoad.remove(loc); //remove and re-add if needed, to update the ordering.
+ toLoad.add(loc);
+ }
+ } catch (RuntimeException | IOException ioexception) {
+ LOGGER.error("Couldn't read global loot modifier list {} in data pack {}", path, resource.sourcePackId(), ioexception);
}
}
+
//use layered config to fetch modifier data files (modifiers missing from config are disabled)
- for (ResourceLocation location : finalLocations)
- {
- JsonElement json = resourceList.get(location);
+ var ret = super.prepare(resources, profilerFiller);
+ ret.keySet().removeIf(k -> !toLoad.contains(k));
+ return ret;
+ }
+
+ @Override
+ protected void apply(Map resources, ResourceManager resourceManagerIn, ProfilerFiller profilerIn) {
+ Builder builder = ImmutableMap.builder();
+ resources.forEach((location, json) -> {
IGlobalLootModifier.DIRECT_CODEC.parse(JsonOps.INSTANCE, json)
// log error if parse fails
.resultOrPartial(errorMsg -> LOGGER.warn("Could not decode GlobalLootModifier with json id {} - error: {}", location, errorMsg))
// add loot modifier if parse succeeds
.ifPresent(modifier -> builder.put(location, modifier));
- }
- this.registeredLootModifiers = builder.build();
+ });
+ this.modifiers = builder.build();
}
/**
* An immutable collection of the registered loot modifiers in layered order.
- * /
+ */
public Collection getAllLootMods() {
- return registeredLootModifiers.values();
+ return modifiers.values();
}
-
-}
-*/
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraftforge/common/loot/LootTableIdCondition.java b/src/main/java/net/minecraftforge/common/loot/LootTableIdCondition.java
index 9d68402911..05802e2230 100644
--- a/src/main/java/net/minecraftforge/common/loot/LootTableIdCondition.java
+++ b/src/main/java/net/minecraftforge/common/loot/LootTableIdCondition.java
@@ -4,77 +4,51 @@
*/
package net.minecraftforge.common.loot;
-/*
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonSerializationContext;
-import net.minecraft.world.level.storage.loot.Serializer;
+
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
+
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
-import net.minecraft.util.GsonHelper;
import net.minecraft.resources.ResourceLocation;
-public class LootTableIdCondition implements LootItemCondition
-{
+public record LootTableIdCondition(ResourceLocation id) implements LootItemCondition {
+ public static final Codec CODEC = RecordCodecBuilder.create(b -> b.group(
+ ResourceLocation.CODEC.fieldOf("loot_table_id").forGetter(LootTableIdCondition::id)
+ ).apply(b, LootTableIdCondition::new));
+
+
// TODO Forge Registry at some point?
- public static final LootItemConditionType LOOT_TABLE_ID = new LootItemConditionType(new LootTableIdCondition.Serializer());
+ public static final LootItemConditionType TYPE = new LootItemConditionType(CODEC);
public static final ResourceLocation UNKNOWN_LOOT_TABLE = new ResourceLocation("forge", "unknown_loot_table");
- private final ResourceLocation targetLootTableId;
-
- private LootTableIdCondition(final ResourceLocation targetLootTableId)
- {
- this.targetLootTableId = targetLootTableId;
+ @Override
+ public LootItemConditionType getType() {
+ return TYPE;
}
@Override
- public LootItemConditionType getType()
- {
- return LOOT_TABLE_ID;
+ public boolean test(LootContext ctx) {
+ return ctx.getQueriedLootTableId().equals(this.id());
}
- @Override
- public boolean test(LootContext lootContext)
- {
- return lootContext.getQueriedLootTableId().equals(this.targetLootTableId);
- }
-
- public static Builder builder(final ResourceLocation targetLootTableId)
- {
+ public static Builder builder(final ResourceLocation targetLootTableId) {
return new Builder(targetLootTableId);
}
- public static class Builder implements LootItemCondition.Builder
- {
- private final ResourceLocation targetLootTableId;
+ public static class Builder implements LootItemCondition.Builder {
+ private final ResourceLocation id;
- public Builder(ResourceLocation targetLootTableId)
- {
- if (targetLootTableId == null) throw new IllegalArgumentException("Target loot table must not be null");
- this.targetLootTableId = targetLootTableId;
+ public Builder(ResourceLocation id) {
+ if (id == null)
+ throw new IllegalArgumentException("Target loot table must not be null");
+ this.id = id;
}
@Override
- public LootItemCondition build()
- {
- return new LootTableIdCondition(this.targetLootTableId);
- }
- }
-
- public static class Serializer implements net.minecraft.world.level.storage.loot.Serializer
- {
- @Override
- public void serialize(JsonObject object, LootTableIdCondition instance, JsonSerializationContext ctx)
- {
- object.addProperty("loot_table_id", instance.targetLootTableId.toString());
- }
-
- @Override
- public LootTableIdCondition deserialize(JsonObject object, JsonDeserializationContext ctx)
- {
- return new LootTableIdCondition(new ResourceLocation(GsonHelper.getAsString(object, "loot_table_id")));
+ public LootItemCondition build() {
+ return new LootTableIdCondition(this.id);
}
}
}
-*/
\ No newline at end of file
diff --git a/src/main/java/net/minecraftforge/common/util/FakePlayer.java b/src/main/java/net/minecraftforge/common/util/FakePlayer.java
index 6bdaf259c9..8c49f47416 100644
--- a/src/main/java/net/minecraftforge/common/util/FakePlayer.java
+++ b/src/main/java/net/minecraftforge/common/util/FakePlayer.java
@@ -15,8 +15,6 @@ import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.PlayerChatMessage;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow;
-import net.minecraft.network.protocol.common.ServerboundClientInformationPacket;
-import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket;
import net.minecraft.network.protocol.game.ServerboundAcceptTeleportationPacket;
import net.minecraft.network.protocol.game.ServerboundBlockEntityTagQuery;
import net.minecraft.network.protocol.game.ServerboundChangeDifficultyPacket;
@@ -76,7 +74,7 @@ import org.jetbrains.annotations.Nullable;
/**
* A basic fake server player implementation that can be used to simulate player actions.
*/
-@Deprecated // TODO: Re-write this whole system to be less hacky. Use until we get a good replacement.
+// TODO: Re-write this whole system to be less hacky. Use until we get a good replacement.
public class FakePlayer extends ServerPlayer {
protected FakePlayer(ServerLevel level, GameProfile name, ClientInformation info) {
super(level.getServer(), level, name, info);
diff --git a/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java b/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java
index f2c2bce581..79920043cc 100644
--- a/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java
+++ b/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java
@@ -14,17 +14,14 @@ import com.mojang.authlib.GameProfile;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.network.CommonListenerCookie;
-
-@Deprecated // TODO: Re-write this whole system to be less hacky. Use until we get a good replacement.
-public class FakePlayerFactory
-{
+// TODO: Re-write this whole system to be less hacky. Use until we get a good replacement.
+public class FakePlayerFactory {
private static final GameProfile MINECRAFT = new GameProfile(UUID.fromString("41C82C87-7AfB-4024-BA57-13D2C99CAE77"), "[Minecraft]");
// Map of all active fake player usernames to their entities
private static final Map fakePlayers = Maps.newHashMap();
private record FakePlayerKey(ServerLevel level, GameProfile username) { }
- public static FakePlayer getMinecraft(ServerLevel level)
- {
+ public static FakePlayer getMinecraft(ServerLevel level) {
return get(level, MINECRAFT);
}
@@ -34,14 +31,12 @@ public class FakePlayerFactory
* WorldEvent.Unload and kill all references to prevent worlds staying in memory,
* or call this function every time and let Forge take care of the cleanup.
*/
- public static FakePlayer get(ServerLevel level, GameProfile username)
- {
+ public static FakePlayer get(ServerLevel level, GameProfile username) {
FakePlayerKey key = new FakePlayerKey(level, username);
return fakePlayers.computeIfAbsent(key, FakePlayerFactory::create);
}
- public static void unloadLevel(ServerLevel level)
- {
+ public static void unloadLevel(ServerLevel level) {
fakePlayers.entrySet().removeIf(entry -> entry.getValue().level() == level);
}
diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java
index 4a7750d0a2..56095ab20a 100644
--- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java
+++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java
@@ -63,6 +63,7 @@ import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import net.minecraft.world.level.BaseSpawner;
import net.minecraft.world.InteractionResultHolder;
+import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.InteractionResult;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
@@ -110,7 +111,9 @@ import net.minecraftforge.event.entity.living.LivingEntityUseItemEvent;
import net.minecraftforge.event.entity.living.LivingExperienceDropEvent;
import net.minecraftforge.event.entity.living.LivingHealEvent;
import net.minecraftforge.event.entity.living.LivingPackSizeEvent;
+import net.minecraftforge.event.entity.living.LivingSwapItemsEvent;
import net.minecraftforge.event.entity.living.MobSpawnEvent;
+import net.minecraftforge.event.entity.living.ShieldBlockEvent;
import net.minecraftforge.event.entity.living.MobSpawnEvent.AllowDespawn;
import net.minecraftforge.event.entity.living.MobSpawnEvent.PositionCheck;
import net.minecraftforge.event.entity.living.MobSpawnEvent.SpawnPlacementCheck;
@@ -572,11 +575,9 @@ public class ForgeEventFactory {
return onProjectileImpactResult(projectile, ray) != ProjectileImpactEvent.ImpactResult.DEFAULT;
}
- public static LootTable loadLootTable(ResourceLocation name, LootTable table) {
+ public static @Nullable LootTable onLoadLootTable(ResourceLocation name, LootTable table) {
var event = new LootTableLoadEvent(name, table);
- if (post(event))
- return LootTable.EMPTY;
- return event.getTable();
+ return post(event) ? null : event.getTable();
}
public static boolean canCreateFluidSource(Level level, BlockPos pos, BlockState state, boolean def) {
@@ -811,4 +812,16 @@ public class ForgeEventFactory {
public static void onChannelRegistrationChange(Connection connection, ChannelRegistrationChangeEvent.Type changeType, HashSet changed) {
post(new ChannelRegistrationChangeEvent(connection, changeType, changed));
}
+
+ public static LivingSwapItemsEvent.Hands onLivingSwapHandItems(LivingEntity entity) {
+ return fire(new LivingSwapItemsEvent.Hands(entity));
+ }
+
+ public static ShieldBlockEvent onShieldBlock(LivingEntity blocker, DamageSource source, float blocked) {
+ return fire(new ShieldBlockEvent(blocker, source, blocked));
+ }
+
+ public static void onEntityEnterSection(Entity entity, long packedOldPos, long packedNewPos) {
+ post(new EntityEvent.EnteringSection(entity, packedOldPos, packedNewPos));
+ }
}
diff --git a/src/main/java/net/minecraftforge/registries/ForgeDeferredRegistriesSetup.java b/src/main/java/net/minecraftforge/registries/ForgeDeferredRegistriesSetup.java
index f95f467317..91fdebd658 100644
--- a/src/main/java/net/minecraftforge/registries/ForgeDeferredRegistriesSetup.java
+++ b/src/main/java/net/minecraftforge/registries/ForgeDeferredRegistriesSetup.java
@@ -25,11 +25,12 @@ public class ForgeDeferredRegistriesSetup
}
ForgeRegistries.DEFERRED_ENTITY_DATA_SERIALIZERS.register(modEventBus);
- //ForgeRegistries.DEFERRED_GLOBAL_LOOT_MODIFIER_SERIALIZERS.register(modEventBus);
+ ForgeRegistries.DEFERRED_GLOBAL_LOOT_MODIFIER_SERIALIZERS.register(modEventBus);
ForgeRegistries.DEFERRED_BIOME_MODIFIER_SERIALIZERS.register(modEventBus);
ForgeRegistries.DEFERRED_FLUID_TYPES.register(modEventBus);
ForgeRegistries.DEFERRED_STRUCTURE_MODIFIER_SERIALIZERS.register(modEventBus);
ForgeRegistries.DEFERRED_HOLDER_SET_TYPES.register(modEventBus);
ForgeRegistries.DEFERRED_DISPLAY_CONTEXTS.register(modEventBus);
+ ForgeRegistries.DEFERRED_CONDITION_CODECS.register(modEventBus);
}
}
diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistries.java b/src/main/java/net/minecraftforge/registries/ForgeRegistries.java
index 66d10b424a..ee87775a51 100644
--- a/src/main/java/net/minecraftforge/registries/ForgeRegistries.java
+++ b/src/main/java/net/minecraftforge/registries/ForgeRegistries.java
@@ -43,6 +43,8 @@ import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacerType;
import net.minecraft.world.level.levelgen.feature.treedecorators.TreeDecoratorType;
import net.minecraftforge.common.Tags;
+import net.minecraftforge.common.crafting.conditions.ICondition;
+import net.minecraftforge.common.loot.IGlobalLootModifier;
import net.minecraftforge.common.world.BiomeModifier;
import net.minecraftforge.fluids.FluidType;
import net.minecraftforge.registries.holdersets.HolderSetType;
@@ -104,12 +106,12 @@ public class ForgeRegistries
* Use {@link Keys#ENTITY_DATA_SERIALIZERS} to create a {@link DeferredRegister}.
*/
public static final Supplier>> ENTITY_DATA_SERIALIZERS = DEFERRED_ENTITY_DATA_SERIALIZERS.makeRegistry(GameData::getDataSerializersRegistryBuilder);
- //static final DeferredRegister> DEFERRED_GLOBAL_LOOT_MODIFIER_SERIALIZERS = DeferredRegister.create(Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS.location().getNamespace());
+ static final DeferredRegister> DEFERRED_GLOBAL_LOOT_MODIFIER_SERIALIZERS = DeferredRegister.create(Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS.location().getNamespace());
/**
* Calling {@link Supplier#get()} before {@link NewRegistryEvent} is fired will result in a null registry returned.
* Use {@link Keys#GLOBAL_LOOT_MODIFIER_SERIALIZERS} to create a {@link DeferredRegister}.
*/
- //public static final Supplier>> GLOBAL_LOOT_MODIFIER_SERIALIZERS = DEFERRED_GLOBAL_LOOT_MODIFIER_SERIALIZERS.makeRegistry(GameData::getGLMSerializersRegistryBuilder);
+ public static final Supplier>> GLOBAL_LOOT_MODIFIER_SERIALIZERS = DEFERRED_GLOBAL_LOOT_MODIFIER_SERIALIZERS.makeRegistry(GameData::getGLMSerializersRegistryBuilder);
static final DeferredRegister> DEFERRED_BIOME_MODIFIER_SERIALIZERS = DeferredRegister.create(Keys.BIOME_MODIFIER_SERIALIZERS, Keys.BIOME_MODIFIER_SERIALIZERS.location().getNamespace());
/**
* Calling {@link Supplier#get()} before {@link NewRegistryEvent} is fired will result in a null registry returned.
@@ -142,6 +144,13 @@ public class ForgeRegistries
*/
public static final Supplier> DISPLAY_CONTEXTS = DEFERRED_DISPLAY_CONTEXTS.makeRegistry(GameData::getItemDisplayContextRegistryBuilder);
+ static final DeferredRegister> DEFERRED_CONDITION_CODECS = DeferredRegister.create(Keys.CONDITION_SERIALIZERS, Keys.CONDITION_SERIALIZERS.location().getNamespace());
+ /**
+ * Calling {@link Supplier#get()} before {@link NewRegistryEvent} is fired will result in a null registry returned.
+ * Use {@link Keys#CONDITION_SERIALIZERS} to create a {@link DeferredRegister}.
+ */
+ public static final Supplier>> CONDITION_SERIALIZERS = DEFERRED_CONDITION_CODECS.makeRegistry(GameData::getConditionCodecRegistryBuilder);
+
public static final class Keys {
//Vanilla
public static final ResourceKey> BLOCKS = key("block");
@@ -179,12 +188,13 @@ public class ForgeRegistries
// Forge
public static final ResourceKey>> ENTITY_DATA_SERIALIZERS = key("forge:entity_data_serializers");
- //public static final ResourceKey>> GLOBAL_LOOT_MODIFIER_SERIALIZERS = key("forge:global_loot_modifier_serializers");
+ public static final ResourceKey>> GLOBAL_LOOT_MODIFIER_SERIALIZERS = key("forge:global_loot_modifier_serializers");
public static final ResourceKey>> BIOME_MODIFIER_SERIALIZERS = key("forge:biome_modifier_serializers");
public static final ResourceKey>> STRUCTURE_MODIFIER_SERIALIZERS = key("forge:structure_modifier_serializers");
public static final ResourceKey> FLUID_TYPES = key("forge:fluid_type");
public static final ResourceKey> HOLDER_SET_TYPES = key("forge:holder_set_type");
public static final ResourceKey> DISPLAY_CONTEXTS = key("forge:display_contexts");
+ public static final ResourceKey>> CONDITION_SERIALIZERS = key("forge:condition_codecs");
// Forge Dynamic
public static final ResourceKey> BIOME_MODIFIERS = key("forge:biome_modifier");
@@ -207,4 +217,4 @@ public class ForgeRegistries
Bootstrap.bootStrap();
Tags.init();
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java
index 8c3fddf442..20bdfc7578 100644
--- a/src/main/java/net/minecraftforge/registries/GameData.java
+++ b/src/main/java/net/minecraftforge/registries/GameData.java
@@ -50,6 +50,8 @@ import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.common.CreativeModeTabRegistry;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.crafting.conditions.ICondition;
+import net.minecraftforge.common.loot.IGlobalLootModifier;
import net.minecraftforge.common.util.LogMessageAdapter;
import net.minecraftforge.common.world.BiomeModifier;
import net.minecraftforge.common.world.StructureModifier;
@@ -91,6 +93,7 @@ public class GameData
init();
}
+ @SuppressWarnings("deprecation")
public static void init()
{
if (DISABLE_VANILLA_REGISTRIES)
@@ -146,12 +149,10 @@ public class GameData
return makeRegistry(Keys.ENTITY_DATA_SERIALIZERS, 256 /*vanilla space*/, MAX_VARINT).disableSaving().disableOverrides();
}
- /*
static RegistryBuilder> getGLMSerializersRegistryBuilder()
{
return makeRegistry(Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS).disableSaving().disableSync();
}
- */
static RegistryBuilder> getBiomeModifierSerializersRegistryBuilder()
{
@@ -173,6 +174,11 @@ public class GameData
return new RegistryBuilder().disableSaving().disableSync();
}
+ static RegistryBuilder> getConditionCodecRegistryBuilder()
+ {
+ return new RegistryBuilder>().disableSaving().disableSync();
+ }
+
static RegistryBuilder getItemDisplayContextRegistryBuilder()
{
return new RegistryBuilder()
@@ -232,7 +238,6 @@ public class GameData
return RegistryManager.ACTIVE.getRegistry(Keys.POI_TYPES).getSlaveMap(BLOCKSTATE_TO_POINT_OF_INTEREST_TYPE, Map.class);
}
- @SuppressWarnings({ "unchecked", "rawtypes" })
public static void vanillaSnapshot()
{
LOGGER.debug(REGISTRIES, "Creating vanilla freeze snapshot");
@@ -250,13 +255,13 @@ public class GameData
LOGGER.debug(REGISTRIES, "Vanilla freeze snapshot created");
}
+ @SuppressWarnings("deprecation")
public static void unfreezeData()
{
LOGGER.debug(REGISTRIES, "Unfreezing vanilla registries");
BuiltInRegistries.REGISTRY.stream().filter(r -> r instanceof MappedRegistry).forEach(r -> ((MappedRegistry>)r).unfreeze());
}
- @SuppressWarnings({ "rawtypes", "unchecked" })
public static void freezeData()
{
LOGGER.debug(REGISTRIES, "Freezing registries");
@@ -286,7 +291,7 @@ public class GameData
public static void revertToFrozen() {
revertTo(RegistryManager.FROZEN, true);
}
- @SuppressWarnings({ "unchecked", "rawtypes" })
+
public static void revertTo(final RegistryManager target, boolean fireEvents)
{
if (target.registries.isEmpty())
@@ -312,7 +317,6 @@ public class GameData
LOGGER.debug(REGISTRIES, "{} state restored.", target.getName());
}
- @SuppressWarnings({ "rawtypes", "unchecked" })
public static void revert(RegistryManager state, ResourceLocation registry, boolean lock)
{
LOGGER.debug(REGISTRIES, "Reverting {} to {}", registry, state.getName());
@@ -381,8 +385,10 @@ public class GameData
this.nextId = 0;
}
+ @SuppressWarnings("unused")
void remove(I key)
{
+ @SuppressWarnings("deprecation")
Integer prev = this.tToId.remove(key);
if (prev != null)
{
@@ -437,6 +443,7 @@ public class GameData
{
final ClearableObjectIntIdentityMap idMap = new ClearableObjectIntIdentityMap()
{
+ @SuppressWarnings("deprecation")
@Override
public int getId(BlockState key)
{
@@ -527,6 +534,7 @@ public class GameData
@Override
public void onAdd(IForgeRegistryInternal owner, RegistryManager stage, int id, ResourceKey key, PoiType obj, @Nullable PoiType oldObj)
{
+ @SuppressWarnings("unchecked")
Map map = owner.getSlaveMap(BLOCKSTATE_TO_POINT_OF_INTEREST_TYPE, Map.class);
if (oldObj != null)
{
@@ -595,7 +603,6 @@ public class GameData
}
- @SuppressWarnings({ "unchecked", "rawtypes" })
public static Multimap injectSnapshot(Map snapshot, boolean injectFrozenData, boolean isLocalWorld)
{
LOGGER.info(REGISTRIES, "Injecting existing registry data into this {} instance", EffectiveSide.get());
@@ -756,7 +763,6 @@ public class GameData
}
//Another bouncer for generic reasons
- @SuppressWarnings("unchecked")
private static void processMissing(ResourceLocation name, RegistryManager STAGING, MissingMappingsEvent e, Map missing, Map remaps, Collection defaulted, Collection failed, boolean injectNetworkDummies)
{
List> mappings = e.getAllMappings(ResourceKey.createRegistryKey(name));
diff --git a/src/test_old/java/net/minecraftforge/debug/CreativeModeTabTest.java b/src/test/java/net/minecraftforge/debug/CreativeModeTabTest.java
similarity index 67%
rename from src/test_old/java/net/minecraftforge/debug/CreativeModeTabTest.java
rename to src/test/java/net/minecraftforge/debug/CreativeModeTabTest.java
index a181ee9998..dd3d4cc821 100644
--- a/src/test_old/java/net/minecraftforge/debug/CreativeModeTabTest.java
+++ b/src/test/java/net/minecraftforge/debug/CreativeModeTabTest.java
@@ -26,16 +26,14 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.RegisterEvent;
@Mod(CreativeModeTabTest.MOD_ID)
-public class CreativeModeTabTest
-{
+public class CreativeModeTabTest {
public static final String MOD_ID = "creative_mode_tab_test";
private static final boolean ENABLED = true;
private static final ResourceKey LOGS = ResourceKey.create(Registries.CREATIVE_MODE_TAB, new ResourceLocation(MOD_ID, "logs"));
private static final ResourceKey STONE = ResourceKey.create(Registries.CREATIVE_MODE_TAB, new ResourceLocation(MOD_ID, "stone"));
- public CreativeModeTabTest()
- {
+ public CreativeModeTabTest() {
if (!ENABLED)
return;
@@ -45,49 +43,45 @@ public class CreativeModeTabTest
modEventBus.addListener(CreativeModeTabTest::onCreativeModeTabBuildContents);
}
- private static void onCreativeModeTabRegister(RegisterEvent event)
- {
+ private static void onCreativeModeTabRegister(RegisterEvent event) {
event.register(Registries.CREATIVE_MODE_TAB, helper -> {
helper.register(LOGS, CreativeModeTab.builder().icon(() -> new ItemStack(Blocks.ACACIA_LOG))
- .title(Component.literal("Logs"))
- .withLabelColor(0x00FF00)
- .displayItems((params, output) -> {
- output.accept(new ItemStack(Blocks.ACACIA_LOG));
- output.accept(new ItemStack(Blocks.BIRCH_LOG));
- output.accept(new ItemStack(Blocks.DARK_OAK_LOG));
- output.accept(new ItemStack(Blocks.JUNGLE_LOG));
- output.accept(new ItemStack(Blocks.OAK_LOG));
- output.accept(new ItemStack(Blocks.SPRUCE_LOG));
- })
- .build());
+ .title(Component.literal("Logs"))
+ .withLabelColor(0x00FF00)
+ .displayItems((params, output) -> {
+ output.accept(new ItemStack(Blocks.ACACIA_LOG));
+ output.accept(new ItemStack(Blocks.BIRCH_LOG));
+ output.accept(new ItemStack(Blocks.DARK_OAK_LOG));
+ output.accept(new ItemStack(Blocks.JUNGLE_LOG));
+ output.accept(new ItemStack(Blocks.OAK_LOG));
+ output.accept(new ItemStack(Blocks.SPRUCE_LOG));
+ })
+ .build());
+
helper.register(STONE, CreativeModeTab.builder().icon(() -> new ItemStack(Blocks.STONE))
- .title(Component.literal("Stone"))
- .withLabelColor(0x0000FF)
- .displayItems((params, output) -> {
- output.accept(new ItemStack(Blocks.STONE));
- output.accept(new ItemStack(Blocks.GRANITE));
- output.accept(new ItemStack(Blocks.DIORITE));
- output.accept(new ItemStack(Blocks.ANDESITE));
- })
- .withTabsAfter(CreativeModeTabs.BUILDING_BLOCKS)
- .build());
+ .title(Component.literal("Stone"))
+ .withLabelColor(0x0000FF)
+ .displayItems((params, output) -> {
+ output.accept(new ItemStack(Blocks.STONE));
+ output.accept(new ItemStack(Blocks.GRANITE));
+ output.accept(new ItemStack(Blocks.DIORITE));
+ output.accept(new ItemStack(Blocks.ANDESITE));
+ })
+ .withTabsAfter(CreativeModeTabs.BUILDING_BLOCKS)
+ .build());
helper.register(new ResourceLocation(MOD_ID, "colors"), CreativeModeTab.builder().title(Component.literal("Colors"))
- .displayItems((params, output) ->
- {
- for (DyeColor color : DyeColor.values())
- {
- output.accept(DyeItem.byColor(color));
- }
- })
- .withTabFactory(CreativeModeColorTab::new)
- .withTabsBefore(CreativeModeTabs.COLORED_BLOCKS)
- .build()
+ .displayItems((params, output) -> {
+ for (DyeColor color : DyeColor.values())
+ output.accept(DyeItem.byColor(color));
+ })
+ .withTabFactory(CreativeModeColorTab::new)
+ .withTabsBefore(CreativeModeTabs.COLORED_BLOCKS)
+ .build()
);
List blocks = List.of(Blocks.GRANITE, Blocks.DIORITE, Blocks.ANDESITE, Blocks.COBBLESTONE);
- for (int i = 0; i < blocks.size(); i++)
- {
+ for (int i = 0; i < blocks.size(); i++) {
Block block = blocks.get(i);
helper.register(new ResourceLocation(MOD_ID, "dummy" + i), CreativeModeTab.builder()
.title(Component.literal("Dummy " + i))
@@ -99,22 +93,20 @@ public class CreativeModeTabTest
//final ResourceLocation custom_tabs_image = new ResourceLocation(MOD_ID, "textures/gui/container/creative_inventory/custom_tabs.png");
helper.register(new ResourceLocation(MOD_ID, "with_tabs_image"), CreativeModeTab.builder()
- .title(Component.translatable("itemGroup.with_tabs_image"))
- .icon(() -> new ItemStack(Blocks.BRICKS))
- .displayItems((params, output) -> output.accept(Blocks.BRICKS))
- //.withTabsImage(custom_tabs_image)
- .build());
+ .title(Component.translatable("itemGroup.with_tabs_image"))
+ .icon(() -> new ItemStack(Blocks.BRICKS))
+ .displayItems((params, output) -> output.accept(Blocks.BRICKS))
+ //.withTabsImage(custom_tabs_image)
+ .build());
});
}
private static ItemStack i(ItemLike item) { return new ItemStack(item); }
- private static void onCreativeModeTabBuildContents(BuildCreativeModeTabContentsEvent event)
- {
+ private static void onCreativeModeTabBuildContents(BuildCreativeModeTabContentsEvent event) {
var entries = event.getEntries();
var vis = TabVisibility.PARENT_AND_SEARCH_TABS;
- if (event.getTabKey() == LOGS)
- {
+ if (event.getTabKey() == LOGS) {
entries.putAfter(i(Blocks.ACACIA_LOG), i(Blocks.STRIPPED_ACACIA_LOG), vis);
entries.putAfter(i(Blocks.BIRCH_LOG), i(Blocks.STRIPPED_BIRCH_LOG), vis);
entries.putAfter(i(Blocks.DARK_OAK_LOG), i(Blocks.STRIPPED_DARK_OAK_LOG), vis);
@@ -123,8 +115,7 @@ public class CreativeModeTabTest
entries.putAfter(i(Blocks.SPRUCE_LOG), i(Blocks.STRIPPED_SPRUCE_LOG), vis);
}
- if (event.getTabKey() == STONE)
- {
+ if (event.getTabKey() == STONE) {
entries.putBefore(i(Blocks.STONE), i(Blocks.SMOOTH_STONE), vis);
entries.putBefore(i(Blocks.GRANITE), i(Blocks.POLISHED_GRANITE), vis);
entries.putBefore(i(Blocks.DIORITE), i(Blocks.POLISHED_DIORITE), vis);
@@ -132,25 +123,20 @@ public class CreativeModeTabTest
}
}
- private static class CreativeModeColorTab extends CreativeModeTab
- {
+ private static class CreativeModeColorTab extends CreativeModeTab {
private final ItemStack[] iconItems;
- public CreativeModeColorTab(CreativeModeTab.Builder builder)
- {
+ public CreativeModeColorTab(CreativeModeTab.Builder builder) {
super(builder);
DyeColor[] colors = DyeColor.values();
iconItems = new ItemStack[colors.length];
for (int i = 0; i < colors.length; i++)
- {
iconItems[i] = new ItemStack(DyeItem.byColor(colors[i]));
- }
}
@Override
- public ItemStack getIconItem()
- {
+ public ItemStack getIconItem() {
int idx = (int)(System.currentTimeMillis() / 1200) % iconItems.length;
return iconItems[idx];
}
diff --git a/src/test_old/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java b/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java
similarity index 63%
rename from src/test_old/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java
rename to src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java
index e73d325402..c409a712da 100644
--- a/src/test_old/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java
+++ b/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java
@@ -4,37 +4,34 @@
*/
package net.minecraftforge.debug.gameplay.loot;
-/*
+
import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableMap;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.advancements.critereon.EnchantmentPredicate;
import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.advancements.critereon.MinMaxBounds;
-import net.minecraft.core.registries.Registries;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.level.block.Blocks;
-import net.minecraft.data.DataGenerator;
import net.minecraft.data.PackOutput;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantment.Rarity;
-import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
+import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
-import net.minecraft.world.item.crafting.SmeltingRecipe;
+import net.minecraft.world.item.CreativeModeTab.TabVisibility;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.LootParams;
-import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
-import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
import net.minecraft.world.level.storage.loot.predicates.MatchTool;
@@ -45,9 +42,10 @@ import net.minecraftforge.common.loot.LootModifier;
import net.minecraftforge.common.loot.LootTableIdCondition;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.registries.RegistryObject;
+import net.minecraftforge.test.Empty;
import net.minecraftforge.fml.common.Mod;
-import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.data.event.GatherDataEvent;
+import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.registries.DeferredRegister;
@@ -62,64 +60,78 @@ public class GlobalLootModifiersTest {
public static final String MODID = "global_loot_test";
public static final boolean ENABLE = true;
- public GlobalLootModifiersTest()
- {
- if(ENABLE)
- {
- GLM.register(FMLJavaModLoadingContext.get().getModEventBus());
- ENCHANTS.register(FMLJavaModLoadingContext.get().getModEventBus());
- }
+ public GlobalLootModifiersTest() {
+ if (!ENABLE)
+ return;
+
+ var modBus = FMLJavaModLoadingContext.get().getModEventBus();
+ GLM.register(modBus);
+ ENCHANTS.register(modBus);
+ modBus.register(this);
+
}
private static final DeferredRegister> GLM = DeferredRegister.create(ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, MODID);
private static final DeferredRegister ENCHANTS = DeferredRegister.create(ForgeRegistries.ENCHANTMENTS, MODID);
- private static final RegistryObject> DUNGEON_LOOT = GLM.register("dungeon_loot", DungeonLootEnhancerModifier.CODEC);
- private static final RegistryObject> SMELTING = GLM.register("smelting", SmeltingEnchantmentModifier.CODEC);
- private static final RegistryObject> WHEATSEEDS = GLM.register("wheat_harvest", WheatSeedsConverterModifier.CODEC);
- private static final RegistryObject> SILKTOUCH = GLM.register("silk_touch_bamboo", SilkTouchTestModifier.CODEC);
- private static final RegistryObject SMELT = ENCHANTS.register("smelt", () -> new SmelterEnchantment(Rarity.UNCOMMON, EnchantmentCategory.DIGGER, EquipmentSlot.MAINHAND));
+ public static final RegistryObject> DUNGEON_LOOT = GLM.register("dungeon_loot", DungeonLootEnhancerModifier.CODEC);
+ public static final RegistryObject> SMELTING = GLM.register("smelting", SmeltingEnchantmentModifier.CODEC);
+ public static final RegistryObject> WHEATSEEDS = GLM.register("wheat_harvest", WheatSeedsConverterModifier.CODEC);
+ public static final RegistryObject> SILKTOUCH = GLM.register("silk_touch_bamboo", SilkTouchTestModifier.CODEC);
+ public static final RegistryObject SMELT = ENCHANTS.register("smelt", () -> new SmelterEnchantment(Rarity.UNCOMMON, EnchantmentCategory.DIGGER, EquipmentSlot.MAINHAND));
- @EventBusSubscriber(modid = MODID, bus = EventBusSubscriber.Bus.MOD)
- public static class EventHandlers {
- @SubscribeEvent
- public static void runData(GatherDataEvent event)
- {
- if(ENABLE)
- event.getGenerator().addProvider(event.includeServer(), new DataProvider(event.getGenerator().getPackOutput(), MODID));
+ @SubscribeEvent
+ public void runData(GatherDataEvent event) {
+ event.getGenerator().addProvider(event.includeServer(), new DataProvider(event.getGenerator().getPackOutput(), MODID));
+ }
+
+ @SubscribeEvent
+ public void onCreativeModeTabBuildContents(BuildCreativeModeTabContentsEvent event) {
+ var entries = event.getEntries();
+ var vis = TabVisibility.PARENT_AND_SEARCH_TABS;
+ if (event.getTabKey() == Empty.TAB) {
+ var smelt = new ItemStack(Items.SHEARS);
+ EnchantmentHelper.setEnchantments(ImmutableMap.builder().put(SMELT.get(), 1).build(), smelt);
+ entries.put(smelt, vis);
}
}
- private static class DataProvider extends GlobalLootModifierProvider
- {
- public DataProvider(PackOutput output, String modid)
- {
+ private static class DataProvider extends GlobalLootModifierProvider {
+ public DataProvider(PackOutput output, String modid) {
super(output, modid);
}
@Override
- protected void start()
- {
+ protected void start() {
add("smelting", new SmeltingEnchantmentModifier(
- new LootItemCondition[]{
- MatchTool.toolMatches(
- ItemPredicate.Builder.item().hasEnchantment(
- new EnchantmentPredicate(SMELT.get(), MinMaxBounds.Ints.atLeast(1))))
- .build()
- })
+ new LootItemCondition[]{
+ MatchTool.toolMatches(
+ ItemPredicate.Builder.item().hasEnchantment(
+ new EnchantmentPredicate(SMELT.get(), MinMaxBounds.Ints.atLeast(1))
+ )
+ ).build()
+ })
);
add("wheat_harvest", new WheatSeedsConverterModifier(
- new LootItemCondition[] {
- MatchTool.toolMatches(ItemPredicate.Builder.item().of(Items.SHEARS)).build(),
- LootItemBlockStatePropertyCondition.hasBlockStateProperties(Blocks.WHEAT).build()
- },
- 3, Items.WHEAT_SEEDS, Items.WHEAT)
+ new LootItemCondition[] {
+ MatchTool.toolMatches(ItemPredicate.Builder.item().of(Items.SHEARS)).build(),
+ LootItemBlockStatePropertyCondition.hasBlockStateProperties(Blocks.WHEAT).build()
+ },
+ 3, Items.WHEAT_SEEDS, Items.WHEAT)
);
add("dungeon_loot", new DungeonLootEnhancerModifier(
- new LootItemCondition[] { LootTableIdCondition.builder(new ResourceLocation("chests/simple_dungeon")).build() },
- 2)
+ new LootItemCondition[] {
+ LootTableIdCondition.builder(new ResourceLocation("chests/simple_dungeon")).build()
+ }, 2)
+ );
+
+ // Bamboo silk harvests everything
+ add("bamboo_silk", new SilkTouchTestModifier(
+ new LootItemCondition[] {
+ MatchTool.toolMatches(ItemPredicate.Builder.item().of(Items.BAMBOO)).build()
+ })
);
}
}
@@ -132,10 +144,14 @@ public class GlobalLootModifiersTest {
/**
* The smelting enchantment causes this modifier to be invoked, via the smelting loot_modifier json
- *
- * /
+ */
private static class SmeltingEnchantmentModifier extends LootModifier {
- public static final Supplier> CODEC = Suppliers.memoize(() -> RecordCodecBuilder.create(inst -> codecStart(inst).apply(inst, SmeltingEnchantmentModifier::new)));
+ public static final Supplier> CODEC = Suppliers.memoize(() ->
+ RecordCodecBuilder.create(inst ->
+ codecStart(inst)
+ .apply(inst, SmeltingEnchantmentModifier::new)
+ )
+ );
public SmeltingEnchantmentModifier(LootItemCondition[] conditionsIn) {
super(conditionsIn);
@@ -144,8 +160,8 @@ public class GlobalLootModifiersTest {
@NotNull
@Override
public ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context) {
- ObjectArrayList ret = new ObjectArrayList();
- generatedLoot.forEach((stack) -> ret.add(smelt(stack, context)));
+ var ret = new ObjectArrayList();
+ generatedLoot.forEach(stack -> ret.add(smelt(stack, context)));
return ret;
}
@@ -170,9 +186,14 @@ public class GlobalLootModifiersTest {
/**
* When harvesting blocks with bamboo, this modifier is invoked, via the silk_touch_bamboo loot_modifier json
*
- * /
+ */
private static class SilkTouchTestModifier extends LootModifier {
- public static final Supplier> CODEC = Suppliers.memoize(() -> RecordCodecBuilder.create(inst -> codecStart(inst).apply(inst, SilkTouchTestModifier::new)));
+ public static final Supplier> CODEC = Suppliers.memoize(() ->
+ RecordCodecBuilder.create(inst ->
+ codecStart(inst)
+ .apply(inst, SilkTouchTestModifier::new)
+ )
+ );
public SilkTouchTestModifier(LootItemCondition[] conditionsIn) {
super(conditionsIn);
@@ -181,15 +202,18 @@ public class GlobalLootModifiersTest {
@NotNull
@Override
public ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context) {
- ItemStack ctxTool = context.getParamOrNull(LootContextParams.TOOL);
+ var ctxTool = context.getParamOrNull(LootContextParams.TOOL);
//return early if silk-touch is already applied (otherwise we'll get stuck in an infinite loop).
- if(ctxTool == null || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, ctxTool) > 0) return generatedLoot;
- ItemStack fakeTool = ctxTool.copy();
+ if (ctxTool == null || ctxTool.getEnchantmentLevel(Enchantments.SILK_TOUCH) > 0) return generatedLoot;
+ var fakeTool = ctxTool.copy();
fakeTool.enchant(Enchantments.SILK_TOUCH, 1);
- LootParams.Builder builder = new LootParams.Builder(context.getLevel());
- builder.withParameter(LootContextParams.TOOL, fakeTool);
- LootTable loottable = context.getLevel().getServer().getLootData().getLootTable(context.getParamOrNull(LootContextParams.BLOCK_STATE).getBlock().getLootTable());
- return loottable.getRandomItems(builder.create(LootContextParamSets.EMPTY)); // TODO - porting: we need an AT
+ var params = new LootParams.Builder(context.getLevel())
+ .withParameter(LootContextParams.TOOL, fakeTool)
+ .create(LootContextParamSets.EMPTY);
+
+ return context.getLevel().getServer().getLootData()
+ .getLootTable(context.getParamOrNull(LootContextParams.BLOCK_STATE).getBlock().getLootTable())
+ .getRandomItems(params);
}
@Override
@@ -202,14 +226,14 @@ public class GlobalLootModifiersTest {
* When harvesting wheat with shears, this modifier is invoked via the wheat_harvest loot_modifier json
* This modifier checks how many seeds were harvested and turns X seeds into Y wheat (3:1)
*
- * /
+ */
private static class WheatSeedsConverterModifier extends LootModifier {
public static final Supplier> CODEC = Suppliers.memoize(() -> RecordCodecBuilder.create(inst -> codecStart(inst).and(
- inst.group(
- Codec.INT.fieldOf("numSeeds").forGetter(m -> m.numSeedsToConvert),
- ForgeRegistries.ITEMS.getCodec().fieldOf("seedItem").forGetter(m -> m.itemToCheck),
- ForgeRegistries.ITEMS.getCodec().fieldOf("replacement").forGetter(m -> m.itemReward)
- )).apply(inst, WheatSeedsConverterModifier::new)
+ inst.group(
+ Codec.INT.fieldOf("numSeeds").forGetter(m -> m.numSeedsToConvert),
+ ForgeRegistries.ITEMS.getCodec().fieldOf("seedItem").forGetter(m -> m.itemToCheck),
+ ForgeRegistries.ITEMS.getCodec().fieldOf("replacement").forGetter(m -> m.itemReward)
+ )).apply(inst, WheatSeedsConverterModifier::new)
));
private final int numSeedsToConvert;
@@ -252,8 +276,8 @@ public class GlobalLootModifiersTest {
private static class DungeonLootEnhancerModifier extends LootModifier {
public static final Supplier> CODEC = Suppliers.memoize(() -> RecordCodecBuilder.create(inst -> codecStart(inst)
- .and(ExtraCodecs.POSITIVE_INT.optionalFieldOf("multiplication_factor", 2).forGetter(m -> m.multiplicationFactor))
- .apply(inst, DungeonLootEnhancerModifier::new)
+ .and(ExtraCodecs.POSITIVE_INT.optionalFieldOf("multiplication_factor", 2).forGetter(m -> m.multiplicationFactor))
+ .apply(inst, DungeonLootEnhancerModifier::new)
));
private final int multiplicationFactor;
@@ -266,9 +290,9 @@ public class GlobalLootModifiersTest {
@Override
protected ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context) {
return generatedLoot.stream()
- .map(ItemStack::copy)
- .peek(stack -> stack.setCount(Math.min(stack.getMaxStackSize(), stack.getCount() * this.multiplicationFactor)))
- .collect(Collectors.toCollection(ObjectArrayList::new));
+ .map(ItemStack::copy)
+ .peek(stack -> stack.setCount(Math.min(stack.getMaxStackSize(), stack.getCount() * this.multiplicationFactor)))
+ .collect(Collectors.toCollection(ObjectArrayList::new));
}
@Override
@@ -276,5 +300,4 @@ public class GlobalLootModifiersTest {
return CODEC.get();
}
}
-}
-*/
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/test/java/net/minecraftforge/test/Empty.java b/src/test/java/net/minecraftforge/test/Empty.java
index 8e10b08e3d..4aacb2d78f 100644
--- a/src/test/java/net/minecraftforge/test/Empty.java
+++ b/src/test/java/net/minecraftforge/test/Empty.java
@@ -5,10 +5,59 @@
package net.minecraftforge.test;
-import net.minecraftforge.fml.common.Mod;
+import java.util.Optional;
-/* Empty test mod to make FML happy if there are no others */
-@Mod("empty")
+import net.minecraft.DetectedVersion;
+import net.minecraft.core.registries.Registries;
+import net.minecraft.data.metadata.PackMetadataGenerator;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.packs.PackType;
+import net.minecraft.server.packs.metadata.pack.PackMetadataSection;
+import net.minecraft.world.item.CreativeModeTab;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.Items;
+import net.minecraftforge.data.event.GatherDataEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
+import net.minecraftforge.registries.RegisterEvent;
+
+/* A place where I can put common utility stuff for now. Until I re-write the test codebase. */
+@Mod(Empty.MOD_ID)
public class Empty {
-
+ public static final String MOD_ID = "empty";
+ public static final ResourceKey TAB = ResourceKey.create(Registries.CREATIVE_MODE_TAB, new ResourceLocation(MOD_ID, "test_items"));
+
+ public Empty() {
+ var modBus = FMLJavaModLoadingContext.get().getModEventBus();
+ modBus.register(this);
+ }
+
+ @SubscribeEvent
+ public void onRegister(RegisterEvent event) {
+ event.register(Registries.CREATIVE_MODE_TAB, h -> {
+ h.register(TAB, CreativeModeTab.builder()
+ .icon(() -> new ItemStack(Items.STICK))
+ .title(Component.literal("Test Items"))
+ .build()
+ );
+ });
+ }
+
+ @SubscribeEvent
+ public void onDataGen(GatherDataEvent event) {
+ var gen = event.getGenerator();
+ var packOutput = gen.getPackOutput();
+
+ gen.addProvider(true, new PackMetadataGenerator(packOutput)
+ .add(PackMetadataSection.TYPE, new PackMetadataSection(
+ Component.literal("Forge tests resource pack"),
+ DetectedVersion.BUILT_IN.getPackVersion(PackType.CLIENT_RESOURCES),
+ Optional.empty()
+ //Arrays.stream(PackType.values()).collect(Collectors.toMap(Function.identity(), DetectedVersion.BUILT_IN::getPackVersion))
+ ))
+ );
+ }
}
diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/META-INF/mods.toml
index e421c88e14..56730474a7 100644
--- a/src/test/resources/META-INF/mods.toml
+++ b/src/test/resources/META-INF/mods.toml
@@ -3,4 +3,18 @@ loaderVersion="[28,)"
license="LGPL v2.1"
[[mods]]
-modId="empty"
\ No newline at end of file
+modId="empty"
+
+[[mods]]
+modId="creative_mode_tab_test"
+
+
+
+[[mods]]
+modId="global_loot_test"
+[[dependencies.global_loot_test]]
+modId="forge"
+mandatory=true
+versionRange="[1,)"
+ordering="AFTER"
+side="BOTH"
diff --git a/src/test_old/java/net/minecraftforge/debug/DataGeneratorTest.java b/src/test_old/java/net/minecraftforge/debug/DataGeneratorTest.java
index 9d9937e3a6..1e90131105 100644
--- a/src/test_old/java/net/minecraftforge/debug/DataGeneratorTest.java
+++ b/src/test_old/java/net/minecraftforge/debug/DataGeneratorTest.java
@@ -4,13 +4,12 @@
*/
package net.minecraftforge.debug;
-/*
+
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
@@ -22,7 +21,6 @@ import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
-import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
@@ -30,25 +28,23 @@ import java.util.stream.Stream;
import com.google.gson.JsonNull;
import com.google.gson.JsonPrimitive;
import net.minecraft.DetectedVersion;
-import net.minecraft.Util;
import net.minecraft.advancements.critereon.InventoryChangeTrigger;
-import net.minecraft.core.*;
+import net.minecraft.core.Direction;
+import net.minecraft.core.Holder;
+import net.minecraft.core.HolderGetter;
+import net.minecraft.core.HolderLookup;
+import net.minecraft.core.RegistrySetBuilder;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.PackOutput;
import net.minecraft.data.metadata.PackMetadataGenerator;
-import net.minecraft.data.recipes.*;
import net.minecraft.data.worldgen.BootstapContext;
-import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.packs.metadata.pack.PackMetadataSection;
import net.minecraft.sounds.SoundEvents;
-import net.minecraft.tags.ItemTags;
import net.minecraft.world.item.ItemDisplayContext;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.TheEndBiomeSource;
import net.minecraft.world.level.block.ButtonBlock;
@@ -61,11 +57,6 @@ import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
-import net.minecraftforge.common.crafting.CompoundIngredient;
-import net.minecraftforge.common.crafting.PartialNBTIngredient;
-import net.minecraftforge.common.crafting.DifferenceIngredient;
-import net.minecraftforge.common.crafting.IntersectionIngredient;
-import net.minecraftforge.common.crafting.StrictNBTIngredient;
import net.minecraftforge.common.data.*;
import net.minecraftforge.registries.ForgeRegistries;
import org.apache.commons.lang3.tuple.Triple;
@@ -85,7 +76,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.advancements.Advancement;
-import net.minecraft.advancements.AdvancementRewards;
+import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.advancements.FrameType;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.renderer.block.model.ItemTransform;
@@ -108,9 +99,6 @@ import net.minecraftforge.client.model.generators.ModelFile;
import net.minecraftforge.client.model.generators.ModelFile.UncheckedModelFile;
import net.minecraftforge.client.model.generators.MultiPartBlockStateBuilder;
import net.minecraftforge.client.model.generators.VariantBlockStateBuilder;
-import net.minecraftforge.common.crafting.ConditionalAdvancement;
-import net.minecraftforge.common.crafting.ConditionalRecipe;
-import net.minecraftforge.common.crafting.conditions.IConditionBuilder;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
@@ -130,8 +118,7 @@ import net.minecraft.world.level.block.TrapDoorBlock;
@SuppressWarnings("deprecation")
@Mod(DataGeneratorTest.MODID)
@Mod.EventBusSubscriber(bus = Bus.MOD)
-public class DataGeneratorTest
-{
+public class DataGeneratorTest {
static final String MODID = "data_gen_test";
private static Gson GSON = null;
@@ -144,24 +131,24 @@ public class DataGeneratorTest
.add(Registries.LEVEL_STEM, DataGeneratorTest::levelStem);
@SubscribeEvent
- public static void gatherData(GatherDataEvent event)
- {
+ public static void gatherData(GatherDataEvent event) {
GSON = new GsonBuilder()
- .registerTypeAdapter(Variant.class, new Variant.Deserializer())
- .registerTypeAdapter(ItemTransforms.class, new ItemTransforms.Deserializer())
- .registerTypeAdapter(ItemTransform.class, new ItemTransform.Deserializer())
- .create();
+ .registerTypeAdapter(Variant.class, new Variant.Deserializer())
+ .registerTypeAdapter(ItemTransforms.class, new ItemTransforms.Deserializer())
+ .registerTypeAdapter(ItemTransform.class, new ItemTransform.Deserializer())
+ .create();
DataGenerator gen = event.getGenerator();
PackOutput packOutput = gen.getPackOutput();
CompletableFuture lookupProvider = event.getLookupProvider();
gen.addProvider(true, new PackMetadataGenerator(packOutput)
- .add(PackMetadataSection.TYPE, new PackMetadataSection(
- Component.literal("Forge tests resource pack"),
- DetectedVersion.BUILT_IN.getPackVersion(PackType.CLIENT_RESOURCES),
- Arrays.stream(PackType.values()).collect(Collectors.toMap(Function.identity(), DetectedVersion.BUILT_IN::getPackVersion))
- ))
+ .add(PackMetadataSection.TYPE, new PackMetadataSection(
+ Component.literal("Forge tests resource pack"),
+ DetectedVersion.BUILT_IN.getPackVersion(PackType.CLIENT_RESOURCES),
+ Optional.empty()
+ //Arrays.stream(PackType.values()).collect(Collectors.toMap(Function.identity(), DetectedVersion.BUILT_IN::getPackVersion))
+ ))
);
gen.addProvider(event.includeClient(), new Lang(packOutput));
// Let blockstate provider see generated item models by passing its existing file helper
@@ -171,7 +158,7 @@ public class DataGeneratorTest
gen.addProvider(event.includeClient(), new SoundDefinitions(packOutput, event.getExistingFileHelper()));
gen.addProvider(event.includeClient(), new ParticleDescriptions(packOutput, event.getExistingFileHelper()));
- gen.addProvider(event.includeServer(), new Recipes(packOutput));
+ //gen.addProvider(event.includeServer(), new Recipes(packOutput));
gen.addProvider(event.includeServer(), new Tags(packOutput, lookupProvider, event.getExistingFileHelper()));
gen.addProvider(event.includeServer(), new ForgeAdvancementProvider(packOutput, lookupProvider, event.getExistingFileHelper(), List.of(new Advancements())));
gen.addProvider(event.includeServer(), new DatapackBuiltinEntriesProvider(packOutput, lookupProvider, BUILDER, Set.of(MODID)));
@@ -187,6 +174,7 @@ public class DataGeneratorTest
context.register(TEST_LEVEL_STEM, levelStem);
}
+ /*
public static class Recipes extends RecipeProvider implements IConditionBuilder
{
public Recipes(PackOutput gen)
@@ -367,6 +355,7 @@ public class DataGeneratorTest
.save(consumer, new ResourceLocation("data_gen_test", "compound_ingredient_custom_types"));
}
}
+ */
public static class SoundDefinitions extends SoundDefinitionsProvider
{
@@ -1059,12 +1048,9 @@ public class DataGeneratorTest
}
}
- private static class Advancements implements ForgeAdvancementProvider.AdvancementGenerator
- {
-
+ private static class Advancements implements ForgeAdvancementProvider.AdvancementGenerator {
@Override
- public void generate(HolderLookup.Provider registries, Consumer saver, ExistingFileHelper existingFileHelper)
- {
+ public void generate(HolderLookup.Provider registries, Consumer saver, ExistingFileHelper existingFileHelper) {
Advancement.Builder.advancement().display(Items.DIRT,
Component.translatable(Items.DIRT.getDescriptionId()),
Component.translatable("dirt_description"),
@@ -1074,7 +1060,7 @@ public class DataGeneratorTest
true,
false)
.addCriterion("has_dirt", InventoryChangeTrigger.TriggerInstance.hasItems(Items.DIRT))
- .save(saver, new ResourceLocation(MODID, "obtain_dirt"), existingFileHelper);
+ .save(saver, new ResourceLocation(MODID, "obtain_dirt"));
Advancement.Builder.advancement().display(Items.DIAMOND_BLOCK,
Component.translatable(Items.DIAMOND_BLOCK.getDescriptionId()),
@@ -1085,7 +1071,7 @@ public class DataGeneratorTest
true,
false)
.addCriterion("obtained_diamond_block", InventoryChangeTrigger.TriggerInstance.hasItems(Items.DIAMOND_BLOCK))
- .save(saver, new ResourceLocation("obtain_diamond_block"), existingFileHelper);
+ .save(saver, new ResourceLocation("obtain_diamond_block"));
Advancement.Builder.advancement()
.display(Blocks.GRASS_BLOCK,
@@ -1097,7 +1083,7 @@ public class DataGeneratorTest
false,
false)
.addCriterion("crafting_table", InventoryChangeTrigger.TriggerInstance.hasItems(Blocks.CRAFTING_TABLE))
- .save(saver, new ResourceLocation("story/root"), existingFileHelper);
+ .save(saver, new ResourceLocation("story/root"));
// This should cause an error because of the parent not existing
/* Advancement.Builder.advancement().display(Blocks.COBBLESTONE,
@@ -1111,7 +1097,7 @@ public class DataGeneratorTest
.addCriterion("get_cobbleStone", InventoryChangeTrigger.Instance.hasItems(Items.COBBLESTONE))
.parent(new ResourceLocation("not_there/not_here"))
.save(consumer, new ResourceLocation("illegal_parent"), fileHelper);
-* /
+*/
Advancement.Builder.advancement().display(Blocks.COBBLESTONE,
Component.translatable(Items.COBBLESTONE.getDescriptionId()),
@@ -1123,7 +1109,7 @@ public class DataGeneratorTest
false)
.addCriterion("get_cobbleStone", InventoryChangeTrigger.TriggerInstance.hasItems(Items.COBBLESTONE))
.parent(new ResourceLocation("forge", "dummy_parent"))
- .save(saver, new ResourceLocation("good_parent"), existingFileHelper);
+ .save(saver, new ResourceLocation("good_parent"));
}
}
@@ -1266,4 +1252,3 @@ public class DataGeneratorTest
return model.replaceAll("^\\w+:", "minecraft:");
}
}
-*/
diff --git a/src/test_old/java/net/minecraftforge/debug/fluid/NewFluidTest.java b/src/test_old/java/net/minecraftforge/debug/fluid/NewFluidTest.java
index aad2b68f6c..c084053b14 100644
--- a/src/test_old/java/net/minecraftforge/debug/fluid/NewFluidTest.java
+++ b/src/test_old/java/net/minecraftforge/debug/fluid/NewFluidTest.java
@@ -4,7 +4,8 @@
*/
package net.minecraftforge.debug.fluid;
-/*
+
+import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.*;
import net.minecraft.world.level.material.MapColor;
import net.minecraft.world.level.material.FluidState;
@@ -59,41 +60,33 @@ public class NewFluidTest {
public static final DeferredRegister FLUID_TYPES = DeferredRegister.create(ForgeRegistries.Keys.FLUID_TYPES, MODID);
public static final DeferredRegister FLUIDS = DeferredRegister.create(ForgeRegistries.FLUIDS, MODID);
- private static ForgeFlowingFluid.Properties makeProperties()
- {
+ private static ForgeFlowingFluid.Properties makeProperties() {
return new ForgeFlowingFluid.Properties(test_fluid_type, test_fluid, test_fluid_flowing)
.bucket(TEST_FLUID_BUCKET).block(test_fluid_block);
}
- public static RegistryObject test_fluid_type = FLUID_TYPES.register("test_fluid", () -> new FluidType(FluidType.Properties.create())
- {
+ public static RegistryObject test_fluid_type = FLUID_TYPES.register("test_fluid", () -> new FluidType(FluidType.Properties.create()) {
@Override
- public void initializeClient(Consumer consumer)
- {
- consumer.accept(new IClientFluidTypeExtensions()
- {
+ public void initializeClient(Consumer consumer) {
+ consumer.accept(new IClientFluidTypeExtensions() {
@Override
- public ResourceLocation getStillTexture()
- {
+ public ResourceLocation getStillTexture() {
return FLUID_STILL;
}
@Override
- public ResourceLocation getFlowingTexture()
- {
+ public ResourceLocation getFlowingTexture() {
return FLUID_FLOWING;
}
@Nullable
@Override
- public ResourceLocation getOverlayTexture()
- {
+ public ResourceLocation getOverlayTexture() {
return FLUID_OVERLAY;
}
@Override
- public int getTintColor()
- {
+ public int getTintColor() {
return 0x3F1080FF;
}
});
@@ -122,10 +115,8 @@ public class NewFluidTest {
new BlockItem(fluidloggable_block.get(), new Item.Properties())
);
- public NewFluidTest()
- {
- if (ENABLE)
- {
+ public NewFluidTest() {
+ if (ENABLE) {
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
modEventBus.addListener(this::loadComplete);
@@ -138,17 +129,14 @@ public class NewFluidTest {
}
}
- private void addCreative(BuildCreativeModeTabContentsEvent event)
- {
- if (event.getTabKey() == CreativeModeTabs.INGREDIENTS)
- {
+ private void addCreative(BuildCreativeModeTabContentsEvent event) {
+ if (event.getTabKey() == CreativeModeTabs.INGREDIENTS) {
event.accept(FLUID_LOGGABLE_BLOCK_ITEM);
event.accept(TEST_FLUID_BUCKET);
}
}
- public void loadComplete(FMLLoadCompleteEvent event)
- {
+ public void loadComplete(FMLLoadCompleteEvent event) {
// some sanity checks
BlockState state = Fluids.WATER.defaultFluidState().createLegacyBlock();
BlockState state2 = Fluids.WATER.getFluidType().getBlockForFluidState(null,null,Fluids.WATER.defaultFluidState());
@@ -159,30 +147,27 @@ public class NewFluidTest {
}
// WARNING: this doesn't allow "any fluid", only the fluid from this test mod!
- private static class FluidloggableBlock extends Block implements SimpleWaterloggedBlock
- {
+ private static class FluidloggableBlock extends Block implements SimpleWaterloggedBlock {
public static final BooleanProperty FLUIDLOGGED = BooleanProperty.create("fluidlogged");
- public FluidloggableBlock(Properties properties)
- {
+ public FluidloggableBlock(Properties properties) {
super(properties);
registerDefaultState(getStateDefinition().any().setValue(FLUIDLOGGED, false));
}
@Override
- protected void createBlockStateDefinition(StateDefinition.Builder builder)
- {
+ protected void createBlockStateDefinition(StateDefinition.Builder builder) {
builder.add(FLUIDLOGGED);
}
@Override
- public boolean canPlaceLiquid(BlockGetter worldIn, BlockPos pos, BlockState state, Fluid fluidIn) {
+ public boolean canPlaceLiquid(@Nullable Player player, BlockGetter worldIn, BlockPos pos, BlockState state, Fluid fluidIn) {
return !state.getValue(FLUIDLOGGED) && fluidIn == test_fluid.get();
}
@Override
public boolean placeLiquid(LevelAccessor worldIn, BlockPos pos, BlockState state, FluidState fluidStateIn) {
- if (canPlaceLiquid(worldIn, pos, state, fluidStateIn.getType())) {
+ if (canPlaceLiquid(null, worldIn, pos, state, fluidStateIn.getType())) {
if (!worldIn.isClientSide()) {
worldIn.setBlock(pos, state.setValue(FLUIDLOGGED, true), 3);
worldIn.scheduleTick(pos, fluidStateIn.getType(), fluidStateIn.getType().getTickDelay(worldIn));
@@ -195,7 +180,7 @@ public class NewFluidTest {
}
@Override
- public ItemStack pickupBlock(LevelAccessor worldIn, BlockPos pos, BlockState state) {
+ public ItemStack pickupBlock(@Nullable Player player, LevelAccessor worldIn, BlockPos pos, BlockState state) {
if (state.getValue(FLUIDLOGGED)) {
worldIn.setBlock(pos, state.setValue(FLUIDLOGGED, false), 3);
return new ItemStack(TEST_FLUID_BUCKET.get());
@@ -208,5 +193,4 @@ public class NewFluidTest {
return state.getValue(FLUIDLOGGED) ? test_fluid.get().defaultFluidState() : Fluids.EMPTY.defaultFluidState();
}
}
-}
-*/
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/test_old/java/net/minecraftforge/debug/gameplay/loot/package-info.java b/src/test_old/java/net/minecraftforge/debug/gameplay/loot/package-info.java
deleted file mode 100644
index 4436a52f7b..0000000000
--- a/src/test_old/java/net/minecraftforge/debug/gameplay/loot/package-info.java
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (c) Forge Development LLC and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-@ParametersAreNonnullByDefault
-@MethodsReturnNonnullByDefault
-package net.minecraftforge.debug.gameplay.loot;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-import net.minecraft.MethodsReturnNonnullByDefault;
diff --git a/src/test_old/resources/META-INF/mods.toml b/src/test_old/resources/META-INF/mods.toml
index 387a30d4b2..cab937fdf0 100644
--- a/src/test_old/resources/META-INF/mods.toml
+++ b/src/test_old/resources/META-INF/mods.toml
@@ -98,14 +98,6 @@ modId="trsr_transformer_test"
[[mods]]
modId="nameplate_render_test"
[[mods]]
-modId="global_loot_test"
-[[dependencies.global_loot_test]]
-modId="forge"
-mandatory=true
-versionRange="[1,)"
-ordering="AFTER"
-side="BOTH"
-[[mods]]
modId="custom_plant_type_test"
[[mods]]
modId="chunk_data_event_save_null_world_test"
@@ -292,8 +284,6 @@ modId="grindstone_event_test"
[[mods]]
modId="data_pack_registries_test"
[[mods]]
-modId="creative_mode_tab_test"
-[[mods]]
modId="render_level_stages_test"
[[mods]]
modId="trade_with_villager_event_test"