WIP port to 1.21

This commit is contained in:
thedarkcolour 2024-06-15 23:21:37 -07:00
parent 2f44a167ed
commit c80b221b46
No known key found for this signature in database
GPG Key ID: 6599A8E0516C8F38
52 changed files with 329 additions and 396 deletions

View File

@ -1,7 +1,7 @@
plugins {
id 'java-library'
id 'idea'
id 'net.neoforged.gradle.userdev' version '7.0.105'
id 'net.neoforged.moddev' version '0.1.74'
}
version = '2.10'
@ -10,32 +10,38 @@ base {
archivesName = 'exdeorum'
}
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
neoForge {
version = neo_version
runs {
configureEach {
systemProperty 'forge.logging.console.level', 'debug'
jvmArgument '-XX:+AllowEnhancedClassRedefinition'
modSource project.sourceSets.main
}
client {}
server {
programArgument '--nogui'
}
data {
// instead of using --all, skip file check validation
programArguments.addAll('--server', '--client', '--dev', '--reports')
programArguments.addAll ('--mod', 'exdeorum', '--output', file('src/generated/resources/').absolutePath, '--existing', file('src/main/resources/').absolutePath)
}
}
}
java.toolchain.languageVersion = JavaLanguageVersion.of(21)
java.withSourcesJar()
minecraft.accessTransformers.file(rootProject.file('src/main/resources/META-INF/accesstransformer.cfg'))
runs {
configureEach {
systemProperty 'forge.logging.console.level', 'debug'
jvmArgument '-XX:+AllowEnhancedClassRedefinition'
modSource project.sourceSets.main
}
client {}
server {
programArgument '--nogui'
}
data {
// instead of using --all, skip file check validation
programArguments.addAll('--server', '--client', '--dev', '--reports')
programArguments.addAll ('--mod', 'exdeorum', '--output', file('src/generated/resources/').absolutePath, '--existing', file('src/main/resources/').absolutePath)
}
}
// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' }
@ -45,6 +51,8 @@ sourceSets {
main {
java {
exclude 'thedarkcolour/exdeorum/compat/kubejs/'
exclude 'thedarkcolour/exdeorum/compat/jei/'
exclude 'thedarkcolour/exdeorum/compat/top/'
}
}
}
@ -101,23 +109,23 @@ repositories {
}
dependencies {
implementation("net.neoforged:neoforge:${neo_version}")
implementation("net.neoforged:neoforge:${}")
// TOP OPTIONAL
compileOnly("mcjty.theoneprobe:theoneprobe:${mc_version}_neo-${top_version}") {
transitive = false
}
//compileOnly("mcjty.theoneprobe:theoneprobe:${mc_version}_neo-${top_version}") {
// transitive = false
//}
// JADE OPTIONAL
implementation("curse.maven:jade-324717:5109393")
compileOnly("curse.maven:jade-324717:5109393")
// JEI OPTIONAL
compileOnly("mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}")
runtimeOnly("mezz.jei:jei-${mc_version}-neoforge:${jei_version}")
//compileOnly("mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}")
//runtimeOnly("mezz.jei:jei-${mc_version}-neoforge:${jei_version}")
// REI OPTIONAL todo add
compileOnly("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}")
compileOnly("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}")
// EMI OPTIONAL
compileOnly("dev.emi:emi-neoforge:${emi_version}:api")
runtimeOnly("dev.emi:emi-neoforge:${emi_version}")
compileOnly("dev.emi:emi-neoforge:${emi_version}")
//implementation("curse.maven:reipc-521393:4837449")
// KubeJS OPTIONAL todo add when KubeJS updates
//implementation("dev.architectury:architectury-neoforge:${architectury_version}")
@ -125,7 +133,7 @@ dependencies {
//implementation("dev.latvian.mods:kubejs-neoforge:${kubejs_version}")
// ModKit DEV ONLY
implementation('com.github.thedarkcolour:Modkit:e9334176e0')
implementation('com.github.thedarkcolour:Modkit:e7c1881681')
// Oculus + Embeddium OPTIONAL
compileOnly('maven.modrinth:oculus:1.20.1-1.6.9')

View File

@ -1,68 +1,6 @@
## Ex Deorum 2.10
- Fix issue with Inventory Tweaks item restocking for sieves
- Fix sieving not using more than 64 sieves at a time when high sieve ranges were enabled
- Fix desync bug with barrels that sometimes happens when emptying/filling with a bucket
- Fix overriding Superflat world type
- Fix lag spike when inserting compost into the Barrel for the first time
- Fix June barrel config
- Fluids in barrels and crucibles now affect mobs standing inside them
- Add `exdeorum:ore_chunks` tag for use in Tag Filters from item transport mods
- Add distinct sound events for Ex Deorum sounds so they can be easily detected by Sound Muffler mods. Here are the sound IDs:
- `exdeorum:barrel_add_compost`: Played when compost is added to the barrel
- `exdeorum:barrel_compost`: Played when the barrel finished composting dirt
- `exdeorum:barrel_mixing`: Played when a block is mixed in the barrel (ex. clay)
- `exdeorum:barrel_fluid_transform`: Played when a fluid finishes transforming in a barrel (ex. witch water)
- `exdeorum:silk_worm_drop`: Played when a silk worm is dropped from leaves harvested by a crook
- `exdeorum:silk_worm_infest`: Played when a silk worm is used on a leaves block
- `exdeorum:silk_worm_eat`: Played when a player eats a cooked silk worm
- `exdeorum:grass_seeds_place`: Played when grass seeds or nylium spores are used on grass or netherrack
- `exdeorum:sculk_core_activate`: Played when a sculk core is used on a sculk shrieker to spawn Wardens
- `exdeorum:watering_can_use`: Played when a watering can is watering something
- `exdeorum:watering_can_stop`: Played when a player stops using the watering can
- Fixed fluid mixing sounds playing at the same volume regardless of distance from the barrel
- Add note to Random Armor Trim indicating it does not drop Netherite Upgrade template
- Changed default value of server config `simultaneous_compressed_sieve_usage` to true so compressed sieves aren't terrible anymore
## Ex Deorum 2.9
- Fix overriding default world type in Create World screen when common config option set_void_world_as_default is false.
- Removed set_void_world_as_default option from client config, you must now only use the option from the common config.
- Fixed bug where barrels filled by rain would not trigger a transformation recipe (e.g. Witch Water conversion)
- Added clientside config option to disable rainbow compost in barrels during June
- Fixed barrel fluid transformation recipes ignoring the result fluid and only crafting witch water
- Fixed bug where barrels would not trigger a transformation recipe while it is raining (ex. Witch Water conversion)
- Add config options to prevent barrels and crucibles from collecting rainwater
## Ex Deorum 2.8
- Fixed bug where compressed sieves would not drop their sieves upon being broken.
- Fix typo in JEI integration where both sieve categories were "Compressed Sieve".
- Add integration for SkyBlock Builder. Now, if that mod is installed, SkyBlock builder's preset is chosen by default instead of Ex Deorum's. This goes for the server.properties file too.
- Added config option for using compressed sieves simultaneously.
- Added Immersive Engineering integration for Ex Deorum's ore chunks.
## Ex Deorum 2.7
- Fixed End Portal not spawning and End Cities not generating
- Fixed an issue with void worlds not generating bastion remnants, nether fortresses, or obsidian pillars in the End
## Ex Deorum 2.6
- Fixed crash on server load
## Ex Deorum 2.5
- Fixed compatibility with EMI
- Add compressed hammers, sieves, and blocks from Ex Deorum 1.30
## Ex Deorum 2.4
- Added compatibility with EMI (only works when also using JEI)
## Ex Deorum 2.3
- Fixed infested leaves not dropping string with a Crook
## Ex Deorum 2.2
- Fixed hammers and crooks not working
## Ex Deorum 2.1
- Add a config option to disable the automated_sieve nerf (now you can enable machines to use multiple sieves simultaneously)
## Ex Deorum 2.0
- Ported to NeoForge 1.20.4
- Has same features as Ex Deorum 1.28
- Fixed light levels for barrel and crucible
## Ex Deorum 3.0
- Update to NeoForge 1.21
- The One Probe (TOP) compat is unimplemented
- JEI compat is unimplemented
- REI compat is unimplemented
- KubeJS compat is unimplemented

View File

@ -3,10 +3,10 @@
org.gradle.jvmargs=-Xmx3G
org.gradle.parallel=true
mc_version=1.20.4
neo_version=20.4.198
neo_version_range=[20.4,)
loader_version_range=[2,)
mc_version=1.21
neo_version=21.0.0-beta
neo_version_range=[21,)
loader_version_range=[3,)
jei_version=17.3.0.49
rei_version=14.0.688

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@ -18,10 +18,10 @@
package thedarkcolour.exdeorum;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModList;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.ModConfig;
import net.neoforged.fml.loading.FMLEnvironment;
@ -64,9 +64,10 @@ public class ExDeorum {
ClientHandler.register(modBus);
}
// Config init
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, EConfig.SERVER_SPEC);
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, EConfig.COMMON_SPEC);
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, EConfig.CLIENT_SPEC);
var container = ModList.get().getModContainerById(ID).get();
container.registerConfig(ModConfig.Type.SERVER, EConfig.SERVER_SPEC);
container.registerConfig(ModConfig.Type.COMMON, EConfig.COMMON_SPEC);
container.registerConfig(ModConfig.Type.CLIENT, EConfig.CLIENT_SPEC);
}
private static void createRegistries(IEventBus modBus) {
@ -87,4 +88,8 @@ public class ExDeorum {
DefaultMaterials.registerMaterials();
ECompressedBlocks.register();
}
public static ResourceLocation loc(String menuProperty) {
return ResourceLocation.fromNamespaceAndPath(ID, menuProperty);
}
}

View File

@ -21,7 +21,7 @@ package thedarkcolour.exdeorum.blockentity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
@ -119,7 +119,7 @@ public abstract class AbstractCrucibleBlockEntity extends ETankBlockEntity {
}
@Override
public void writeVisualData(FriendlyByteBuf buffer) {
public void writeVisualData(RegistryFriendlyByteBuf buffer) {
buffer.writeId(BuiltInRegistries.FLUID, this.tank.getFluid().getFluid());
buffer.writeVarInt(this.tank.getFluidAmount());
buffer.writeId(BuiltInRegistries.BLOCK, this.lastMelted != null ? this.lastMelted : Blocks.AIR);
@ -127,7 +127,7 @@ public abstract class AbstractCrucibleBlockEntity extends ETankBlockEntity {
}
@Override
public void readVisualData(FriendlyByteBuf buffer) {
public void readVisualData(RegistryFriendlyByteBuf buffer) {
Fluid fluid = buffer.readById(BuiltInRegistries.FLUID);
if (fluid == null) {
this.tank.setFluid(FluidStack.EMPTY);

View File

@ -20,7 +20,7 @@ package thedarkcolour.exdeorum.blockentity;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.stats.Stats;
import net.minecraft.util.RandomSource;
@ -92,12 +92,12 @@ public abstract class AbstractSieveBlockEntity extends EBlockEntity implements S
}
@Override
public void writeVisualData(FriendlyByteBuf buffer) {
public void writeVisualData(RegistryFriendlyByteBuf buffer) {
this.logic.writeVisualData(buffer);
}
@Override
public void readVisualData(FriendlyByteBuf buffer) {
public void readVisualData(RegistryFriendlyByteBuf buffer) {
this.logic.readVisualData(buffer);
}

View File

@ -19,9 +19,11 @@
package thedarkcolour.exdeorum.blockentity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.FluidTags;
@ -30,10 +32,9 @@ import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BowlFoodItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.alchemy.PotionContents;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
@ -66,6 +67,8 @@ import thedarkcolour.exdeorum.recipe.barrel.FluidTransformationRecipe;
import thedarkcolour.exdeorum.registry.EBlockEntities;
import thedarkcolour.exdeorum.registry.ESounds;
import java.util.Objects;
public class BarrelBlockEntity extends ETankBlockEntity {
private static final int MOSS_SPREAD_RANGE = 2;
private static final int MAX_CAPACITY = 1000;
@ -91,11 +94,11 @@ public class BarrelBlockEntity extends ETankBlockEntity {
}
@Override
public void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
public void saveAdditional(CompoundTag nbt, HolderLookup.Provider lookup) {
super.saveAdditional(nbt, lookup);
nbt.put("item", this.item.serializeNBT());
nbt.put("tank", this.tank.writeToNBT(new CompoundTag()));
nbt.put("item", this.item.serializeNBT(lookup));
nbt.put("tank", this.tank.writeToNBT(lookup, new CompoundTag()));
nbt.putShort("compost", this.compost);
nbt.putFloat("progress", this.progress);
nbt.putShort("r", this.r);
@ -104,11 +107,11 @@ public class BarrelBlockEntity extends ETankBlockEntity {
}
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
public void loadAdditional(CompoundTag nbt, HolderLookup.Provider lookup) {
super.loadAdditional(nbt, lookup);
this.item.deserializeNBT(nbt.getCompound("item"));
this.tank.readFromNBT(nbt.getCompound("tank"));
this.item.deserializeNBT(lookup, nbt.getCompound("item"));
this.tank.readFromNBT(lookup, nbt.getCompound("tank"));
this.compost = nbt.getShort("compost");
this.progress = nbt.getFloat("progress");
this.r = nbt.getShort("r");
@ -119,9 +122,9 @@ public class BarrelBlockEntity extends ETankBlockEntity {
}
@Override
public void writeVisualData(FriendlyByteBuf buffer) {
buffer.writeItem(this.item.getStackInSlot(0));
buffer.writeFluidStack(this.tank.getFluid());
public void writeVisualData(RegistryFriendlyByteBuf buffer) {
ItemStack.STREAM_CODEC.encode(buffer, this.item.getStackInSlot(0));
FluidStack.STREAM_CODEC.encode(buffer, this.tank.getFluid());
buffer.writeShort(this.compost);
buffer.writeFloat(this.progress);
buffer.writeShort(this.r);
@ -130,9 +133,9 @@ public class BarrelBlockEntity extends ETankBlockEntity {
}
@Override
public void readVisualData(FriendlyByteBuf buffer) {
this.item.setStackInSlot(0, buffer.readItem());
this.tank.setFluid(buffer.readFluidStack());
public void readVisualData(RegistryFriendlyByteBuf buffer) {
this.item.setStackInSlot(0, ItemStack.STREAM_CODEC.decode(buffer));
this.tank.setFluid(FluidStack.STREAM_CODEC.decode(buffer));
this.compost = buffer.readShort();
this.progress = buffer.readFloat();
this.r = buffer.readShort();
@ -239,7 +242,7 @@ public class BarrelBlockEntity extends ETankBlockEntity {
if (EConfig.SERVER.allowWaterBottleTransfer.get()) {
var fluid = new FluidStack(Fluids.WATER, 250);
if (playerItem.getItem() == Items.POTION && PotionUtils.getPotion(playerItem) == Potions.WATER) {
if (playerItem.getItem() == Items.POTION && playerItem.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).is(Potions.WATER)) {
if (this.tank.fill(fluid, IFluidHandler.FluidAction.SIMULATE) > 0) {
if (!player.getAbilities().instabuild) {
player.setItemInHand(hand, new ItemStack(Items.GLASS_BOTTLE));
@ -304,7 +307,8 @@ public class BarrelBlockEntity extends ETankBlockEntity {
if (!player.getAbilities().instabuild) {
playerItem.shrink(1);
}
var bottle = PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER);
var bottle = new ItemStack(Items.POTION);
bottle.set(DataComponents.POTION_CONTENTS, new PotionContents(Potions.WATER));
if (!player.addItem(bottle)) {
player.drop(bottle, false);
}
@ -592,7 +596,8 @@ public class BarrelBlockEntity extends ETankBlockEntity {
}
private static ItemStack getRemainderItem(ItemStack stack) {
return (stack.getItem() instanceof BowlFoodItem || stack.getItem() == Items.SUSPICIOUS_STEW) ? new ItemStack(Items.BOWL) : stack.getCraftingRemainingItem();
var foodRemainder = Objects.requireNonNull(stack.get(DataComponents.FOOD)).usingConvertsTo();
return foodRemainder.map(ItemStack::copy).orElseGet(stack::getCraftingRemainingItem);
}
@Override

View File

@ -21,7 +21,7 @@ package thedarkcolour.exdeorum.blockentity;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.Connection;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
@ -31,7 +31,6 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import thedarkcolour.exdeorum.network.VisualUpdateTracker;
import thedarkcolour.exdeorum.registry.EBlockEntities;
import javax.annotation.Nullable;
@ -70,11 +69,11 @@ public abstract class EBlockEntity extends BlockEntity {
return InteractionResult.PASS;
}
public void writeVisualData(FriendlyByteBuf buffer) {
public void writeVisualData(RegistryFriendlyByteBuf buffer) {
}
public void readVisualData(FriendlyByteBuf buffer) {
public void readVisualData(RegistryFriendlyByteBuf buffer) {
}

View File

@ -23,7 +23,7 @@ import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
@ -61,12 +61,12 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
}
@Override
public void writeVisualData(FriendlyByteBuf buffer) {
public void writeVisualData(RegistryFriendlyByteBuf buffer) {
buffer.writeShort(this.progress);
}
@Override
public void readVisualData(FriendlyByteBuf buffer) {
public void readVisualData(RegistryFriendlyByteBuf buffer) {
buffer.readShort();
}

View File

@ -20,7 +20,7 @@ package thedarkcolour.exdeorum.blockentity;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
@ -93,12 +93,12 @@ public class MechanicalSieveBlockEntity extends AbstractMachineBlockEntity<Mecha
}
@Override
public void writeVisualData(FriendlyByteBuf buffer) {
public void writeVisualData(RegistryFriendlyByteBuf buffer) {
this.logic.writeVisualData(buffer);
}
@Override
public void readVisualData(FriendlyByteBuf buffer) {
public void readVisualData(RegistryFriendlyByteBuf buffer) {
this.logic.readVisualData(buffer);
}

View File

@ -18,6 +18,7 @@
package thedarkcolour.exdeorum.blockentity.helper;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
@ -40,7 +41,7 @@ public class FluidHelper extends FluidTank {
if (this.fluid.isEmpty()) {
return Math.min(this.capacity, resource.getAmount());
}
if (!this.fluid.isFluidEqual(resource)) {
if (!FluidStack.isSameFluidSameComponents(this.fluid, resource)) {
return 0;
}
return Math.min(this.capacity - this.fluid.getAmount(), resource.getAmount());
@ -48,12 +49,11 @@ public class FluidHelper extends FluidTank {
if (this.fluid.isEmpty()) {
// fix forge's implementation to avoid dupes
int amount = Math.min(this.capacity, resource.getAmount());
this.fluid = new FluidStack(resource, Math.min(this.capacity, amount));
this.fluid = new FluidStack(resource.getFluid(), Math.min(this.capacity, amount));
onContentsChanged();
return amount;
}
if (!this.fluid.isFluidEqual(resource))
{
if (!FluidStack.isSameFluidSameComponents(this.fluid, resource)) {
return 0;
}
int filled = this.capacity - this.fluid.getAmount();
@ -71,8 +71,8 @@ public class FluidHelper extends FluidTank {
}
@Override
public FluidTank readFromNBT(CompoundTag nbt) {
super.readFromNBT(nbt);
public FluidTank readFromNBT(HolderLookup.Provider provider, CompoundTag nbt) {
super.readFromNBT(provider, nbt);
if (!this.fluid.isEmpty()) {
this.fluid.setAmount(Math.min(this.capacity, this.fluid.getAmount()));
}

View File

@ -20,11 +20,19 @@ package thedarkcolour.exdeorum.compat;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.world.Container;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeInput;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.enchantment.ItemEnchantments;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level;
import net.neoforged.fml.ModList;
import thedarkcolour.exdeorum.material.DefaultMaterials;
import thedarkcolour.exdeorum.material.MaterialRegistry;
@ -33,6 +41,7 @@ import thedarkcolour.exdeorum.registry.EItems;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
public class CompatUtil {
@ -72,12 +81,19 @@ public class CompatUtil {
return materials;
}
public static <C extends Container, R extends Recipe<C>, T> List<T> collectAllRecipes(RecipeType<R> recipeType, Function<R, T> mapper) {
var byType = Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().byType(recipeType).values();
public static <C extends RecipeInput, R extends Recipe<C>, T> List<T> collectAllRecipes(RecipeType<R> recipeType, Function<R, T> mapper) {
var byType = Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().byType(recipeType);
List<T> recipes = new ObjectArrayList<>(byType.size());
for (RecipeHolder<R> value : byType) {
recipes.add(mapper.apply(value.value()));
}
return recipes;
}
public static void addEnchantmentsTooltip(ItemStack mesh, Level level, Consumer<Component> aggregator) {
var enchantments = mesh.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
if (!enchantments.isEmpty()) {
enchantments.addToTooltip(Item.TooltipContext.of(level), aggregator, TooltipFlag.NORMAL);
}
}
}

View File

@ -30,10 +30,10 @@ import thedarkcolour.exdeorum.block.SieveBlock;
@WailaPlugin
public class ExDeorumJadePlugin implements IWailaPlugin {
static final ResourceLocation INFESTED_LEAVES = new ResourceLocation(ExDeorum.ID, "infested_leaves");
static final ResourceLocation BARREL = new ResourceLocation(ExDeorum.ID, "barrel");
static final ResourceLocation SIEVE = new ResourceLocation(ExDeorum.ID, "sieve");
static final ResourceLocation CRUCIBLE = new ResourceLocation(ExDeorum.ID, "crucible");
static final ResourceLocation INFESTED_LEAVES = ExDeorum.loc("infested_leaves");
static final ResourceLocation BARREL = ExDeorum.loc("barrel");
static final ResourceLocation SIEVE = ExDeorum.loc("sieve");
static final ResourceLocation CRUCIBLE = ExDeorum.loc("crucible");
@Override
public void registerClient(IWailaClientRegistration registration) {

View File

@ -18,10 +18,12 @@
package thedarkcolour.exdeorum.compat.jade;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.enchantment.ItemEnchantments;
import net.minecraft.world.phys.Vec2;
import snownee.jade.api.BlockAccessor;
import snownee.jade.api.IBlockComponentProvider;
@ -29,6 +31,7 @@ import snownee.jade.api.ITooltip;
import snownee.jade.api.config.IPluginConfig;
import snownee.jade.api.ui.IElementHelper;
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
import thedarkcolour.exdeorum.compat.CompatUtil;
enum SieveComponentProvider implements IBlockComponentProvider {
INSTANCE;
@ -46,14 +49,8 @@ enum SieveComponentProvider implements IBlockComponentProvider {
var element = IElementHelper.get().item(mesh);
tooltip.add(element);
tooltip.append(IElementHelper.get().text(Component.translatable(mesh.getDescriptionId())).translate(new Vec2(2f, 6f)));
if (mesh.isEnchanted()) {
var list = new ObjectArrayList<Component>();
ItemStack.appendEnchantmentNames(list, mesh.getEnchantmentTags());
for (var component : list) {
tooltip.add(component);
}
}
CompatUtil.addEnchantmentsTooltip(mesh, accessor.getLevel(), tooltip::add);
}
}
}

View File

@ -166,7 +166,7 @@ public class ExDeorumJeiPlugin implements IModPlugin {
@Override
public void registerRecipes(IRecipeRegistration registration) {
registration.addItemStackInfo(List.of(new ItemStack(EItems.INFESTED_LEAVES.get()), new ItemStack(EItems.SILK_WORM.get())), Component.translatable(TranslationKeys.SILK_WORM_JEI_INFO));
registration.addItemStackInfo(List.of(new ItemStack(EItems.INFESTED_LEAVES.get()), new ItemStack(EItems.SILKWORM.get())), Component.translatable(TranslationKeys.SILK_WORM_JEI_INFO));
registration.addItemStackInfo(CompatUtil.getAvailableSieves(true, false).stream().map(ItemStack::new).toList(), Component.translatable(TranslationKeys.SIEVE_JEI_INFO));
registration.addItemStackInfo(List.of(new ItemStack(EItems.STRING_MESH.get()), new ItemStack(EItems.STRING_MESH.get()), new ItemStack(EItems.FLINT_MESH.get()), new ItemStack(EItems.IRON_MESH.get()), new ItemStack(EItems.GOLDEN_MESH.get()), new ItemStack(EItems.DIAMOND_MESH.get()), new ItemStack(EItems.NETHERITE_MESH.get())), Component.translatable(TranslationKeys.SIEVE_MESH_JEI_INFO));
registration.addItemStackInfo(List.of(WateringCanItem.getFull(EItems.WOODEN_WATERING_CAN), WateringCanItem.getFull(EItems.STONE_WATERING_CAN), WateringCanItem.getFull(EItems.IRON_WATERING_CAN), WateringCanItem.getFull(EItems.GOLDEN_WATERING_CAN), WateringCanItem.getFull(EItems.DIAMOND_WATERING_CAN), WateringCanItem.getFull(EItems.NETHERITE_WATERING_CAN)), Component.translatable(TranslationKeys.WATERING_CAN_JEI_INFO));

View File

@ -48,7 +48,7 @@ class Advancements extends AdvancementProvider {
}
private static ResourceLocation modLoc(String path) {
return new ResourceLocation(ExDeorum.ID, path);
return ResourceLocation.fromNamespaceAndPath(ExDeorum.ID, path);
}
public static class CoreAchievements implements AdvancementGenerator {
@ -99,7 +99,7 @@ class Advancements extends AdvancementProvider {
var silkWorm = advancement()
.parent(crook)
.display(
EItems.SILK_WORM.get(),
EItems.SILKWORM.get(),
Component.translatable(TranslationKeys.SILK_WORM_ADVANCEMENT_TITLE),
Component.translatable(TranslationKeys.SILK_WORM_ADVANCEMENT_DESCRIPTION),
null,
@ -108,7 +108,7 @@ class Advancements extends AdvancementProvider {
true,
false
)
.addCriterion("has_silk_worm", hasItems(item().of(EItems.SILK_WORM.get()).build()))
.addCriterion("has_silk_worm", hasItems(item().of(EItems.SILKWORM.get()).build()))
.save(saver, modLoc("core/silk_worm"), helper);
var stringMesh = advancement()
.parent(silkWorm)

View File

@ -18,6 +18,7 @@
package thedarkcolour.exdeorum.data;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.loot.BlockLootSubProvider;
import net.minecraft.world.flag.FeatureFlags;
@ -39,8 +40,8 @@ import java.util.Set;
class BlockLoot extends BlockLootSubProvider {
private final List<Block> added = new ArrayList<>();
protected BlockLoot() {
super(Set.of(), FeatureFlags.DEFAULT_FLAGS);
protected BlockLoot(HolderLookup.Provider provider) {
super(Set.of(), FeatureFlags.DEFAULT_FLAGS, provider);
}
@Override

View File

@ -265,7 +265,7 @@ class BlockModels {
private static ResourceLocation texture(Block block, String prefix, String suffix) {
var key = Objects.requireNonNull(BuiltInRegistries.BLOCK.getKey(block));
return new ResourceLocation(key.getNamespace(), "block/" + prefix + key.getPath() + suffix);
return ResourceLocation.fromNamespaceAndPath(key.getNamespace(), "block/" + prefix + key.getPath() + suffix);
}
public static void barrel(MKBlockModelProvider models, Block block, Block appearance) {

View File

@ -45,7 +45,7 @@ public class Data {
dataHelper.createTags(Registries.STRUCTURE_SET, ModTags::createStructureSetTags);
dataHelper.createTags(Registries.WORLD_PRESET, ModTags::createWorldPresetTags);
gen.addProvider(true, new LootTables(output));
gen.addProvider(true, new LootTables(output, lookup));
gen.addProvider(true, new Advancements(output, lookup, helper));
gen.addProvider(true, new Sounds(output, helper));
}

View File

@ -18,15 +18,17 @@
package thedarkcolour.exdeorum.data;
import net.minecraft.core.HolderLookup;
import net.minecraft.data.PackOutput;
import net.minecraft.data.loot.LootTableProvider;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
class LootTables extends LootTableProvider {
public LootTables(PackOutput output) {
super(output, Set.of(), List.of(new SubProviderEntry(BlockLoot::new, LootContextParamSets.BLOCK)));
public LootTables(PackOutput output, CompletableFuture<HolderLookup.Provider> provider) {
super(output, Set.of(), List.of(new SubProviderEntry(BlockLoot::new, LootContextParamSets.BLOCK)), provider);
}
}

View File

@ -221,7 +221,7 @@ public class ModCompatData {
PAMS_CROPS = new ResourceLocation[names.length];
for (int i = 0, namesLength = names.length; i < namesLength; i++) {
PAMS_CROPS[i] = new ResourceLocation(ModIds.PAMS_HARVESTCRAFT_CROPS, names[i]);
PAMS_CROPS[i] = ResourceLocation.fromNamespaceAndPath(ModIds.PAMS_HARVESTCRAFT_CROPS, names[i]);
}
}

View File

@ -98,7 +98,7 @@ class ModTags {
tags.tag(EItemTags.BARRELS).addTags(EItemTags.WOODEN_BARRELS, EItemTags.STONE_BARRELS);
// Cyclic adds ONE compressed block :)
tags.tag(ECompressedBlocks.COMPRESSED_COBBLESTONE.getTag()).addOptional(new ResourceLocation(ModIds.CYCLIC, "compressed_cobblestone"));
tags.tag(ECompressedBlocks.COMPRESSED_COBBLESTONE.getTag()).addOptional(ResourceLocation.fromNamespaceAndPath(ModIds.CYCLIC, "compressed_cobblestone"));
for (var variant : ECompressedBlocks.ALL_VARIANTS) {
var builder = tags.tag(variant.getTag()).add(variant.getItem());
@ -120,7 +120,7 @@ class ModTags {
}
public static void createWorldPresetTags(MKTagsProvider<WorldPreset> tags) {
tags.tag(net.minecraft.tags.WorldPresetTags.NORMAL).add(ResourceKey.create(Registries.WORLD_PRESET, new ResourceLocation(ExDeorum.ID, "void_world")));
tags.tag(net.minecraft.tags.WorldPresetTags.NORMAL).add(ResourceKey.create(Registries.WORLD_PRESET, ResourceLocation.fromNamespaceAndPath(ExDeorum.ID, "void_world")));
}
public static void createFluidTags(MKTagsProvider<Fluid> tags) {

View File

@ -507,7 +507,7 @@ public class Recipes {
recipes.smelting(ingredient(EItems.UNFIRED_PORCELAIN_CRUCIBLE), DefaultMaterials.PORCELAIN_CRUCIBLE.getItem(), 0.1f);
recipes.smelting(ingredient(EItems.UNFIRED_PORCELAIN_BUCKET), EItems.PORCELAIN_BUCKET.get(), 0.1f);
recipes.foodCooking(EItems.SILK_WORM.get(), EItems.COOKED_SILK_WORM.get(), 0.1f);
recipes.foodCooking(EItems.SILKWORM.get(), EItems.COOKED_SILKWORM.get(), 0.1f);
}
private static void crucibleRecipes(RecipeOutput writer) {
lavaCrucible(writer, "cobblestone", ingredient(Tags.Items.COBBLESTONE), 250);
@ -611,10 +611,10 @@ public class Recipes {
}
private static void crookRecipes(RecipeOutput writer) {
crookRecipe(writer, "silkworm", BlockPredicate.blockTag(BlockTags.LEAVES), EItems.SILK_WORM.get(), 0.01f);
crookRecipe(writer, "silkworm", BlockPredicate.blockTag(BlockTags.LEAVES), EItems.SILKWORM.get(), 0.01f);
@SuppressWarnings("OptionalGetWithoutIsPresent")
var fullyInfestedLeaves = BlockPredicate.blockState(EBlocks.INFESTED_LEAVES.get(), StatePropertiesPredicate.Builder.properties().hasProperty(InfestedLeavesBlock.FULLY_INFESTED, true).build().get());
crookRecipe(writer, "silkworm_bonus", fullyInfestedLeaves, EItems.SILK_WORM.get(), 0.01f);
crookRecipe(writer, "silkworm_bonus", fullyInfestedLeaves, EItems.SILKWORM.get(), 0.01f);
crookRecipe(writer, "string_roll_1", fullyInfestedLeaves, Items.STRING, 0.4f);
crookRecipe(writer, "string_roll_2", fullyInfestedLeaves, Items.STRING, 0.1f);
}
@ -704,7 +704,7 @@ public class Recipes {
barrelCompost(writer, "egg", ingredient(Items.EGG), 100);
// foods
barrelCompost(writer, "melon_slice", ingredient(Items.MELON_SLICE), 40);
barrelCompost(writer, "silk_worms", ingredient(EItems.SILK_WORM.get(), EItems.COOKED_SILK_WORM.get()), 40);
barrelCompost(writer, "silk_worms", ingredient(EItems.SILKWORM.get(), EItems.COOKED_SILKWORM.get()), 40);
barrelCompost(writer, "apple", ingredient(Items.APPLE), 100);
barrelCompost(writer, "cookie", ingredient(Items.COOKIE), 100);
barrelCompost(writer, "pumpkin_pie", ingredient(Items.PUMPKIN_PIE), 150);

View File

@ -50,18 +50,16 @@ import net.neoforged.neoforge.client.event.ClientChatEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.common.NeoForgeMod;
import net.neoforged.neoforge.event.AddReloadListenerEvent;
import net.neoforged.neoforge.event.TickEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.neoforge.event.level.LevelEvent;
import net.neoforged.neoforge.event.server.ServerStoppingEvent;
import net.neoforged.neoforge.event.tick.ServerTickEvent;
import net.neoforged.neoforge.fluids.FluidInteractionRegistry;
import net.neoforged.neoforge.fluids.capability.wrappers.FluidBucketWrapper;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import thedarkcolour.exdeorum.ExDeorum;
import thedarkcolour.exdeorum.blockentity.helper.ItemHelper;
import thedarkcolour.exdeorum.client.CompostColors;
import thedarkcolour.exdeorum.compat.ModIds;
import thedarkcolour.exdeorum.compat.top.ExDeorumTopCompat;
import thedarkcolour.exdeorum.config.EConfig;
import thedarkcolour.exdeorum.item.PorcelainBucket;
import thedarkcolour.exdeorum.item.WateringCanItem;
@ -185,9 +183,10 @@ public final class EventHandler {
});
}
private static void registerPayloadHandler(RegisterPayloadHandlerEvent event) {
private static void registerPayloadHandler(RegisterPayloadHandlersEvent event) {
NetworkHandler.register(event.registrar(ExDeorum.ID));
}
private static void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
if (event.getEntity() instanceof ServerPlayer player) {
var generator = player.serverLevel().getChunkSource().getGenerator();
@ -195,7 +194,7 @@ public final class EventHandler {
// tries to account for other SkyBlock generator mods like SkyBlockBuilder
if (generator instanceof VoidChunkGenerator || generator.getClass().getName().toLowerCase(Locale.ROOT).contains("skyblock")) {
NetworkHandler.sendVoidWorld(player);
var advancement = player.server.getAdvancements().get(new ResourceLocation(ExDeorum.ID, "core/root"));
var advancement = player.server.getAdvancements().get(ResourceLocation.fromNamespaceAndPath(ExDeorum.ID, "core/root"));
if (advancement != null) {
if (!player.getAdvancements().getOrStartProgress(advancement).isDone()) {
@ -221,7 +220,8 @@ public final class EventHandler {
// Send messages to other mods
private static void interModEnqueue(InterModEnqueueEvent event) {
if (ModList.get().isLoaded(ModIds.THE_ONE_PROBE)) {
InterModComms.sendTo(ModIds.THE_ONE_PROBE, "getTheOneProbe", ExDeorumTopCompat::new);
// todo The One Probe
//InterModComms.sendTo(ModIds.THE_ONE_PROBE, "getTheOneProbe", ExDeorumTopCompat::new);
}
if (ModList.get().isLoaded(ModIds.INVENTORY_SORTER)) {
InterModComms.sendTo(ModIds.INVENTORY_SORTER, "slotblacklist", ItemHelper.Slot.class::getName);
@ -237,10 +237,8 @@ public final class EventHandler {
});
}
private static void serverTick(TickEvent.ServerTickEvent event) {
if (event.phase == TickEvent.Phase.END) {
VisualUpdateTracker.syncVisualUpdates();
}
private static void serverTick(ServerTickEvent.Post event) {
VisualUpdateTracker.syncVisualUpdates(event.getServer());
}
private static void registerCapabilities(RegisterCapabilitiesEvent event) {
@ -265,7 +263,6 @@ public final class EventHandler {
EItems.PORCELAIN_LAVA_BUCKET,
EItems.PORCELAIN_MILK_BUCKET,
EItems.PORCELAIN_WITCH_WATER_BUCKET);
event.registerItem(Capabilities.FluidHandler.ITEM, (stack, ctx) -> new FluidBucketWrapper(stack), EItems.WITCH_WATER_BUCKET);
event.registerItem(Capabilities.FluidHandler.ITEM, (stack, ctx) -> new WateringCanItem.FluidHandler(stack),
EItems.WOODEN_WATERING_CAN,
EItems.STONE_WATERING_CAN,

View File

@ -36,9 +36,9 @@ import thedarkcolour.exdeorum.registry.EItems;
import java.util.function.Consumer;
public class WitchWaterFluid extends FluidType {
private static final ResourceLocation STILL_TEXTURE = new ResourceLocation(ExDeorum.ID, "block/witch_water_still");
private static final ResourceLocation FLOWING_TEXTURE = new ResourceLocation(ExDeorum.ID, "block/witch_water_flowing");
private static final ResourceLocation OVERLAY_TEXTURE = new ResourceLocation("block/water_overlay");
private static final ResourceLocation STILL_TEXTURE = ExDeorum.loc("block/witch_water_still");
private static final ResourceLocation FLOWING_TEXTURE = ExDeorum.loc("block/witch_water_flowing");
private static final ResourceLocation OVERLAY_TEXTURE = ResourceLocation.withDefaultNamespace("block/water_overlay");
public static BaseFlowingFluid.Properties properties() {
return new BaseFlowingFluid.Properties(EFluids.WITCH_WATER_TYPE, EFluids.WITCH_WATER, EFluids.WITCH_WATER_FLOWING).block(EBlocks.WITCH_WATER).bucket(EItems.WITCH_WATER_BUCKET);

View File

@ -1,3 +1,21 @@
/*
* Ex Deorum
* Copyright (c) 2024 thedarkcolour
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package thedarkcolour.exdeorum.item;
import net.minecraft.world.item.ItemStack;

View File

@ -22,8 +22,8 @@ import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.item.Item;
import thedarkcolour.exdeorum.registry.ESounds;
public class CookedSilkWormItem extends Item {
public CookedSilkWormItem(Properties properties) {
public class CookedSilkwormItem extends Item {
public CookedSilkwormItem(Properties properties) {
super(properties);
}

View File

@ -19,6 +19,7 @@
package thedarkcolour.exdeorum.item;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.ItemTags;
import net.minecraft.world.InteractionHand;
@ -54,17 +55,15 @@ public class CrookItem extends Item {
@Override
public boolean mineBlock(ItemStack stack, Level level, BlockState state, BlockPos pos, LivingEntity living) {
if (!level.isClientSide && state.getDestroySpeed(level, pos) != 0.0F) {
stack.hurtAndBreak(1, living, (p_40992_) -> {
p_40992_.broadcastBreakEvent(EquipmentSlot.MAINHAND);
});
stack.hurtAndBreak(1, living, EquipmentSlot.MAINHAND);
}
return true;
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
return enchantment == Enchantments.BLOCK_FORTUNE || enchantment == Enchantments.UNBREAKING || enchantment == Enchantments.BLOCK_EFFICIENCY;
public boolean canApplyAtEnchantingTable(ItemStack stack, ResourceKey<Enchantment> enchantment) {
return enchantment == Enchantments.FORTUNE || enchantment == Enchantments.UNBREAKING || enchantment == Enchantments.BLOCK_EFFICIENCY;
}
@Override

View File

@ -28,7 +28,6 @@ import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.common.TierSortingRegistry;
import net.neoforged.neoforge.common.util.Lazy;
import org.jetbrains.annotations.Nullable;
import thedarkcolour.exdeorum.recipe.RecipeUtil;

View File

@ -31,6 +31,6 @@ public class NyliumSpreaderItem extends GrassSpreaderItem {
@Override
public boolean canSpread(BlockState state) {
return state.is(Tags.Blocks.NETHERRACK) || state.is(BlockTags.NYLIUM);
return state.is(Tags.Blocks.NETHERRACKS) || state.is(BlockTags.NYLIUM);
}
}

View File

@ -91,8 +91,6 @@ public class PorcelainBucket extends Item {
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand pHand) {
var stack = player.getItemInHand(pHand);
var hitResult = getPlayerPOVHitResult(level, player, this.fluid.get() == Fluids.EMPTY ? ClipContext.Fluid.SOURCE_ONLY : ClipContext.Fluid.NONE);
var ret = EventHooks.onBucketUse(player, level, stack, hitResult);
if (ret != null) return ret;
if (hitResult.getType() == HitResult.Type.MISS) {
return InteractionResultHolder.pass(stack);
} else if (hitResult.getType() != HitResult.Type.BLOCK) {

View File

@ -104,7 +104,7 @@ public abstract class RandomResultItem extends Item {
}
@Override
public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List<Component> tooltip, TooltipFlag pIsAdvanced) {
public void appendHoverText(ItemStack pStack, TooltipContext pLevel, List<Component> tooltip, TooltipFlag pIsAdvanced) {
tooltip.add(Component.translatable(TranslationKeys.RANDOM_TRIM_DOES_NOT_CONTAIN_UPGRADE).withStyle(ChatFormatting.DARK_GRAY));
}
}

View File

@ -30,8 +30,8 @@ import thedarkcolour.exdeorum.blockentity.InfestedLeavesBlockEntity;
import thedarkcolour.exdeorum.registry.EBlocks;
import thedarkcolour.exdeorum.registry.ESounds;
public class SilkWormItem extends Item {
public SilkWormItem(Item.Properties properties) {
public class SilkwormItem extends Item {
public SilkwormItem(Item.Properties properties) {
super(properties);
}

View File

@ -1,28 +0,0 @@
/*
* Ex Deorum
* Copyright (c) 2024 thedarkcolour
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package thedarkcolour.exdeorum.item;
import net.minecraft.world.item.BucketItem;
import thedarkcolour.exdeorum.registry.EFluids;
public class WitchWaterBucketItem extends BucketItem {
public WitchWaterBucketItem(Properties properties) {
super(EFluids.WITCH_WATER, properties);
}
}

View File

@ -1,6 +1,6 @@
package thedarkcolour.exdeorum.loot;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
@ -11,14 +11,14 @@ import thedarkcolour.exdeorum.recipe.RecipeUtil;
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
public class CompressedHammerLootModifier extends HammerLootModifier {
public static final Codec<CompressedHammerLootModifier> CODEC = RecordCodecBuilder.create(inst -> LootModifier.codecStart(inst).apply(inst, CompressedHammerLootModifier::new));
public static final MapCodec<CompressedHammerLootModifier> CODEC = RecordCodecBuilder.mapCodec(inst -> LootModifier.codecStart(inst).apply(inst, CompressedHammerLootModifier::new));
public CompressedHammerLootModifier(LootItemCondition[] conditionsIn) {
super(conditionsIn);
}
@Override
public Codec<? extends IGlobalLootModifier> codec() {
public MapCodec<? extends IGlobalLootModifier> codec() {
return CODEC;
}

View File

@ -19,8 +19,10 @@
package thedarkcolour.exdeorum.loot;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.core.registries.Registries;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
@ -40,7 +42,7 @@ import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
import java.util.List;
public class CrookLootModifier extends LootModifier {
public static final Codec<CrookLootModifier> CODEC = RecordCodecBuilder.create(inst -> LootModifier.codecStart(inst).apply(inst, CrookLootModifier::new));
public static final MapCodec<CrookLootModifier> CODEC = RecordCodecBuilder.mapCodec(inst -> LootModifier.codecStart(inst).apply(inst, CrookLootModifier::new));
protected CrookLootModifier(LootItemCondition[] conditions) {
super(conditions);
@ -54,8 +56,8 @@ public class CrookLootModifier extends LootModifier {
if (state != null && stack != null) {
var rand = context.getRandom();
if (stack.getEnchantmentLevel(Enchantments.SILK_TOUCH) == 0) {
var fortune = stack.getEnchantmentLevel(Enchantments.BLOCK_FORTUNE);
if (stack.getEnchantmentLevel(context.getLevel().holderLookup(Registries.ENCHANTMENT).getOrThrow(Enchantments.SILK_TOUCH)) == 0) {
var fortune = stack.getEnchantmentLevel(context.getLevel().holderLookup(Registries.ENCHANTMENT).getOrThrow(Enchantments.FORTUNE));
var rolls = Math.max(1, Mth.ceil(fortune / 3f));
for (CrookRecipe recipe : RecipeUtil.getCrookRecipes(state)) {
@ -71,6 +73,7 @@ public class CrookLootModifier extends LootModifier {
// this must not be a crook in order to avoid recursively triggering CrookLootModifier from the re roll method
// copying the tag is required so that enchantments like fortune are preserved
var nonCrook = new ItemStack(Items.BARRIER);
// todo data components
nonCrook.setTag(stack.getTag());
for (int i = 0; i < rolls; i++) {
@ -98,7 +101,7 @@ public class CrookLootModifier extends LootModifier {
}
@Override
public Codec<? extends IGlobalLootModifier> codec() {
public MapCodec<? extends IGlobalLootModifier> codec() {
return CODEC;
}
}

View File

@ -19,6 +19,7 @@
package thedarkcolour.exdeorum.loot;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.util.RandomSource;
@ -81,7 +82,7 @@ public class HammerLootModifier extends LootModifier {
}
@Override
public Codec<? extends IGlobalLootModifier> codec() {
public MapCodec<? extends IGlobalLootModifier> codec() {
return CODEC;
}

View File

@ -18,7 +18,7 @@
package thedarkcolour.exdeorum.loot;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntity;
@ -32,7 +32,7 @@ import thedarkcolour.exdeorum.registry.ELootFunctions;
import java.util.List;
public class MachineLootFunction extends LootItemConditionalFunction {
public static final Codec<MachineLootFunction> CODEC = RecordCodecBuilder.create(instance -> commonFields(instance).apply(instance, MachineLootFunction::new));
public static final MapCodec<MachineLootFunction> CODEC = RecordCodecBuilder.mapCodec(instance -> commonFields(instance).apply(instance, MachineLootFunction::new));
protected MachineLootFunction(List<LootItemCondition> conditions) {
super(conditions);
@ -42,7 +42,7 @@ public class MachineLootFunction extends LootItemConditionalFunction {
protected ItemStack run(ItemStack stack, LootContext ctx) {
BlockEntity blockEntity = ctx.getParamOrNull(LootContextParams.BLOCK_ENTITY);
if (blockEntity != null) {
blockEntity.saveToItem(stack);
blockEntity.saveToItem(stack, ctx.getLevel().registryAccess());
}
return stack;

View File

@ -60,11 +60,11 @@ public class MaterialParser {
} else if (soundTypeJson instanceof JsonObject soundTypeObj) {
if (soundTypeObj.has("break_sound") && soundTypeObj.has("step_sound") && soundTypeObj.has("place_sound") && soundTypeObj.has("hit_sound") && soundTypeObj.has("fall_sound")) {
return new DeferredSoundType(1.0f, 1.0f,
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("break_sound").getAsString())),
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("step_sound").getAsString())),
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("place_sound").getAsString())),
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("hit_sound").getAsString())),
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("fall_sound").getAsString()))
DeferredHolder.create(Registries.SOUND_EVENT, ResourceLocation.parse(soundTypeObj.get("break_sound").getAsString())),
DeferredHolder.create(Registries.SOUND_EVENT, ResourceLocation.parse(soundTypeObj.get("step_sound").getAsString())),
DeferredHolder.create(Registries.SOUND_EVENT, ResourceLocation.parse(soundTypeObj.get("place_sound").getAsString())),
DeferredHolder.create(Registries.SOUND_EVENT, ResourceLocation.parse(soundTypeObj.get("hit_sound").getAsString())),
DeferredHolder.create(Registries.SOUND_EVENT, ResourceLocation.parse(soundTypeObj.get("fall_sound").getAsString()))
);
}
} else {

View File

@ -35,7 +35,7 @@ public class ClientMessageHandler {
ctx.workHandler().execute(ClientHandler::disableVoidFogRendering);
}
static void handleVisualUpdate(VisualUpdateMessage msg, PlayPayloadContext ctx) {
static void handleVisualUpdate(VisualUpdateMessage msg, IPayloadContext ctx) {
ctx.workHandler().execute(() -> {
ClientLevel level = Minecraft.getInstance().level;
if (level != null && level.getBlockEntity(msg.pos) instanceof EBlockEntity blockEntity) {
@ -52,7 +52,7 @@ public class ClientMessageHandler {
});
}
public static void handleMenuProperty(MenuPropertyMessage msg, PlayPayloadContext ctx) {
public static void handleMenuProperty(MenuPropertyMessage msg, IPayloadContext ctx) {
ctx.workHandler().execute(() -> {
Player player = Minecraft.getInstance().player;

View File

@ -18,28 +18,28 @@
package thedarkcolour.exdeorum.network;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import thedarkcolour.exdeorum.ExDeorum;
// Like ClientboundContainerSetDataPacket except that the value is 32 bits instead of 16 bits
public record MenuPropertyMessage(int containerId, int index, int value) implements CustomPacketPayload {
public static final ResourceLocation ID = new ResourceLocation(ExDeorum.ID, "menu_property");
public static final Type<MenuPropertyMessage> TYPE = new Type<>(ExDeorum.loc("menu_property"));
public static final StreamCodec<RegistryFriendlyByteBuf, MenuPropertyMessage> STREAM_CODEC = StreamCodec.of(MenuPropertyMessage::write, MenuPropertyMessage::decode);
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeByte(this.containerId);
buffer.writeShort(this.index);
buffer.writeVarInt(this.value);
public static void write(RegistryFriendlyByteBuf buffer, MenuPropertyMessage msg) {
buffer.writeByte(msg.containerId);
buffer.writeShort(msg.index);
buffer.writeVarInt(msg.value);
}
@Override
public ResourceLocation id() {
return ID;
}
public static MenuPropertyMessage decode(FriendlyByteBuf buffer) {
public static MenuPropertyMessage decode(RegistryFriendlyByteBuf buffer) {
return new MenuPropertyMessage(buffer.readByte(), buffer.readShort(), buffer.readVarInt());
}
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View File

@ -20,29 +20,23 @@ package thedarkcolour.exdeorum.network;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.network.registration.IPayloadRegistrar;
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
public final class NetworkHandler {
// DO NOT CONVERT the lambdas to method reference. The server will crash loading client code otherwise.
@SuppressWarnings("Convert2MethodRef")
public static void register(IPayloadRegistrar registrar) {
registrar.play(MenuPropertyMessage.ID, MenuPropertyMessage::decode, sidedHandler -> {
sidedHandler.client((msg, ctx) -> ClientMessageHandler.handleMenuProperty(msg, ctx));
});
registrar.play(VisualUpdateMessage.ID, VisualUpdateMessage::decode, sidedHandler -> {
sidedHandler.client((msg, ctx) -> ClientMessageHandler.handleVisualUpdate(msg, ctx));
});
// not sure if these stop working if they're in the wrong phase, so I'll put them in both
registrar.common(VoidWorldMessage.ID, buffer -> VoidWorldMessage.INSTANCE, sidedHandler -> {
sidedHandler.client((msg, ctx) -> ClientMessageHandler.handleVoidWorldMessage(msg, ctx));
});
public static void register(PayloadRegistrar registrar) {
registrar.playToClient(MenuPropertyMessage.TYPE, MenuPropertyMessage.STREAM_CODEC, (msg, ctx) -> ClientMessageHandler.handleMenuProperty(msg, ctx));
registrar.playToClient(VisualUpdateMessage.TYPE, VisualUpdateMessage.STREAM_CODEC, (msg, ctx) -> ClientMessageHandler.handleVisualUpdate(msg, ctx));
// not sure if this stops working if they're in the wrong phase, so I'll put it in both
registrar.commonToClient(VoidWorldMessage.TYPE, VoidWorldMessage.STREAM_CODEC, (msg, ctx) -> ClientMessageHandler.handleVoidWorldMessage(msg, ctx));
}
public static void sendVoidWorld(ServerPlayer player) {
PacketDistributor.PLAYER.with(player).send(VoidWorldMessage.INSTANCE);
PacketDistributor.sendToPlayer(player, VoidWorldMessage.INSTANCE);
}
public static void sendMenuProperty(ServerPlayer player, int containerId, int index, int prevSieveEnergy) {
PacketDistributor.PLAYER.with(player).send(new MenuPropertyMessage(containerId, index, prevSieveEnergy));
PacketDistributor.sendToPlayer(player, new MenuPropertyMessage(containerId, index, prevSieveEnergy));
}
}

View File

@ -21,27 +21,28 @@ package thedarkcolour.exdeorum.network;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.entity.BlockEntityType;
import org.jetbrains.annotations.Nullable;
import thedarkcolour.exdeorum.ExDeorum;
import thedarkcolour.exdeorum.blockentity.EBlockEntity;
// todo rewrite this to be less jank
class VisualUpdateMessage implements CustomPacketPayload {
public static final ResourceLocation ID = new ResourceLocation(ExDeorum.ID, "visual_update");
/**
* @param blockEntity Null on the dedicated client side
* @param payload Null on the server side
*/
record VisualUpdateMessage(
BlockPos pos,
@Nullable EBlockEntity blockEntity,
BlockEntityType<?> blockEntityType,
@Nullable FriendlyByteBuf payload
) implements CustomPacketPayload {
public static final Type<VisualUpdateMessage> TYPE = new Type<>(ExDeorum.loc("visual_update"));
public static final StreamCodec<RegistryFriendlyByteBuf, VisualUpdateMessage> STREAM_CODEC = StreamCodec.of(VisualUpdateMessage::write, VisualUpdateMessage::decode);
final BlockEntityType<?> blockEntityType;
final BlockPos pos;
// Null on the dedicated client side
@Nullable
final EBlockEntity blockEntity;
// Null on the server side
@Nullable
final FriendlyByteBuf payload;
public VisualUpdateMessage(BlockPos pos, @Nullable EBlockEntity blockEntity, @Nullable BlockEntityType<?> blockEntityType, @Nullable FriendlyByteBuf payload) {
VisualUpdateMessage(BlockPos pos, @Nullable EBlockEntity blockEntity, @Nullable BlockEntityType<?> blockEntityType, @Nullable FriendlyByteBuf payload) {
this.pos = pos;
this.blockEntity = blockEntity;
// payload is saved on the client until it can be handled properly
@ -51,26 +52,25 @@ class VisualUpdateMessage implements CustomPacketPayload {
}
@SuppressWarnings("DataFlowIssue")
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeBlockPos(this.pos);
buffer.writeId(BuiltInRegistries.BLOCK_ENTITY_TYPE, this.blockEntityType);
public static void write(FriendlyByteBuf buffer, VisualUpdateMessage msg) {
buffer.writeBlockPos(msg.pos);
buffer.writeById(BuiltInRegistries.BLOCK_ENTITY_TYPE::getId, msg.blockEntityType);
// write a placeholder value for the number of data bytes, keeping its index for updating later
var dataBytesIndex = buffer.writerIndex();
buffer.writeInt(0);
// write data bytes
this.blockEntity.writeVisualData(buffer);
msg.blockEntity.writeVisualData(buffer);
// set the correct number of data bytes
var numDataBytes = buffer.writerIndex() - dataBytesIndex - 4;
buffer.setInt(dataBytesIndex, numDataBytes);
}
@Override
public ResourceLocation id() {
return ID;
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
public static VisualUpdateMessage decode(FriendlyByteBuf buffer) {
return new VisualUpdateMessage(buffer.readBlockPos(), null, buffer.readById(BuiltInRegistries.BLOCK_ENTITY_TYPE), new FriendlyByteBuf(buffer.readBytes(buffer.readInt())));
return new VisualUpdateMessage(buffer.readBlockPos(), null, buffer.readById(BuiltInRegistries.BLOCK_ENTITY_TYPE::byId), new FriendlyByteBuf(buffer.readBytes(buffer.readInt())));
}
}

View File

@ -19,52 +19,51 @@
package thedarkcolour.exdeorum.network;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.network.PacketDistributor;
import thedarkcolour.exdeorum.blockentity.EBlockEntity;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
// Syncs certain block entity data to the client for visual purposes
// Since some block entities might change their data multiple times a tick, this class keeps track of
// whether a block entity has updated and then pushes out the changes once at the end of each tick.
public class VisualUpdateTracker {
// WeakHashMap is faster than Guava mapmaker because it isn't thread safe
// Use sets to avoid duplicate updates
private static final Map<LevelChunk, Set<BlockPos>> UPDATES = new WeakHashMap<>();
private static final Map<ResourceKey<Level>, Map<ChunkPos, Set<BlockPos>>> UPDATES = new HashMap<>();
public static void sendVisualUpdate(EBlockEntity blockEntity) {
var level = blockEntity.getLevel();
if (level != null && !level.isClientSide) {
var dimension = level.getChunkAt(blockEntity.getBlockPos());
Set<BlockPos> updatesList;
if (!UPDATES.containsKey(dimension)) {
UPDATES.put(dimension, updatesList = new HashSet<>());
} else {
updatesList = UPDATES.get(dimension);
}
updatesList.add(blockEntity.getBlockPos());
Map<ChunkPos, Set<BlockPos>> chunkUpdates = UPDATES.computeIfAbsent(level.dimension(), key -> new HashMap<>());
chunkUpdates.computeIfAbsent(new ChunkPos(blockEntity.getBlockPos()), key -> new HashSet<>()).add(blockEntity.getBlockPos());
}
}
public static void syncVisualUpdates() {
for (var entry : UPDATES.entrySet()) {
var pendingUpdates = entry.getValue();
public static void syncVisualUpdates(MinecraftServer server) {
for (var levelUpdates : UPDATES.entrySet()) {
var level = server.getLevel(levelUpdates.getKey());
for (var updatePos : pendingUpdates) {
var chunk = entry.getKey();
if (level != null) {
var pendingUpdates = levelUpdates.getValue();
if (chunk.getBlockEntity(updatePos) instanceof EBlockEntity blockEntity) {
// packet uses strong reference
PacketDistributor.TRACKING_CHUNK.with(chunk).send(new VisualUpdateMessage(updatePos, blockEntity, blockEntity.getType(), null));
for (var chunkUpdates : pendingUpdates.entrySet()) {
var chunkPos = chunkUpdates.getKey();
for (var updatePos : chunkUpdates.getValue()) {
if (level.getBlockEntity(updatePos) instanceof EBlockEntity blockEntity) {
PacketDistributor.sendToPlayersTrackingChunk(level, chunkPos, new VisualUpdateMessage(updatePos, blockEntity, blockEntity.getType(), null));
}
}
}
}
pendingUpdates.clear();
}
}
}

View File

@ -19,6 +19,7 @@
package thedarkcolour.exdeorum.network;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import thedarkcolour.exdeorum.ExDeorum;
@ -28,14 +29,11 @@ import thedarkcolour.exdeorum.ExDeorum;
public enum VoidWorldMessage implements CustomPacketPayload {
INSTANCE;
public static final ResourceLocation ID = new ResourceLocation(ExDeorum.ID, "void_world_msg");
public static final StreamCodec<FriendlyByteBuf, VoidWorldMessage> STREAM_CODEC = StreamCodec.unit(INSTANCE);
public static final Type<VoidWorldMessage> TYPE = new Type<>(ExDeorum.loc("void_world_msg"));
@Override
public void write(FriendlyByteBuf pBuffer) {
}
@Override
public ResourceLocation id() {
return ID;
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View File

@ -20,7 +20,7 @@ package thedarkcolour.exdeorum.recipe;
import com.mojang.datafixers.Products;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.HolderLookup;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
@ -46,7 +46,7 @@ public abstract class ProbabilityRecipe extends SingleIngredientRecipe {
}
@Override
public ItemStack getResultItem(RegistryAccess access) {
public ItemStack getResultItem(HolderLookup.Provider access) {
return new ItemStack(this.result);
}

View File

@ -18,12 +18,11 @@
package thedarkcolour.exdeorum.recipe;
import net.minecraft.core.NonNullList;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.Container;
import net.minecraft.core.HolderLookup;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeInput;
import net.minecraft.world.level.Level;
/**
@ -32,7 +31,7 @@ import net.minecraft.world.level.Level;
* Has one ingredient by default and just tests off of that. Only the 1st slot
* of any container will be checked, so only one slot should be present.
*/
public abstract class SingleIngredientRecipe implements Recipe<Container> {
public abstract class SingleIngredientRecipe implements Recipe<RecipeInput> {
public final Ingredient ingredient;
public final boolean dependsOnNbt;
@ -46,12 +45,12 @@ public abstract class SingleIngredientRecipe implements Recipe<Container> {
}
@Override
public boolean matches(Container inventory, Level level) {
public boolean matches(RecipeInput inventory, Level level) {
return this.ingredient.test(inventory.getItem(0));
}
@Override
public ItemStack assemble(Container pContainer, RegistryAccess pRegistryAccess) {
public ItemStack assemble(RecipeInput pContainer, HolderLookup.Provider pRegistryAccess) {
return ItemStack.EMPTY;
}
@ -61,16 +60,7 @@ public abstract class SingleIngredientRecipe implements Recipe<Container> {
}
@Override
public ItemStack getResultItem(RegistryAccess access) {
public ItemStack getResultItem(HolderLookup.Provider access) {
return ItemStack.EMPTY;
}
/**
* @deprecated Only used in Vanilla recipe books, and my blocks do not use the recipe book!
*/
@Deprecated
@Override
public NonNullList<Ingredient> getIngredients() {
return NonNullList.create();
}
}

View File

@ -20,13 +20,13 @@ package thedarkcolour.exdeorum.recipe.barrel;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.Container;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeInput;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.Level;
@ -73,7 +73,7 @@ public class BarrelMixingRecipe extends SingleIngredientRecipe {
// Do not use
@Override
@Deprecated
public boolean matches(Container inventory, Level level) {
public boolean matches(RecipeInput inventory, Level level) {
return false;
}
@ -82,7 +82,7 @@ public class BarrelMixingRecipe extends SingleIngredientRecipe {
}
@Override
public ItemStack getResultItem(RegistryAccess access) {
public ItemStack getResultItem(HolderLookup.Provider access) {
return new ItemStack(this.result);
}

View File

@ -38,9 +38,9 @@ import java.util.List;
public class EItems {
public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(ExDeorum.ID);
// Silk Worm (todo rename to "silkworm" in 1.21)
public static final DeferredItem<SilkWormItem> SILK_WORM = ITEMS.register("silk_worm", () -> new SilkWormItem(props()));
public static final DeferredItem<Item> COOKED_SILK_WORM = ITEMS.register("cooked_silk_worm", () -> new CookedSilkWormItem(props().food(new FoodProperties.Builder().nutrition(2).saturationMod(0.6f).build())));
// Silk Worm
public static final DeferredItem<SilkwormItem> SILKWORM = ITEMS.register("silkworm", () -> new SilkwormItem(props()));
public static final DeferredItem<Item> COOKED_SILKWORM = ITEMS.register("cooked_silkworm", () -> new CookedSilkwormItem(props().food(new FoodProperties.Builder().nutrition(2).saturationModifier(0.6f).build())));
// Crooks
public static final DeferredItem<Item> CROOK = ITEMS.register("crook", () -> new CrookItem(props().durability(128), 2.0f));
@ -130,7 +130,7 @@ public class EItems {
public static final DeferredItem<Item> PORCELAIN_WITCH_WATER_BUCKET = ITEMS.register("porcelain_witch_water_bucket", () -> new PorcelainBucket(EFluids.WITCH_WATER, props().craftRemainder(PORCELAIN_BUCKET.get()).stacksTo(1)));
// Fluids
public static final DeferredItem<Item> WITCH_WATER_BUCKET = ITEMS.register("witch_water_bucket", () -> new WitchWaterBucketItem(props().craftRemainder(Items.BUCKET).stacksTo(1)));
public static final DeferredItem<Item> WITCH_WATER_BUCKET = ITEMS.register("witch_water_bucket", () -> new BucketItem(EFluids.WITCH_WATER.get(), props().craftRemainder(Items.BUCKET).stacksTo(1)));
public static DeferredItem<Item> registerSimpleItem(String name) {
return ITEMS.register(name, () -> new Item(props()));
@ -207,8 +207,8 @@ public class EItems {
output.accept(RANDOM_ARMOR_TRIM.get());
output.accept(RANDOM_POTTERY_SHERD.get());
output.accept(SILK_WORM.get());
output.accept(COOKED_SILK_WORM.get());
output.accept(SILKWORM.get());
output.accept(COOKED_SILKWORM.get());
output.accept(CROOK.get());
output.accept(BONE_CROOK.get());
var wateringCans = List.of(WOODEN_WATERING_CAN, STONE_WATERING_CAN, IRON_WATERING_CAN, GOLDEN_WATERING_CAN, DIAMOND_WATERING_CAN, NETHERITE_WATERING_CAN);

View File

@ -30,6 +30,6 @@ public class EStructureSetTags {
public static final TagKey<StructureSet> THE_END_VOID_STRUCTURES = tag("the_end_void_structure_sets");
public static TagKey<StructureSet> tag(String name) {
return TagKey.create(Registries.STRUCTURE_SET, new ResourceLocation(ExDeorum.ID, name));
return TagKey.create(Registries.STRUCTURE_SET, ExDeorum.loc(name));
}
}

View File

@ -18,12 +18,9 @@
package thedarkcolour.exdeorum.voidworld;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.*;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
@ -39,11 +36,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
import net.minecraft.world.level.levelgen.RandomState;
import net.minecraft.world.level.levelgen.*;
import net.minecraft.world.level.levelgen.blending.Blender;
import net.minecraft.world.level.levelgen.structure.StructureSet;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
@ -52,17 +45,14 @@ import thedarkcolour.exdeorum.config.EConfig;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Stream;
public class VoidChunkGenerator extends NoiseBasedChunkGenerator {
public static final Codec<VoidChunkGenerator> CODEC = RecordCodecBuilder.create((inst) -> {
return inst.group(
BiomeSource.CODEC.fieldOf("biome_source").forGetter(gen -> gen.biomeSource),
NoiseGeneratorSettings.CODEC.fieldOf("settings").forGetter(gen -> gen.settings),
TagKey.codec(Registries.STRUCTURE_SET).fieldOf("allowed_structure_sets").forGetter(gen -> gen.allowedStructureSets)
).apply(inst, inst.stable(VoidChunkGenerator::new));
});
public static final MapCodec<VoidChunkGenerator> CODEC = RecordCodecBuilder.mapCodec(inst -> inst.group(
BiomeSource.CODEC.fieldOf("biome_source").forGetter(gen -> gen.biomeSource),
NoiseGeneratorSettings.CODEC.fieldOf("settings").forGetter(gen -> gen.settings),
TagKey.codec(Registries.STRUCTURE_SET).fieldOf("allowed_structure_sets").forGetter(gen -> gen.allowedStructureSets)
).apply(inst, inst.stable(VoidChunkGenerator::new)));
private final Holder<NoiseGeneratorSettings> settings;
private final TagKey<StructureSet> allowedStructureSets;
private final boolean generateNormal;
@ -72,12 +62,12 @@ public class VoidChunkGenerator extends NoiseBasedChunkGenerator {
super(biomeSource, settings);
this.settings = settings;
this.allowedStructureSets = allowedStructureSets;
this.generateNormal = (settings.is(new ResourceLocation("minecraft:end")) && !EConfig.COMMON.voidEndGeneration.get()) || (settings.is(new ResourceLocation("minecraft:nether")) && !EConfig.COMMON.voidNetherGeneration.get());
this.allowBiomeDecoration = !settings.is(new ResourceLocation("minecraft:overworld"));
this.generateNormal = (settings.is(ResourceLocation.parse("minecraft:end")) && !EConfig.COMMON.voidEndGeneration.get()) || (settings.is(ResourceLocation.parse("minecraft:nether")) && !EConfig.COMMON.voidNetherGeneration.get());
this.allowBiomeDecoration = !settings.is(ResourceLocation.parse("minecraft:overworld"));
}
@Override
protected Codec<? extends ChunkGenerator> codec() {
protected MapCodec<? extends ChunkGenerator> codec() {
return CODEC;
}
@ -109,9 +99,9 @@ public class VoidChunkGenerator extends NoiseBasedChunkGenerator {
}
@Override
public CompletableFuture<ChunkAccess> fillFromNoise(Executor pExecutor, Blender pBlender, RandomState pRandom, StructureManager pStructureManager, ChunkAccess chunk) {
public CompletableFuture<ChunkAccess> fillFromNoise(Blender blender, RandomState random, StructureManager manager, ChunkAccess chunk) {
if (this.generateNormal) {
return super.fillFromNoise(pExecutor, pBlender, pRandom, pStructureManager, chunk);
return super.fillFromNoise(blender, random, manager, chunk);
} else {
return CompletableFuture.completedFuture(chunk);
}
@ -167,22 +157,26 @@ public class VoidChunkGenerator extends NoiseBasedChunkGenerator {
return registries.registryOrThrow(Registries.STRUCTURE_SET).getTagOrEmpty(this.allowedStructureSets).iterator().hasNext();
}
private static class FilteredLookup extends HolderLookup.Delegate<StructureSet> {
private final TagKey<StructureSet> allowedValues;
private FilteredLookup(HolderLookup<StructureSet> pParent, TagKey<StructureSet> allowedValues) {
super(pParent);
this.allowedValues = allowedValues;
}
private record FilteredLookup(HolderLookup<StructureSet> parent,
TagKey<StructureSet> allowedValues) implements HolderLookup<StructureSet> {
@Override
public Optional<Holder.Reference<StructureSet>> get(ResourceKey<StructureSet> key) {
return this.parent.get(key).filter(obj -> obj.is(this.allowedValues));
}
@Override
public Optional<HolderSet.Named<StructureSet>> get(TagKey<StructureSet> tagKey) {
return this.parent.get(tagKey);
}
@Override
public Stream<Holder.Reference<StructureSet>> listElements() {
return this.parent.listElements().filter(obj -> obj.is(this.allowedValues));
}
@Override
public Stream<HolderSet.Named<StructureSet>> listTags() {
return this.parent.listTags();
}
}
}