From 469ac8c1031f568d883faf93b2a40d5c3c6c5cad Mon Sep 17 00:00:00 2001 From: AlphaMode <26313415+AlphaMode@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:22:46 -0500 Subject: [PATCH] improv: 1.20.1 fabric port finishes (#15) --- gradle.properties | 2 +- .../capability/CapabilityProvider.java | 38 - .../nitrogen/capability/CapabilityUtil.java | 41 +- .../nitrogen/capability/INBTSynchable.java | 258 +++--- .../NitrogenBlockLootSubProvider.java | 4 +- .../providers/NitrogenBlockStateProvider.java | 735 +++++++++--------- .../providers/NitrogenItemModelProvider.java | 348 ++++----- .../providers/NitrogenRecipeProvider.java | 6 +- .../nitrogen/network/BasePacket.java | 10 + .../nitrogen/network/PacketRelay.java | 19 +- .../network/packet/SyncEntityPacket.java | 113 +-- .../network/packet/SyncLevelPacket.java | 69 +- .../nitrogen/network/packet/SyncPacket.java | 122 +-- .../clientbound/UpdateUserInfoPacket.java | 4 +- .../serverbound/TriggerUpdateInfoPacket.java | 6 +- 15 files changed, 872 insertions(+), 903 deletions(-) delete mode 100644 src/main/java/com/aetherteam/nitrogen/capability/CapabilityProvider.java create mode 100644 src/main/java/com/aetherteam/nitrogen/network/BasePacket.java diff --git a/gradle.properties b/gradle.properties index 9657d0d..b032ee3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,5 +15,5 @@ parchment_mappings=2023.08.20 fabric_api_version=0.89.3+1.20.1 components_version=5.1.0 porting_lib_version=2.1.1087+1.20 -porting_lib_modules=accessors,base,data,networking,utility +porting_lib_modules=accessors,base,data,networking,utility,model_generators jei_version=15.2.0.27 diff --git a/src/main/java/com/aetherteam/nitrogen/capability/CapabilityProvider.java b/src/main/java/com/aetherteam/nitrogen/capability/CapabilityProvider.java deleted file mode 100644 index bde666b..0000000 --- a/src/main/java/com/aetherteam/nitrogen/capability/CapabilityProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.aetherteam.nitrogen.capability; - -//import net.minecraft.core.Direction; -//import net.minecraft.nbt.CompoundTag; -//import net.minecraftforge.common.capabilities.Capability; -//import net.minecraftforge.common.capabilities.ICapabilitySerializable; -//import net.minecraftforge.common.util.INBTSerializable; -//import net.minecraftforge.common.util.LazyOptional; -// -///** -// * Record used for creating basic capability providers. -// * @param registeredCapability The registered {@link Capability} field. -// * @param capabilityInterface The {@link INBTSerializable}<{@link CompoundTag}> capability class. -// */ -//public record CapabilityProvider(Capability registeredCapability, INBTSerializable capabilityInterface) implements ICapabilitySerializable { -// @Override -// public CompoundTag serializeNBT() { -// return this.capabilityInterface().serializeNBT(); -// } -// -// @Override -// public void deserializeNBT(CompoundTag tag) { -// this.capabilityInterface().deserializeNBT(tag); -// } -// -// /** -// * Warning for "unchecked" is suppressed because the generic cast is fine for capabilities. -// */ -// @SuppressWarnings("unchecked") -// @Override -// public LazyOptional getCapability(Capability capability, Direction side) { -// if (capability == this.registeredCapability()) { -// return LazyOptional.of(() -> (T) this.capabilityInterface()); -// } -// return LazyOptional.empty(); -// } -//} -// todo CARDINAL COMPONENTS \ No newline at end of file diff --git a/src/main/java/com/aetherteam/nitrogen/capability/CapabilityUtil.java b/src/main/java/com/aetherteam/nitrogen/capability/CapabilityUtil.java index 7692b1d..af76e79 100644 --- a/src/main/java/com/aetherteam/nitrogen/capability/CapabilityUtil.java +++ b/src/main/java/com/aetherteam/nitrogen/capability/CapabilityUtil.java @@ -1,23 +1,22 @@ package com.aetherteam.nitrogen.capability; -//import com.aetherteam.nitrogen.network.packet.SyncLevelPacket; -//import net.minecraft.client.Minecraft; -//import net.minecraft.world.entity.player.Player; -//import net.minecraft.world.level.Level; -// -//public class CapabilityUtil { -// /** -// * Used to sync data for level capabilities. This is in its own class to avoid classloading {@link Minecraft} from {@link SyncLevelPacket} on servers. -// * @param syncLevelPacket The {@link SyncLevelPacket}. -// * @param playerEntity The {@link Player} that the level belongs to. -// * @param key The {@link String} key for the field to sync. -// * @param value The {@link Object} value to sync to the field. -// * @param isClientSide Whether the level is clientside, as a {@link Boolean}. -// * @see SyncLevelPacket -// */ -// public static void syncLevelCapability(SyncLevelPacket syncLevelPacket, Player playerEntity, String key, Object value, boolean isClientSide) { -// Level level = isClientSide ? Minecraft.getInstance().level : playerEntity.level(); -// syncLevelPacket.getCapability(level).ifPresent((synchable) -> synchable.getSynchableFunctions().get(key).getMiddle().accept(value)); -// } -//} -// todo CARDINAL COMPONENTS \ No newline at end of file +import com.aetherteam.nitrogen.network.packet.SyncLevelPacket; +import net.minecraft.client.Minecraft; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; + +public class CapabilityUtil { + /** + * Used to sync data for level capabilities. This is in its own class to avoid classloading {@link Minecraft} from {@link SyncLevelPacket} on servers. + * @param syncLevelPacket The {@link SyncLevelPacket}. + * @param playerEntity The {@link Player} that the level belongs to. + * @param key The {@link String} key for the field to sync. + * @param value The {@link Object} value to sync to the field. + * @param isClientSide Whether the level is clientside, as a {@link Boolean}. + * @see SyncLevelPacket + */ + public static void syncLevelCapability(SyncLevelPacket syncLevelPacket, Player playerEntity, String key, Object value, boolean isClientSide) { + Level level = isClientSide ? Minecraft.getInstance().level : playerEntity.level(); + syncLevelPacket.getCapability(level).ifPresent((synchable) -> synchable.getSynchableFunctions().get(key).getMiddle().accept(value)); + } +} \ No newline at end of file diff --git a/src/main/java/com/aetherteam/nitrogen/capability/INBTSynchable.java b/src/main/java/com/aetherteam/nitrogen/capability/INBTSynchable.java index 76514ed..bb9bba6 100644 --- a/src/main/java/com/aetherteam/nitrogen/capability/INBTSynchable.java +++ b/src/main/java/com/aetherteam/nitrogen/capability/INBTSynchable.java @@ -1,131 +1,131 @@ package com.aetherteam.nitrogen.capability; -//import com.aetherteam.nitrogen.network.BasePacket; -//import com.aetherteam.nitrogen.network.PacketRelay; -//import net.minecraft.nbt.Tag; -//import net.minecraft.resources.ResourceKey; -//import net.minecraft.server.level.ServerPlayer; -//import net.minecraft.world.level.Level; -//import net.minecraftforge.common.util.INBTSerializable; -//import net.minecraftforge.network.simple.SimpleChannel; -//import org.apache.commons.lang3.tuple.Triple; -//import oshi.util.tuples.Quintet; -// -//import org.jetbrains.annotations.Nullable; -//import java.util.Map; -//import java.util.function.Consumer; -//import java.util.function.Supplier; -// -//public interface INBTSynchable extends INBTSerializable { -// /** -// * Sets a value to be synced to the given direction. -// * @param direction The network {@link Direction} to send the packet. -// * @param key The {@link String} key for the field to sync. -// * @param value The {@link Object} value to sync to the field. -// */ -// default void setSynched(Direction direction, String key, Object value) { -// this.setSynched(direction, key, value, null); -// } -// -// /** -// * Sets a value to be synced to the given direction.

-// * Warning for "unchecked" is suppressed because casting from wildcards to classes inside type bounds is fine. -// * @param direction The network {@link Direction} to send the packet. -// * @param key The {@link String} key for the field to sync. -// * @param value The {@link Object} value to sync to the field. -// * @param extra An extra value if necessary. The type of class that needs to be given depends on the direction.

-// * {@link Direction#SERVER} - None.

-// * {@link Direction#CLIENT} - None.

-// * {@link Direction#NEAR} - {@link Quintet}<{@link Double}, {@link Double}, {@link Double}, {@link Double}, {@link ResourceKey}<{@link Level}>>. This represents the 5 values needed for {@link PacketRelay#sendToNear(SimpleChannel, Object, double, double, double, double, ResourceKey)}.

-// * {@link Direction#PLAYER} - {@link ServerPlayer}.

-// * {@link Direction#DIMENSION} - {@link ResourceKey}<{@link Level}>>. This represents the dimension to send the packet to. -// */ -// @SuppressWarnings("unchecked") -// default void setSynched(Direction direction, String key, Object value, @Nullable Object extra) { -// switch(direction) { -// case SERVER -> PacketRelay.sendToServer(this.getPacketChannel(), this.getSyncPacket(key, this.getSynchableFunctions().get(key).getLeft(), value)); -// case CLIENT -> PacketRelay.sendToAll(this.getPacketChannel(), this.getSyncPacket(key, this.getSynchableFunctions().get(key).getLeft(), value)); -// case NEAR -> { -// if (extra instanceof Quintet quintet) { -// Quintet> nearValues = (Quintet>) quintet; -// PacketRelay.sendToNear(this.getPacketChannel(), this.getSyncPacket(key, this.getSynchableFunctions().get(key).getLeft(), value), nearValues.getA(), nearValues.getB(), nearValues.getC(), nearValues.getD(), nearValues.getE()); -// } -// } -// case PLAYER -> { -// if (extra instanceof ServerPlayer serverPlayer) { -// PacketRelay.sendToPlayer(this.getPacketChannel(), this.getSyncPacket(key, this.getSynchableFunctions().get(key).getLeft(), value), serverPlayer); -// } -// } -// case DIMENSION -> { -// if (extra instanceof ResourceKey resourceKey) { -// ResourceKey dimensionValue = (ResourceKey) resourceKey; -// PacketRelay.sendToDimension(this.getPacketChannel(), this.getSyncPacket(key, this.getSynchableFunctions().get(key).getLeft(), value), dimensionValue); -// } -// } -// } -// this.getSynchableFunctions().get(key).getMiddle().accept(value); -// } -// -// /** -// * Forces all synchable capability values to sync to the given direction. -// * @param direction The network {@link Direction} to send the packet. -// */ -// default void forceSync(Direction direction) { -// this.forceSync(direction, null); -// } -// -// /** -// * Forces all synchable capability values to sync to the given direction. -// * @param direction The network {@link Direction} to send the packet. -// * @param extra An extra value if necessary. The type of class that needs to be given depends on the direction.

-// * {@link Direction#SERVER} - None.

-// * {@link Direction#CLIENT} - None.

-// * {@link Direction#NEAR} - {@link Quintet}<{@link Double}, {@link Double}, {@link Double}, {@link Double}, {@link ResourceKey}<{@link Level}>>. This represents the 5 values needed for {@link PacketRelay#sendToNear(SimpleChannel, Object, double, double, double, double, ResourceKey)}.

-// * {@link Direction#PLAYER} - {@link ServerPlayer}.

-// * {@link Direction#DIMENSION} - {@link ResourceKey}<{@link Level}>>. This represents the dimension to send the packet to. -// */ -// default void forceSync(Direction direction, @Nullable Object extra) { -// for (Map.Entry, Supplier>> entry : this.getSynchableFunctions().entrySet()) { -// this.setSynched(direction, entry.getKey(), entry.getValue().getRight().get(), extra); -// } -// } -// -// /** -// * @return A {@link Map} of {@link String}s (representing the name of a field), and {@link Triple}s, containing -// * {@link Type}s (representing the data type), -// * {@link Consumer}<{@link Object}>s (representing setter methods), and -// * {@link Supplier}<{@link Object}>s (representing getter methods). -// */ -// Map, Supplier>> getSynchableFunctions(); -// -// /** -// * Creates the packet used for syncing. -// * @param key The {@link String} key for the field to sync. -// * @param type The {@link Type} for the field's data type. -// * @param value The {@link Object} value to sync to the field. -// * @return The {@link BasePacket} for syncing. -// */ -// BasePacket getSyncPacket(String key, INBTSynchable.Type type, Object value); -// -// /** -// * @return The {@link SimpleChannel} to send the packet through. -// */ -// SimpleChannel getPacketChannel(); -// -// enum Direction { -// SERVER, -// CLIENT, -// NEAR, -// PLAYER, -// DIMENSION -// } -// -// enum Type { -// INT, -// FLOAT, -// DOUBLE, -// BOOLEAN, -// UUID -// } -//} -// todo CARDINAL COMPONENTS \ No newline at end of file +import com.aetherteam.nitrogen.network.BasePacket; +import com.aetherteam.nitrogen.network.PacketRelay; +import io.github.fabricators_of_create.porting_lib.core.util.INBTSerializable; +import io.github.fabricators_of_create.porting_lib.util.ServerLifecycleHooks; +import me.pepperbell.simplenetworking.SimpleChannel; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.Level; +import org.apache.commons.lang3.tuple.Triple; +import oshi.util.tuples.Quintet; + +import org.jetbrains.annotations.Nullable; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public interface INBTSynchable extends INBTSerializable { + /** + * Sets a value to be synced to the given direction. + * @param direction The network {@link Direction} to send the packet. + * @param key The {@link String} key for the field to sync. + * @param value The {@link Object} value to sync to the field. + */ + default void setSynched(Direction direction, String key, Object value) { + this.setSynched(direction, key, value, null); + } + + /** + * Sets a value to be synced to the given direction.

+ * Warning for "unchecked" is suppressed because casting from wildcards to classes inside type bounds is fine. + * @param direction The network {@link Direction} to send the packet. + * @param key The {@link String} key for the field to sync. + * @param value The {@link Object} value to sync to the field. + * @param extra An extra value if necessary. The type of class that needs to be given depends on the direction.

+ * {@link Direction#SERVER} - None.

+ * {@link Direction#CLIENT} - None.

+ * {@link Direction#NEAR} - {@link Quintet}<{@link Double}, {@link Double}, {@link Double}, {@link Double}, {@link ResourceKey}<{@link Level}>>. This represents the 5 values needed for {@link PacketRelay#sendToNear(SimpleChannel, BasePacket, double, double, double, double, ResourceKey)}.

+ * {@link Direction#PLAYER} - {@link ServerPlayer}.

+ * {@link Direction#DIMENSION} - {@link ResourceKey}<{@link Level}>>. This represents the dimension to send the packet to. + */ + @SuppressWarnings("unchecked") + default void setSynched(Direction direction, String key, Object value, @Nullable Object extra) { + switch(direction) { + case SERVER -> PacketRelay.sendToServer(this.getPacketChannel(), this.getSyncPacket(key, this.getSynchableFunctions().get(key).getLeft(), value)); + case CLIENT -> PacketRelay.sendToAll(this.getPacketChannel(), this.getSyncPacket(key, this.getSynchableFunctions().get(key).getLeft(), value)); + case NEAR -> { + if (extra instanceof Quintet quintet) { + Quintet> nearValues = (Quintet>) quintet; + PacketRelay.sendToNear(this.getPacketChannel(), this.getSyncPacket(key, this.getSynchableFunctions().get(key).getLeft(), value), nearValues.getA(), nearValues.getB(), nearValues.getC(), nearValues.getD(), nearValues.getE()); + } + } + case PLAYER -> { + if (extra instanceof ServerPlayer serverPlayer) { + PacketRelay.sendToPlayer(this.getPacketChannel(), this.getSyncPacket(key, this.getSynchableFunctions().get(key).getLeft(), value), serverPlayer); + } + } + case DIMENSION -> { + if (extra instanceof ResourceKey resourceKey) { + ResourceKey dimensionValue = (ResourceKey) resourceKey; + PacketRelay.sendToDimension(this.getPacketChannel(), this.getSyncPacket(key, this.getSynchableFunctions().get(key).getLeft(), value), dimensionValue); + } + } + } + this.getSynchableFunctions().get(key).getMiddle().accept(value); + } + + /** + * Forces all synchable capability values to sync to the given direction. + * @param direction The network {@link Direction} to send the packet. + */ + default void forceSync(Direction direction) { + this.forceSync(direction, null); + } + + /** + * Forces all synchable capability values to sync to the given direction. + * @param direction The network {@link Direction} to send the packet. + * @param extra An extra value if necessary. The type of class that needs to be given depends on the direction.

+ * {@link Direction#SERVER} - None.

+ * {@link Direction#CLIENT} - None.

+ * {@link Direction#NEAR} - {@link Quintet}<{@link Double}, {@link Double}, {@link Double}, {@link Double}, {@link ResourceKey}<{@link Level}>>. This represents the 5 values needed for {@link PacketRelay#sendToNear(SimpleChannel, Object, double, double, double, double, ResourceKey)}.

+ * {@link Direction#PLAYER} - {@link ServerPlayer}.

+ * {@link Direction#DIMENSION} - {@link ResourceKey}<{@link Level}>>. This represents the dimension to send the packet to. + */ + default void forceSync(Direction direction, @Nullable Object extra) { + for (Map.Entry, Supplier>> entry : this.getSynchableFunctions().entrySet()) { + this.setSynched(direction, entry.getKey(), entry.getValue().getRight().get(), extra); + } + } + + /** + * @return A {@link Map} of {@link String}s (representing the name of a field), and {@link Triple}s, containing + * {@link Type}s (representing the data type), + * {@link Consumer}<{@link Object}>s (representing setter methods), and + * {@link Supplier}<{@link Object}>s (representing getter methods). + */ + Map, Supplier>> getSynchableFunctions(); + + /** + * Creates the packet used for syncing. + * @param key The {@link String} key for the field to sync. + * @param type The {@link Type} for the field's data type. + * @param value The {@link Object} value to sync to the field. + * @return The {@link BasePacket} for syncing. + */ + BasePacket getSyncPacket(String key, INBTSynchable.Type type, Object value); + + /** + * @return The {@link SimpleChannel} to send the packet through. + */ + SimpleChannel getPacketChannel(); + + enum Direction { + SERVER, + CLIENT, + NEAR, + PLAYER, + DIMENSION + } + + enum Type { + INT, + FLOAT, + DOUBLE, + BOOLEAN, + UUID + } +} \ No newline at end of file diff --git a/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenBlockLootSubProvider.java b/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenBlockLootSubProvider.java index a109c94..85fa47f 100644 --- a/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenBlockLootSubProvider.java +++ b/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenBlockLootSubProvider.java @@ -1,8 +1,8 @@ package com.aetherteam.nitrogen.data.providers; +import io.github.fabricators_of_create.porting_lib.data.ModdedBlockLootSubProvider; import io.github.fabricators_of_create.porting_lib.tags.Tags; import net.minecraft.advancements.critereon.ItemPredicate; -import net.minecraft.data.loot.BlockLootSubProvider; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; @@ -16,7 +16,7 @@ import java.util.Set; -public abstract class NitrogenBlockLootSubProvider extends BlockLootSubProvider { +public abstract class NitrogenBlockLootSubProvider extends ModdedBlockLootSubProvider { public NitrogenBlockLootSubProvider(Set items, FeatureFlagSet flags) { super(items, flags); } diff --git a/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenBlockStateProvider.java b/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenBlockStateProvider.java index 40e4656..4d8a4c2 100644 --- a/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenBlockStateProvider.java +++ b/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenBlockStateProvider.java @@ -1,370 +1,369 @@ package com.aetherteam.nitrogen.data.providers; -//import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider; -//import net.minecraft.core.Direction; -//import net.minecraft.data.PackOutput; -//import net.minecraft.resources.ResourceLocation; -//import net.minecraft.world.level.block.*; -//import net.minecraft.world.level.block.state.properties.BlockStateProperties; -//import net.minecraft.world.level.block.state.properties.Property; -//import net.minecraft.world.level.block.state.properties.SlabType; -//import net.minecraft.world.level.block.state.properties.WallSide; -//import net.minecraftforge.client.model.generators.*; -//import net.minecraftforge.common.data.ExistingFileHelper; -//import net.minecraftforge.registries.ForgeRegistries; -// -//import java.util.Map; -// -//public abstract class NitrogenBlockStateProvider extends FabricModelProvider { -// public NitrogenBlockStateProvider(PackOutput output, String id, ExistingFileHelper helper) { -// super(output, id, helper); -// } -// -// public String name(Block block) { -// ResourceLocation location = ForgeRegistries.BLOCKS.getKey(block); -// if (location != null) { -// return location.getPath(); -// } else { -// throw new IllegalStateException("Unknown block: " + block.toString()); -// } -// } -// -// public ResourceLocation texture(String name) { -// return this.modLoc("block/" + name); -// } -// -// public ResourceLocation texture(String name, String location) { -// return this.modLoc("block/" + location + name); -// } -// -// public ResourceLocation texture(String name, String location, String suffix) { -// return this.modLoc("block/" + location + name + suffix); -// } -// -// public ResourceLocation extend(ResourceLocation location, String suffix) { -// return new ResourceLocation(location.getNamespace(), location.getPath() + suffix); -// } -// -// public void block(Block block, String location) { -// this.simpleBlock(block, this.cubeAll(block, location)); -// } -// -// public void portal(Block block) { -// ModelFile portal_ew = this.models().withExistingParent(this.name(block) + "_ew", this.mcLoc("block/nether_portal_ew")) -// .texture("particle", this.modLoc("block/miscellaneous/" + this.name(block))) -// .texture("portal", this.modLoc("block/miscellaneous/" + this.name(block))) -// .renderType(new ResourceLocation("translucent")); -// ModelFile portal_ns = this.models().withExistingParent(this.name(block) + "_ns", this.mcLoc("block/nether_portal_ns")) -// .texture("particle", this.modLoc("block/miscellaneous/" + this.name(block))) -// .texture("portal", this.modLoc("block/miscellaneous/" + this.name(block))) -// .renderType(new ResourceLocation("translucent")); -// this.getVariantBuilder(block).forAllStates(state -> { -// Direction.Axis axis = state.getValue(NetherPortalBlock.AXIS); -// return ConfiguredModel.builder() -// .modelFile(axis == Direction.Axis.Z ? portal_ew : portal_ns) -// .build(); -// }); -// } -// -// public void translucentBlock(Block block, String location) { -// this.simpleBlock(block, this.cubeAllTranslucent(block, location)); -// } -// -// public void log(RotatedPillarBlock block) { -// this.axisBlock(block, this.texture(this.name(block), "natural/"), this.extend(this.texture(this.name(block), "natural/"), "_top")); -// } -// -// public void wood(RotatedPillarBlock block, RotatedPillarBlock baseBlock) { -// this.axisBlock(block, this.texture(this.name(baseBlock), "natural/"), this.texture(this.name(baseBlock), "natural/")); -// } -// -// public void pane(IronBarsBlock block, GlassBlock glass, String location) { -// this.paneBlockWithRenderType(block, this.texture(this.name(glass), location), this.extend(this.texture(this.name(block), location), "_top"), ResourceLocation.tryParse("translucent")); -// } -// -// public void torchBlock(Block block, Block wall) { -// ModelFile torch = this.models().torch(this.name(block), this.texture(this.name(block), "utility/")).renderType(new ResourceLocation("cutout")); -// ModelFile wallTorch = this.models().torchWall(this.name(wall), this.texture(this.name(block), "utility/")).renderType(new ResourceLocation("cutout")); -// this.simpleBlock(block, torch); -// getVariantBuilder(wall).forAllStates(state -> -// ConfiguredModel.builder() -// .modelFile(wallTorch) -// .rotationY(((int) state.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot() + 90) % 360) -// .build()); -// } -// -// public void signBlock(StandingSignBlock signBlock, WallSignBlock wallSignBlock, ResourceLocation texture) { -// ModelFile sign = this.models().sign(this.name(signBlock), texture); -// this.signBlock(signBlock, wallSignBlock, sign); -// } -// -// public void crossBlock(Block block, String location) { -// this.crossBlock(block, models().cross(this.name(block), this.texture(this.name(block), location)).renderType(new ResourceLocation("cutout"))); -// } -// -// public void crossBlock(Block block, ModelFile model) { -// this.getVariantBuilder(block).forAllStates(state -> ConfiguredModel.builder().modelFile(model).build()); -// } -// -// public void pottedPlant(Block block, Block flower, String location) { -// ModelFile pot = this.models().withExistingParent(this.name(block), this.mcLoc("block/flower_pot_cross")).texture("plant", this.modLoc("block/" + location + this.name(flower))).renderType(new ResourceLocation("cutout")); -// this.getVariantBuilder(block).partialState().addModels(new ConfiguredModel(pot)); -// } -// -// public void saplingBlock(Block block, String location) { -// ModelFile sapling = models().cross(this.name(block), this.texture(this.name(block), location)).renderType(new ResourceLocation("cutout")); -// this.getVariantBuilder(block).forAllStatesExcept(state -> ConfiguredModel.builder().modelFile(sapling).build(), SaplingBlock.STAGE); -// } -// -// public void chest(Block block, ModelFile chest) { -// this.getVariantBuilder(block).forAllStatesExcept(state -> ConfiguredModel.builder().modelFile(chest).build(), -// ChestBlock.TYPE, ChestBlock.WATERLOGGED); -// } -// -// public void fence(FenceBlock block, Block baseBlock, String location) { -// this.fenceBlock(block, this.texture(this.name(baseBlock), location)); -// this.fenceColumn(block, this.name(baseBlock), location); -// } -// -// public void fenceColumn(CrossCollisionBlock block, String side, String location) { -// String baseName = this.name(block); -// this.fourWayBlock(block, -// this.models().fencePost(baseName + "_post", this.texture(side, location)), -// this.models().fenceSide(baseName + "_side", this.texture(side, location))); -// } -// -// public void fenceGateBlock(FenceGateBlock block, Block baseBlock, String location) { -// this.fenceGateBlockInternal(block, this.name(block), this.texture(this.name(baseBlock), location)); -// } -// -// public void fenceGateBlockInternal(FenceGateBlock block, String baseName, ResourceLocation texture) { -// ModelFile gate = this.models().fenceGate(baseName, texture); -// ModelFile gateOpen = this.models().fenceGateOpen(baseName + "_open", texture); -// ModelFile gateWall = this.models().fenceGateWall(baseName + "_wall", texture); -// ModelFile gateWallOpen = this.models().fenceGateWallOpen(baseName + "_wall_open", texture); -// this.fenceGateBlock(block, gate, gateOpen, gateWall, gateWallOpen); -// } -// -// public void doorBlock(DoorBlock block, ResourceLocation bottom, ResourceLocation top) { -// this.doorBlockWithRenderType(block, bottom, top, "cutout"); -// } -// -// public void trapdoorBlock(TrapDoorBlock block, ResourceLocation texture, boolean orientable) { -// this.trapdoorBlockWithRenderType(block, texture, orientable, "cutout"); -// } -// -// public void buttonBlock(ButtonBlock block, ResourceLocation texture) { -// ModelFile button = this.models().button(this.name(block), texture); -// ModelFile buttonPressed = this.models().buttonPressed(this.name(block) + "_pressed", texture); -// this.buttonBlock(block, button, buttonPressed); -// } -// -// public void pressurePlateBlock(PressurePlateBlock block, ResourceLocation texture) { -// ModelFile pressurePlate = this.models().pressurePlate(this.name(block), texture); -// ModelFile pressurePlateDown = this.models().pressurePlateDown(this.name(block) + "_down", texture); -// this.pressurePlateBlock(block, pressurePlate, pressurePlateDown); -// } -// -// public void wallBlock(WallBlock block, Block baseBlock, String location) { -// this.wallBlockInternal(block, this.name(block), this.texture(this.name(baseBlock), location)); -// } -// -// public void wallBlockInternal(WallBlock block, String baseName, ResourceLocation texture) { -// this.wallBlock(block, this.models().wallPost(baseName + "_post", texture), -// this.models().wallSide(baseName + "_side", texture), -// this.models().wallSideTall(baseName + "_side_tall", texture)); -// } -// -// protected BlockModelBuilder makeWallPostModel(int width, int height, String name) { -// return models().withExistingParent(name, this.mcLoc("block/block")) -// .element().from(8 - width, 0.0F, 8 - width).to(8 + width, height, 8 + width) -// .face(Direction.DOWN).texture("#top").cullface(Direction.DOWN).end() -// .face(Direction.UP).texture("#top").cullface(Direction.UP).end() -// .face(Direction.NORTH).texture("#side").end() -// .face(Direction.SOUTH).texture("#side").end() -// .face(Direction.WEST).texture("#side").end() -// .face(Direction.EAST).texture("#side").end().end(); -// } -// -// protected BlockModelBuilder makeWallSideModel(int length, int height, String name, ModelBuilder.FaceRotation faceRotation, int u1, int u2) { -// return models().withExistingParent(name, this.mcLoc("block/block")) -// .element().from(5.0F, 0.0F, 0.0F).to(11.0F, height, length) -// .face(Direction.DOWN).texture("#top").rotation(faceRotation).uvs(u1, 5, u2, 11).cullface(Direction.DOWN).end() -// .face(Direction.UP).texture("#top").rotation(faceRotation).uvs(u1, 5, u2, 11).end() -// .face(Direction.NORTH).texture("#side").cullface(Direction.NORTH).end() -// .face(Direction.SOUTH).texture("#side").end() -// .face(Direction.WEST).texture("#side").end() -// .face(Direction.EAST).texture("#side").end().end(); -// } -// -// public void logWallBlock(WallBlock block, Block baseBlock, String location, String modid, boolean postUsesTop, ModelFile postBig, ModelFile postShort, ModelFile postTall, ModelFile side, ModelFile sideAlt, ModelFile sideTall, ModelFile sideTallAlt, ModelFile sideShort, ModelFile sideAltShort, ModelFile sideTallShort, ModelFile sideTallAltShort) { -// this.logWallBlockInternal(block, this.name(block), new ResourceLocation(modid, "block/" + location + this.name(baseBlock)), postUsesTop, postBig, postShort, postTall, side, sideAlt, sideTall, sideTallAlt, sideShort, sideAltShort, sideTallShort, sideTallAltShort); -// } -// -// private void logWallBlockInternal(WallBlock block, String baseName, ResourceLocation texture, boolean postUsesTop, ModelFile postBig, ModelFile postShort, ModelFile postTall, ModelFile side, ModelFile sideAlt, ModelFile sideTall, ModelFile sideTallAlt, ModelFile sideShort, ModelFile sideAltShort, ModelFile sideTallShort, ModelFile sideTallAltShort) { -// this.logWallBlock( -// this.getMultipartBuilder(block), -// models().getBuilder(baseName + "_post_short").parent(postShort).texture("particle", texture).texture("top", texture).texture("side", texture), -// models().getBuilder(baseName + "_post_tall").parent(postTall).texture("particle", texture).texture("top", texture).texture("side", texture), -// models().getBuilder(baseName + "_side").parent(side).texture("particle", texture).texture("top", texture).texture("side", texture), -// models().getBuilder(baseName + "_side_alt").parent(sideAlt).texture("particle", texture).texture("top", texture).texture("side", texture), -// models().getBuilder(baseName + "_side_tall").parent(sideTall).texture("particle", texture).texture("top", texture).texture("side", texture), -// models().getBuilder(baseName + "_side_tall_alt").parent(sideTallAlt).texture("particle", texture).texture("top", texture).texture("side", texture) -// ); -// -// this.logWallBlockWithPost( -// this.getMultipartBuilder(block), -// models().getBuilder(baseName + "_post").parent(postBig).texture("particle", texture).texture("top", postUsesTop ? (texture + "_top") : texture.toString()).texture("side", texture), -// models().getBuilder(baseName + "_side_short").parent(sideShort).texture("particle", texture).texture("top", texture).texture("side", texture), -// models().getBuilder(baseName + "_side_alt_short").parent(sideAltShort).texture("particle", texture).texture("top", texture).texture("side", texture), -// models().getBuilder(baseName + "_side_tall_short").parent(sideTallShort).texture("particle", texture).texture("top", texture).texture("side", texture), -// models().getBuilder(baseName + "_side_tall_alt_short").parent(sideTallAltShort).texture("particle", texture).texture("top", texture).texture("side", texture) -// ); -// } -// -// public void logWallBlock(MultiPartBlockStateBuilder builder, ModelFile postShort, ModelFile postTall, ModelFile side, ModelFile sideAlt, ModelFile sideTall, ModelFile sideTallAlt) { -// builder -// // Smaller post when West & East are both short while North & South being none -// .part().modelFile(postShort).addModel() -// .nestedGroup().condition(WallBlock.UP, false).condition(WallBlock.EAST_WALL, WallSide.LOW).condition(WallBlock.WEST_WALL, WallSide.LOW).end().end() -// // Taller thinner post when West & East are both tall while North & South being none -// .part().modelFile(postTall).addModel() -// .nestedGroup().condition(WallBlock.UP, false).condition(WallBlock.EAST_WALL, WallSide.TALL).condition(WallBlock.WEST_WALL, WallSide.TALL).end().end() -// // Rotated small post when West & East are both none while North & South are short -// .part().modelFile(postShort).rotationY(90).addModel() -// .nestedGroup().condition(WallBlock.UP, false).condition(WallBlock.EAST_WALL, WallSide.NONE).condition(WallBlock.NORTH_WALL, WallSide.LOW).condition(WallBlock.WEST_WALL, WallSide.NONE).condition(WallBlock.SOUTH_WALL, WallSide.LOW).end().end() -// // Rotated small post when West & East are both none while North & South are tall -// .part().modelFile(postTall).rotationY(90).addModel() -// .nestedGroup().condition(WallBlock.UP, false).condition(WallBlock.EAST_WALL, WallSide.NONE).condition(WallBlock.NORTH_WALL, WallSide.TALL).condition(WallBlock.WEST_WALL, WallSide.NONE).condition(WallBlock.SOUTH_WALL, WallSide.TALL).end().end(); -// WALL_PROPS.entrySet().stream() -// .filter(e -> e.getKey().getAxis().isHorizontal()) -// .forEach(e -> { -// this.logWallSidePart(builder, side, sideAlt, e, WallSide.LOW, false); -// this.logWallSidePart(builder, sideTall, sideTallAlt, e, WallSide.TALL, false); -// }); -// } -// -// public void logWallBlockWithPost(MultiPartBlockStateBuilder builder, ModelFile postBig, ModelFile side, ModelFile sideAlt, ModelFile sideTall, ModelFile sideTallAlt) { -// builder -// // Big post for connections, typically including angled -// .part().modelFile(postBig).addModel() -// .condition(WallBlock.UP, true).end(); -// WALL_PROPS.entrySet().stream() -// .filter(e -> e.getKey().getAxis().isHorizontal()) -// .forEach(e -> { -// this.logWallSidePart(builder, side, sideAlt, e, WallSide.LOW, true); -// this.logWallSidePart(builder, sideTall, sideTallAlt, e, WallSide.TALL, true); -// }); -// } -// -// private void logWallSidePart(MultiPartBlockStateBuilder builder, ModelFile model, ModelFile modelAlt, Map.Entry> entry, WallSide height, boolean hasPost) { -// int rotation = (((int) entry.getKey().toYRot()) + 180) % 360; -// builder.part() -// .modelFile(rotation < 180 ? model : modelAlt) -// .rotationY(rotation) -// .addModel() -// .condition(entry.getValue(), height).condition(WallBlock.UP, hasPost); -// } -// -// public void stairs(StairBlock block, Block baseBlock, String location) { -// this.stairsBlock(block, this.texture(this.name(baseBlock), location)); -// } -// -// public void translucentSlab(Block block, Block baseBlock, String location) { -// ResourceLocation texture = this.texture(this.name(baseBlock), location); -// this.translucentSlabBlock(block, models().slab(this.name(block), texture, texture, texture).renderType(new ResourceLocation("translucent")), -// this.models().slabTop(this.name(block) + "_top", texture, texture, texture).renderType(new ResourceLocation("translucent")), -// this.models().getExistingFile(this.texture(this.name(baseBlock)))); -// } -// -// public void translucentSlabBlock(Block block, ModelFile bottom, ModelFile top, ModelFile doubleSlab) { -// this.getVariantBuilder(block) -// .partialState().with(SlabBlock.TYPE, SlabType.BOTTOM).addModels(new ConfiguredModel(bottom)) -// .partialState().with(SlabBlock.TYPE, SlabType.TOP).addModels(new ConfiguredModel(top)) -// .partialState().with(SlabBlock.TYPE, SlabType.DOUBLE).addModels(new ConfiguredModel(doubleSlab)); -// } -// -// public void slab(SlabBlock block, Block baseBlock, String location) { -// this.slabBlock(block, this.texture(this.name(baseBlock)), this.texture(this.name(baseBlock), location)); -// } -// -// public void bookshelf(Block block, Block endBlock) { -// ModelFile bookshelf = this.models().cubeColumn(this.name(block), this.texture(this.name(block), "construction/"), this.texture(this.name(endBlock), "construction/")); -// this.getVariantBuilder(block).partialState().addModels(new ConfiguredModel(bookshelf)); -// } -// -// public ModelFile cubeAll(Block block, String location) { -// return this.models().cubeAll(this.name(block), this.texture(this.name(block), location)); -// } -// -// public ModelFile cubeAllTranslucent(Block block, String location) { -// return this.models().cubeAll(this.name(block), this.texture(this.name(block), location)).renderType(new ResourceLocation("translucent")); -// } -// -// public ModelFile cubeBottomTop(String block, ResourceLocation side, ResourceLocation bottom, ResourceLocation top) { -// return this.models().cubeBottomTop(block, side, bottom, top); -// } -// -// public void craftingTable(Block block, Block baseBlock, String location, String modid) { -// ResourceLocation baseTexture = new ResourceLocation(modid, "block/" + location + this.name(baseBlock)); -// ModelFile workbench = this.models().cube(this.name(block), -// baseTexture, -// this.extend(this.texture(this.name(block), "utility/"), "_top"), -// this.extend(this.texture(this.name(block), "utility/"), "_front"), -// this.extend(this.texture(this.name(block), "utility/"), "_side"), -// this.extend(this.texture(this.name(block), "utility/"), "_front"), -// this.extend(this.texture(this.name(block), "utility/"), "_side")) -// .texture("particle", this.extend(this.texture(this.name(block), "utility/"), "_front")); -// this.getVariantBuilder(block).partialState().addModels(new ConfiguredModel(workbench)); -// } -// -// public void furnace(Block block) { -// String blockName = this.name(block); -// ResourceLocation side = this.extend(this.texture(this.name(block), "utility/"), "_side"); -// ResourceLocation front_on = this.extend(this.texture(this.name(block), "utility/"), "_front_on"); -// ResourceLocation front = this.extend(this.texture(this.name(block), "utility/"), "_front"); -// ResourceLocation top = this.extend(this.texture(this.name(block), "utility/"), "_top"); -// ModelFile normal = this.models().orientable(blockName, side, front, top); -// ModelFile lit = this.models().orientable(blockName + "_on", side, front_on, top); -// this.getVariantBuilder(block).forAllStatesExcept((state) -> { -// Direction direction = state.getValue(AbstractFurnaceBlock.FACING); -// if (state.getValue(AbstractFurnaceBlock.LIT)) { -// return this.rotateModel(direction, lit); -// } else { -// return this.rotateModel(direction, normal); -// } -// }); -// } -// -// public ConfiguredModel[] rotateModel(Direction direction, ModelFile model) { -// switch (direction) { -// case NORTH -> { -// return ConfiguredModel.builder().modelFile(model).build(); -// } -// case SOUTH -> { -// return ConfiguredModel.builder().modelFile(model).rotationY(180).build(); -// } -// case WEST -> { -// return ConfiguredModel.builder().modelFile(model).rotationY(270).build(); -// } -// case EAST -> { -// return ConfiguredModel.builder().modelFile(model).rotationY(90).build(); -// } -// } -// return ConfiguredModel.builder().build(); -// } -// -// public void ladder(LadderBlock block) { -// ResourceLocation location = this.texture(this.name(block), "construction/"); -// ModelFile ladder = models().withExistingParent(this.name(block), this.mcLoc("block/block")).renderType(new ResourceLocation("cutout")).ao(false) -// .texture("particle", location).texture("texture", location) -// .element().from(0.0F, 0.0F, 15.2F).to(16.0F, 16.0F, 15.2F).shade(false) -// .face(Direction.NORTH).uvs(0.0F, 0.0F, 16.0F, 16.0F).texture("#texture").end() -// .face(Direction.SOUTH).uvs(16.0F, 0.0F, 0.0F, 16.0F).texture("#texture").end() -// .end(); -// this.getVariantBuilder(block).forAllStatesExcept((state) -> { -// Direction direction = state.getValue(LadderBlock.FACING); -// return ConfiguredModel.builder().modelFile(ladder).rotationY((int) (direction.toYRot() + 180) % 360).build(); -// }, LadderBlock.WATERLOGGED); -// } -//} +import io.github.fabricators_of_create.porting_lib.data.ExistingFileHelper; +import io.github.fabricators_of_create.porting_lib.models.generators.ConfiguredModel; +import io.github.fabricators_of_create.porting_lib.models.generators.ModelBuilder; +import io.github.fabricators_of_create.porting_lib.models.generators.ModelFile; +import io.github.fabricators_of_create.porting_lib.models.generators.block.BlockModelBuilder; +import io.github.fabricators_of_create.porting_lib.models.generators.block.BlockStateProvider; +import io.github.fabricators_of_create.porting_lib.models.generators.block.MultiPartBlockStateBuilder; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.data.PackOutput; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.Property; +import net.minecraft.world.level.block.state.properties.SlabType; +import net.minecraft.world.level.block.state.properties.WallSide; + +import java.util.Map; + +public abstract class NitrogenBlockStateProvider extends BlockStateProvider { + public NitrogenBlockStateProvider(PackOutput output, String id, ExistingFileHelper helper) { + super(output, id, helper); + } + + public String name(Block block) { + return BuiltInRegistries.BLOCK.getKey(block).getPath(); + } + + public ResourceLocation texture(String name) { + return this.modLoc("block/" + name); + } + + public ResourceLocation texture(String name, String location) { + return this.modLoc("block/" + location + name); + } + + public ResourceLocation texture(String name, String location, String suffix) { + return this.modLoc("block/" + location + name + suffix); + } + + public ResourceLocation extend(ResourceLocation location, String suffix) { + return new ResourceLocation(location.getNamespace(), location.getPath() + suffix); + } + + public void block(Block block, String location) { + this.simpleBlock(block, this.cubeAll(block, location)); + } + + public void portal(Block block) { + ModelFile portal_ew = this.models().withExistingParent(this.name(block) + "_ew", this.mcLoc("block/nether_portal_ew")) + .texture("particle", this.modLoc("block/miscellaneous/" + this.name(block))) + .texture("portal", this.modLoc("block/miscellaneous/" + this.name(block))) + .renderType(new ResourceLocation("translucent")); + ModelFile portal_ns = this.models().withExistingParent(this.name(block) + "_ns", this.mcLoc("block/nether_portal_ns")) + .texture("particle", this.modLoc("block/miscellaneous/" + this.name(block))) + .texture("portal", this.modLoc("block/miscellaneous/" + this.name(block))) + .renderType(new ResourceLocation("translucent")); + this.getVariantBuilder(block).forAllStates(state -> { + Direction.Axis axis = state.getValue(NetherPortalBlock.AXIS); + return ConfiguredModel.builder() + .modelFile(axis == Direction.Axis.Z ? portal_ew : portal_ns) + .build(); + }); + } + + public void translucentBlock(Block block, String location) { + this.simpleBlock(block, this.cubeAllTranslucent(block, location)); + } + + public void log(RotatedPillarBlock block) { + this.axisBlock(block, this.texture(this.name(block), "natural/"), this.extend(this.texture(this.name(block), "natural/"), "_top")); + } + + public void wood(RotatedPillarBlock block, RotatedPillarBlock baseBlock) { + this.axisBlock(block, this.texture(this.name(baseBlock), "natural/"), this.texture(this.name(baseBlock), "natural/")); + } + + public void pane(IronBarsBlock block, GlassBlock glass, String location) { + this.paneBlockWithRenderType(block, this.texture(this.name(glass), location), this.extend(this.texture(this.name(block), location), "_top"), ResourceLocation.tryParse("translucent")); + } + + public void torchBlock(Block block, Block wall) { + ModelFile torch = this.models().torch(this.name(block), this.texture(this.name(block), "utility/")).renderType(new ResourceLocation("cutout")); + ModelFile wallTorch = this.models().torchWall(this.name(wall), this.texture(this.name(block), "utility/")).renderType(new ResourceLocation("cutout")); + this.simpleBlock(block, torch); + getVariantBuilder(wall).forAllStates(state -> + ConfiguredModel.builder() + .modelFile(wallTorch) + .rotationY(((int) state.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot() + 90) % 360) + .build()); + } + + public void signBlock(StandingSignBlock signBlock, WallSignBlock wallSignBlock, ResourceLocation texture) { + ModelFile sign = this.models().sign(this.name(signBlock), texture); + this.signBlock(signBlock, wallSignBlock, sign); + } + + public void crossBlock(Block block, String location) { + this.crossBlock(block, models().cross(this.name(block), this.texture(this.name(block), location)).renderType(new ResourceLocation("cutout"))); + } + + public void crossBlock(Block block, ModelFile model) { + this.getVariantBuilder(block).forAllStates(state -> ConfiguredModel.builder().modelFile(model).build()); + } + + public void pottedPlant(Block block, Block flower, String location) { + ModelFile pot = this.models().withExistingParent(this.name(block), this.mcLoc("block/flower_pot_cross")).texture("plant", this.modLoc("block/" + location + this.name(flower))).renderType(new ResourceLocation("cutout")); + this.getVariantBuilder(block).partialState().addModels(new ConfiguredModel(pot)); + } + + public void saplingBlock(Block block, String location) { + ModelFile sapling = models().cross(this.name(block), this.texture(this.name(block), location)).renderType(new ResourceLocation("cutout")); + this.getVariantBuilder(block).forAllStatesExcept(state -> ConfiguredModel.builder().modelFile(sapling).build(), SaplingBlock.STAGE); + } + + public void chest(Block block, ModelFile chest) { + this.getVariantBuilder(block).forAllStatesExcept(state -> ConfiguredModel.builder().modelFile(chest).build(), + ChestBlock.TYPE, ChestBlock.WATERLOGGED); + } + + public void fence(FenceBlock block, Block baseBlock, String location) { + this.fenceBlock(block, this.texture(this.name(baseBlock), location)); + this.fenceColumn(block, this.name(baseBlock), location); + } + + public void fenceColumn(CrossCollisionBlock block, String side, String location) { + String baseName = this.name(block); + this.fourWayBlock(block, + this.models().fencePost(baseName + "_post", this.texture(side, location)), + this.models().fenceSide(baseName + "_side", this.texture(side, location))); + } + + public void fenceGateBlock(FenceGateBlock block, Block baseBlock, String location) { + this.fenceGateBlockInternal(block, this.name(block), this.texture(this.name(baseBlock), location)); + } + + public void fenceGateBlockInternal(FenceGateBlock block, String baseName, ResourceLocation texture) { + ModelFile gate = this.models().fenceGate(baseName, texture); + ModelFile gateOpen = this.models().fenceGateOpen(baseName + "_open", texture); + ModelFile gateWall = this.models().fenceGateWall(baseName + "_wall", texture); + ModelFile gateWallOpen = this.models().fenceGateWallOpen(baseName + "_wall_open", texture); + this.fenceGateBlock(block, gate, gateOpen, gateWall, gateWallOpen); + } + + public void doorBlock(DoorBlock block, ResourceLocation bottom, ResourceLocation top) { + this.doorBlockWithRenderType(block, bottom, top, "cutout"); + } + + public void trapdoorBlock(TrapDoorBlock block, ResourceLocation texture, boolean orientable) { + this.trapdoorBlockWithRenderType(block, texture, orientable, "cutout"); + } + + public void buttonBlock(ButtonBlock block, ResourceLocation texture) { + ModelFile button = this.models().button(this.name(block), texture); + ModelFile buttonPressed = this.models().buttonPressed(this.name(block) + "_pressed", texture); + this.buttonBlock(block, button, buttonPressed); + } + + public void pressurePlateBlock(PressurePlateBlock block, ResourceLocation texture) { + ModelFile pressurePlate = this.models().pressurePlate(this.name(block), texture); + ModelFile pressurePlateDown = this.models().pressurePlateDown(this.name(block) + "_down", texture); + this.pressurePlateBlock(block, pressurePlate, pressurePlateDown); + } + + public void wallBlock(WallBlock block, Block baseBlock, String location) { + this.wallBlockInternal(block, this.name(block), this.texture(this.name(baseBlock), location)); + } + + public void wallBlockInternal(WallBlock block, String baseName, ResourceLocation texture) { + this.wallBlock(block, this.models().wallPost(baseName + "_post", texture), + this.models().wallSide(baseName + "_side", texture), + this.models().wallSideTall(baseName + "_side_tall", texture)); + } + + protected BlockModelBuilder makeWallPostModel(int width, int height, String name) { + return models().withExistingParent(name, this.mcLoc("block/block")) + .element().from(8 - width, 0.0F, 8 - width).to(8 + width, height, 8 + width) + .face(Direction.DOWN).texture("#top").cullface(Direction.DOWN).end() + .face(Direction.UP).texture("#top").cullface(Direction.UP).end() + .face(Direction.NORTH).texture("#side").end() + .face(Direction.SOUTH).texture("#side").end() + .face(Direction.WEST).texture("#side").end() + .face(Direction.EAST).texture("#side").end().end(); + } + + protected BlockModelBuilder makeWallSideModel(int length, int height, String name, ModelBuilder.FaceRotation faceRotation, int u1, int u2) { + return models().withExistingParent(name, this.mcLoc("block/block")) + .element().from(5.0F, 0.0F, 0.0F).to(11.0F, height, length) + .face(Direction.DOWN).texture("#top").rotation(faceRotation).uvs(u1, 5, u2, 11).cullface(Direction.DOWN).end() + .face(Direction.UP).texture("#top").rotation(faceRotation).uvs(u1, 5, u2, 11).end() + .face(Direction.NORTH).texture("#side").cullface(Direction.NORTH).end() + .face(Direction.SOUTH).texture("#side").end() + .face(Direction.WEST).texture("#side").end() + .face(Direction.EAST).texture("#side").end().end(); + } + + public void logWallBlock(WallBlock block, Block baseBlock, String location, String modid, boolean postUsesTop, ModelFile postBig, ModelFile postShort, ModelFile postTall, ModelFile side, ModelFile sideAlt, ModelFile sideTall, ModelFile sideTallAlt, ModelFile sideShort, ModelFile sideAltShort, ModelFile sideTallShort, ModelFile sideTallAltShort) { + this.logWallBlockInternal(block, this.name(block), new ResourceLocation(modid, "block/" + location + this.name(baseBlock)), postUsesTop, postBig, postShort, postTall, side, sideAlt, sideTall, sideTallAlt, sideShort, sideAltShort, sideTallShort, sideTallAltShort); + } + + private void logWallBlockInternal(WallBlock block, String baseName, ResourceLocation texture, boolean postUsesTop, ModelFile postBig, ModelFile postShort, ModelFile postTall, ModelFile side, ModelFile sideAlt, ModelFile sideTall, ModelFile sideTallAlt, ModelFile sideShort, ModelFile sideAltShort, ModelFile sideTallShort, ModelFile sideTallAltShort) { + this.logWallBlock( + this.getMultipartBuilder(block), + models().getBuilder(baseName + "_post_short").parent(postShort).texture("particle", texture).texture("top", texture).texture("side", texture), + models().getBuilder(baseName + "_post_tall").parent(postTall).texture("particle", texture).texture("top", texture).texture("side", texture), + models().getBuilder(baseName + "_side").parent(side).texture("particle", texture).texture("top", texture).texture("side", texture), + models().getBuilder(baseName + "_side_alt").parent(sideAlt).texture("particle", texture).texture("top", texture).texture("side", texture), + models().getBuilder(baseName + "_side_tall").parent(sideTall).texture("particle", texture).texture("top", texture).texture("side", texture), + models().getBuilder(baseName + "_side_tall_alt").parent(sideTallAlt).texture("particle", texture).texture("top", texture).texture("side", texture) + ); + + this.logWallBlockWithPost( + this.getMultipartBuilder(block), + models().getBuilder(baseName + "_post").parent(postBig).texture("particle", texture).texture("top", postUsesTop ? (texture + "_top") : texture.toString()).texture("side", texture), + models().getBuilder(baseName + "_side_short").parent(sideShort).texture("particle", texture).texture("top", texture).texture("side", texture), + models().getBuilder(baseName + "_side_alt_short").parent(sideAltShort).texture("particle", texture).texture("top", texture).texture("side", texture), + models().getBuilder(baseName + "_side_tall_short").parent(sideTallShort).texture("particle", texture).texture("top", texture).texture("side", texture), + models().getBuilder(baseName + "_side_tall_alt_short").parent(sideTallAltShort).texture("particle", texture).texture("top", texture).texture("side", texture) + ); + } + + public void logWallBlock(MultiPartBlockStateBuilder builder, ModelFile postShort, ModelFile postTall, ModelFile side, ModelFile sideAlt, ModelFile sideTall, ModelFile sideTallAlt) { + builder + // Smaller post when West & East are both short while North & South being none + .part().modelFile(postShort).addModel() + .nestedGroup().condition(WallBlock.UP, false).condition(WallBlock.EAST_WALL, WallSide.LOW).condition(WallBlock.WEST_WALL, WallSide.LOW).end().end() + // Taller thinner post when West & East are both tall while North & South being none + .part().modelFile(postTall).addModel() + .nestedGroup().condition(WallBlock.UP, false).condition(WallBlock.EAST_WALL, WallSide.TALL).condition(WallBlock.WEST_WALL, WallSide.TALL).end().end() + // Rotated small post when West & East are both none while North & South are short + .part().modelFile(postShort).rotationY(90).addModel() + .nestedGroup().condition(WallBlock.UP, false).condition(WallBlock.EAST_WALL, WallSide.NONE).condition(WallBlock.NORTH_WALL, WallSide.LOW).condition(WallBlock.WEST_WALL, WallSide.NONE).condition(WallBlock.SOUTH_WALL, WallSide.LOW).end().end() + // Rotated small post when West & East are both none while North & South are tall + .part().modelFile(postTall).rotationY(90).addModel() + .nestedGroup().condition(WallBlock.UP, false).condition(WallBlock.EAST_WALL, WallSide.NONE).condition(WallBlock.NORTH_WALL, WallSide.TALL).condition(WallBlock.WEST_WALL, WallSide.NONE).condition(WallBlock.SOUTH_WALL, WallSide.TALL).end().end(); + WALL_PROPS.entrySet().stream() + .filter(e -> e.getKey().getAxis().isHorizontal()) + .forEach(e -> { + this.logWallSidePart(builder, side, sideAlt, e, WallSide.LOW, false); + this.logWallSidePart(builder, sideTall, sideTallAlt, e, WallSide.TALL, false); + }); + } + + public void logWallBlockWithPost(MultiPartBlockStateBuilder builder, ModelFile postBig, ModelFile side, ModelFile sideAlt, ModelFile sideTall, ModelFile sideTallAlt) { + builder + // Big post for connections, typically including angled + .part().modelFile(postBig).addModel() + .condition(WallBlock.UP, true).end(); + WALL_PROPS.entrySet().stream() + .filter(e -> e.getKey().getAxis().isHorizontal()) + .forEach(e -> { + this.logWallSidePart(builder, side, sideAlt, e, WallSide.LOW, true); + this.logWallSidePart(builder, sideTall, sideTallAlt, e, WallSide.TALL, true); + }); + } + + private void logWallSidePart(MultiPartBlockStateBuilder builder, ModelFile model, ModelFile modelAlt, Map.Entry> entry, WallSide height, boolean hasPost) { + int rotation = (((int) entry.getKey().toYRot()) + 180) % 360; + builder.part() + .modelFile(rotation < 180 ? model : modelAlt) + .rotationY(rotation) + .addModel() + .condition(entry.getValue(), height).condition(WallBlock.UP, hasPost); + } + + public void stairs(StairBlock block, Block baseBlock, String location) { + this.stairsBlock(block, this.texture(this.name(baseBlock), location)); + } + + public void translucentSlab(Block block, Block baseBlock, String location) { + ResourceLocation texture = this.texture(this.name(baseBlock), location); + this.translucentSlabBlock(block, models().slab(this.name(block), texture, texture, texture).renderType(new ResourceLocation("translucent")), + this.models().slabTop(this.name(block) + "_top", texture, texture, texture).renderType(new ResourceLocation("translucent")), + this.models().getExistingFile(this.texture(this.name(baseBlock)))); + } + + public void translucentSlabBlock(Block block, ModelFile bottom, ModelFile top, ModelFile doubleSlab) { + this.getVariantBuilder(block) + .partialState().with(SlabBlock.TYPE, SlabType.BOTTOM).addModels(new ConfiguredModel(bottom)) + .partialState().with(SlabBlock.TYPE, SlabType.TOP).addModels(new ConfiguredModel(top)) + .partialState().with(SlabBlock.TYPE, SlabType.DOUBLE).addModels(new ConfiguredModel(doubleSlab)); + } + + public void slab(SlabBlock block, Block baseBlock, String location) { + this.slabBlock(block, this.texture(this.name(baseBlock)), this.texture(this.name(baseBlock), location)); + } + + public void bookshelf(Block block, Block endBlock) { + ModelFile bookshelf = this.models().cubeColumn(this.name(block), this.texture(this.name(block), "construction/"), this.texture(this.name(endBlock), "construction/")); + this.getVariantBuilder(block).partialState().addModels(new ConfiguredModel(bookshelf)); + } + + public ModelFile cubeAll(Block block, String location) { + return this.models().cubeAll(this.name(block), this.texture(this.name(block), location)); + } + + public ModelFile cubeAllTranslucent(Block block, String location) { + return this.models().cubeAll(this.name(block), this.texture(this.name(block), location)).renderType(new ResourceLocation("translucent")); + } + + public ModelFile cubeBottomTop(String block, ResourceLocation side, ResourceLocation bottom, ResourceLocation top) { + return this.models().cubeBottomTop(block, side, bottom, top); + } + + public void craftingTable(Block block, Block baseBlock, String location, String modid) { + ResourceLocation baseTexture = new ResourceLocation(modid, "block/" + location + this.name(baseBlock)); + ModelFile workbench = this.models().cube(this.name(block), + baseTexture, + this.extend(this.texture(this.name(block), "utility/"), "_top"), + this.extend(this.texture(this.name(block), "utility/"), "_front"), + this.extend(this.texture(this.name(block), "utility/"), "_side"), + this.extend(this.texture(this.name(block), "utility/"), "_front"), + this.extend(this.texture(this.name(block), "utility/"), "_side")) + .texture("particle", this.extend(this.texture(this.name(block), "utility/"), "_front")); + this.getVariantBuilder(block).partialState().addModels(new ConfiguredModel(workbench)); + } + + public void furnace(Block block) { + String blockName = this.name(block); + ResourceLocation side = this.extend(this.texture(this.name(block), "utility/"), "_side"); + ResourceLocation front_on = this.extend(this.texture(this.name(block), "utility/"), "_front_on"); + ResourceLocation front = this.extend(this.texture(this.name(block), "utility/"), "_front"); + ResourceLocation top = this.extend(this.texture(this.name(block), "utility/"), "_top"); + ModelFile normal = this.models().orientable(blockName, side, front, top); + ModelFile lit = this.models().orientable(blockName + "_on", side, front_on, top); + this.getVariantBuilder(block).forAllStatesExcept((state) -> { + Direction direction = state.getValue(AbstractFurnaceBlock.FACING); + if (state.getValue(AbstractFurnaceBlock.LIT)) { + return this.rotateModel(direction, lit); + } else { + return this.rotateModel(direction, normal); + } + }); + } + + public ConfiguredModel[] rotateModel(Direction direction, ModelFile model) { + switch (direction) { + case NORTH -> { + return ConfiguredModel.builder().modelFile(model).build(); + } + case SOUTH -> { + return ConfiguredModel.builder().modelFile(model).rotationY(180).build(); + } + case WEST -> { + return ConfiguredModel.builder().modelFile(model).rotationY(270).build(); + } + case EAST -> { + return ConfiguredModel.builder().modelFile(model).rotationY(90).build(); + } + } + return ConfiguredModel.builder().build(); + } + + public void ladder(LadderBlock block) { + ResourceLocation location = this.texture(this.name(block), "construction/"); + ModelFile ladder = models().withExistingParent(this.name(block), this.mcLoc("block/block")).renderType(new ResourceLocation("cutout")).ao(false) + .texture("particle", location).texture("texture", location) + .element().from(0.0F, 0.0F, 15.2F).to(16.0F, 16.0F, 15.2F).shade(false) + .face(Direction.NORTH).uvs(0.0F, 0.0F, 16.0F, 16.0F).texture("#texture").end() + .face(Direction.SOUTH).uvs(16.0F, 0.0F, 0.0F, 16.0F).texture("#texture").end() + .end(); + this.getVariantBuilder(block).forAllStatesExcept((state) -> { + Direction direction = state.getValue(LadderBlock.FACING); + return ConfiguredModel.builder().modelFile(ladder).rotationY((int) (direction.toYRot() + 180) % 360).build(); + }, LadderBlock.WATERLOGGED); + } +} \ No newline at end of file diff --git a/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenItemModelProvider.java b/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenItemModelProvider.java index eb83061..7e2e497 100644 --- a/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenItemModelProvider.java +++ b/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenItemModelProvider.java @@ -1,180 +1,172 @@ package com.aetherteam.nitrogen.data.providers; -//import com.aetherteam.nitrogen.Nitrogen; -//import io.github.fabricators_of_create.porting_lib.data.ExistingFileHelper; -//import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider; -//import net.minecraft.core.Direction; -//import net.minecraft.data.PackOutput; -//import net.minecraft.resources.ResourceKey; -//import net.minecraft.resources.ResourceLocation; -//import net.minecraft.world.item.Item; -//import net.minecraft.world.item.ItemDisplayContext; -//import net.minecraft.world.item.armortrim.TrimMaterial; -//import net.minecraft.world.item.armortrim.TrimMaterials; -//import net.minecraft.world.level.block.Block; -// -//import java.util.List; -// -//public abstract class NitrogenItemModelProvider extends FabricModelProvider { -// protected static final List> VANILLA_TRIM_MATERIALS = List.of(TrimMaterials.QUARTZ, TrimMaterials.IRON, TrimMaterials.NETHERITE, TrimMaterials.REDSTONE, TrimMaterials.COPPER, TrimMaterials.GOLD, TrimMaterials.EMERALD, TrimMaterials.DIAMOND, TrimMaterials.LAPIS, TrimMaterials.AMETHYST); -// -// public NitrogenItemModelProvider(PackOutput output, String id, ExistingFileHelper helper) { -// super(output, id, helper); -// } -// -// public String blockName(Block block) { -// ResourceLocation location = ForgeRegistries.BLOCKS.getKey(block); -// if (location != null) { -// return location.getPath(); -// } else { -// throw new IllegalStateException("Unknown block: " + block.toString()); -// } -// } -// -// public String itemName(Item item) { -// ResourceLocation location = ForgeRegistries.ITEMS.getKey(item); -// if (location != null) { -// return location.getPath(); -// } else { -// throw new IllegalStateException("Unknown item: " + item.toString()); -// } -// } -// -// protected ResourceLocation texture(String name) { -// return this.modLoc("block/" + name); -// } -// -// protected ResourceLocation texture(String name, String location) { -// return this.modLoc("block/" + location + name); -// } -// -// public void item(Item item, String location) { -// this.withExistingParent(this.itemName(item), mcLoc("item/generated")) -// .texture("layer0", modLoc("item/" + location + this.itemName(item))); -// } -// -// public void handheldItem(Item item, String location) { -// this.withExistingParent(this.itemName(item), this.mcLoc("item/handheld")) -// .texture("layer0", this.modLoc("item/" + location + this.itemName(item))); -// } -// -// public void bowItem(Item item, String location) { -// this.withExistingParent(this.itemName(item) + "_pulling_0", this.mcLoc("item/bow")).texture("layer0", this.modLoc("item/" + location + this.itemName(item) + "_pulling_0")); -// this.withExistingParent(this.itemName(item) + "_pulling_1", this.mcLoc("item/bow")).texture("layer0", this.modLoc("item/" + location + this.itemName(item) + "_pulling_1")); -// this.withExistingParent(this.itemName(item) + "_pulling_2", this.mcLoc("item/bow")).texture("layer0", this.modLoc("item/" + location + this.itemName(item) + "_pulling_2")); -// this.withExistingParent(this.itemName(item), this.mcLoc("item/bow")) -// .texture("layer0", this.modLoc("item/" + location + this.itemName(item))) -// .override().predicate(new ResourceLocation("pulling"), 1).model(this.getExistingFile(this.modLoc("item/" + this.itemName(item) + "_pulling_0"))).end() -// .override().predicate(new ResourceLocation("pulling"), 1).predicate(new ResourceLocation("pull"), 0.65F).model(this.getExistingFile(this.modLoc("item/" + this.itemName(item) + "_pulling_1"))).end() -// .override().predicate(new ResourceLocation("pulling"), 1).predicate(new ResourceLocation("pull"), 0.9F).model(this.getExistingFile(this.modLoc("item/" + this.itemName(item) + "_pulling_2"))).end(); -// } -// -// public void helmetItem(Item item, String location) { -// this.armorItem(item, location, "helmet"); -// } -// -// public void chestplateItem(Item item, String location) { -// this.armorItem(item, location, "chestplate"); -// } -// -// public void leggingsItem(Item item, String location) { -// this.armorItem(item, location, "leggings"); -// } -// -// public void bootsItem(Item item, String location) { -// this.armorItem(item, location, "boots"); -// } -// -// public void armorItem(Item item, String location, String type) { -// ItemModelBuilder builder = this.withExistingParent(this.itemName(item), this.mcLoc("item/generated")).texture("layer0", this.modLoc("item/" + location + this.itemName(item))); -// double index = 0.1; -// for (ResourceKey trimMaterial : VANILLA_TRIM_MATERIALS) { -// String material = trimMaterial.location().getPath(); -// String name = this.itemName(item) + "_" + material + "_trim"; -// this.withExistingParent(name, this.mcLoc("item/generated")) -// .texture("layer0", this.modLoc("item/" + location + this.itemName(item))) -// .texture("layer1", this.mcLoc("trims/items/" + type + "_trim_" + material)); -// builder.override().predicate(new ResourceLocation("trim_type"), (float) index).model(this.getExistingFile(this.modLoc("item/" + name))).end(); -// index += 0.1; -// } -// } -// -// public void dyedItem(Item item, String location) { -// this.withExistingParent(this.itemName(item), this.mcLoc("item/generated")) -// .texture("layer0", this.modLoc("item/" + location + this.itemName(item))) -// .texture("layer1", this.modLoc("item/" + location + this.itemName(item) + "_overlay")); -// } -// -// public void eggItem(Item item) { -// this.withExistingParent(this.itemName(item), this.mcLoc("item/template_spawn_egg")); -// } -// -// public void itemBlock(Block block) { -// this.withExistingParent(this.blockName(block), this.texture(this.blockName(block))); -// } -// -// public void itemBlock(Block block, String suffix) { -// this.withExistingParent(this.blockName(block), this.texture(this.blockName(block) + suffix)); -// } -// -// public void pane(Block block, Block glass, String location) { -// this.withExistingParent(this.blockName(block), this.mcLoc("item/generated")) -// .texture("layer0", this.texture(this.blockName(glass), location)) -// .renderType(new ResourceLocation("translucent")); -// } -// -// public void itemBlockFlat(Block block, String location) { -// this.withExistingParent(this.blockName(block), this.mcLoc("item/generated")) -// .texture("layer0", this.texture(this.blockName(block), location)); -// } -// -// public void lookalikeBlock(Block block, ResourceLocation lookalike) { -// this.withExistingParent(this.blockName(block), lookalike); -// } -// -// public void itemFence(Block block, Block baseBlock, String location) { -// this.withExistingParent(this.blockName(block), this.mcLoc("block/fence_inventory")) -// .texture("texture", this.texture(this.blockName(baseBlock), location)); -// } -// -// public void itemButton(Block block, Block baseBlock, String location) { -// this.withExistingParent(this.blockName(block), this.mcLoc("block/button_inventory")) -// .texture("texture", this.texture(this.blockName(baseBlock), location)); -// } -// -// public void itemWallBlock(Block block, Block baseBlock, String location) { -// this.wallInventory(this.blockName(block), this.texture(this.blockName(baseBlock), location)); -// } -// -// public void translucentItemWallBlock(Block block, Block baseBlock, String location) { -// this.singleTexture(this.blockName(block), new ResourceLocation(Nitrogen.MODID, BLOCK_FOLDER + "/template_translucent_wall_inventory"), "wall", this.texture(this.blockName(baseBlock), location)); -// } -// -// public void itemLogWallBlock(Block block, Block baseBlock, String location, String modid) { -// ResourceLocation baseTexture = new ResourceLocation(modid, "block/" + location + this.blockName(baseBlock)); -// this.withExistingParent(this.blockName(block), this.mcLoc("block/block")) -// .transforms() -// .transform(ItemDisplayContext.GUI).rotation(30.0F, 135.0F, 0.0F).translation(0.0F, 0.0F, 0.0F).scale(0.625F, 0.625F, 0.625F).end() -// .transform(ItemDisplayContext.FIXED).rotation(0.0F, 90.0F, 0.0F).translation(0.0F, 0.0F, 0.0F).scale(0.5F, 0.5F, 0.5F).end() -// .end() -// .texture("top", baseTexture + "_top").texture("side", baseTexture) -// .element().from(4.0F, 0.0F, 4.0F).to(12.0F, 16.0F, 12.0F) -// .face(Direction.DOWN).uvs(4.0F, 4.0F, 12.0F, 12.0F).texture("#top").cullface(Direction.DOWN).end() -// .face(Direction.UP).uvs(4.0F, 4.0F, 12.0F, 12.0F).texture("#top").end() -// .face(Direction.NORTH).uvs(4.0F, 0.0F, 12.0F, 16.0F).texture("#side").end() -// .face(Direction.SOUTH).uvs(4.0F, 0.0F, 12.0F, 16.0F).texture("#side").end() -// .face(Direction.WEST).uvs(4.0F, 0.0F, 12.0F, 16.0F).texture("#side").end() -// .face(Direction.EAST).uvs(4.0F, 0.0F, 12.0F, 16.0F).texture("#side").end().end() -// .element().from(5.0F, 0.0F, 0.0F).to(11.0F, 13.0F, 16.0F) -// .face(Direction.DOWN).uvs(5.0F, 0.0F, 11.0F, 16.0F).texture("#top").cullface(Direction.DOWN).end() -// .face(Direction.UP).uvs(5.0F, 0.0F, 11.0F, 16.0F).texture("#top").end() -// .face(Direction.NORTH).uvs(5.0F, 3.0F, 11.0F, 16.0F).texture("#side").cullface(Direction.NORTH).end() -// .face(Direction.SOUTH).uvs(5.0F, 3.0F, 11.0F, 16.0F).texture("#side").cullface(Direction.SOUTH).end() -// .face(Direction.WEST).uvs(0.0F, 3.0F, 16.0F, 16.0F).texture("#side").end() -// .face(Direction.EAST).uvs(0.0F, 3.0F, 16.0F, 16.0F).texture("#side").end().end(); -// } -// -// public void itemWoodWallBlock(Block block, Block baseBlock, String location, String modid) { -// this.wallInventory(this.blockName(block), new ResourceLocation(modid, "block/" + location + this.blockName(baseBlock))); -// } -//} +import com.aetherteam.nitrogen.Nitrogen; +import io.github.fabricators_of_create.porting_lib.data.ExistingFileHelper; +import io.github.fabricators_of_create.porting_lib.models.generators.item.ItemModelBuilder; +import io.github.fabricators_of_create.porting_lib.models.generators.item.ItemModelProvider; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.data.PackOutput; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.armortrim.TrimMaterial; +import net.minecraft.world.item.armortrim.TrimMaterials; +import net.minecraft.world.level.block.Block; + +import java.util.List; + +public abstract class NitrogenItemModelProvider extends ItemModelProvider { + protected static final List> VANILLA_TRIM_MATERIALS = List.of(TrimMaterials.QUARTZ, TrimMaterials.IRON, TrimMaterials.NETHERITE, TrimMaterials.REDSTONE, TrimMaterials.COPPER, TrimMaterials.GOLD, TrimMaterials.EMERALD, TrimMaterials.DIAMOND, TrimMaterials.LAPIS, TrimMaterials.AMETHYST); + + public NitrogenItemModelProvider(PackOutput output, String id, ExistingFileHelper helper) { + super(output, id, helper); + } + + public String blockName(Block block) { + return BuiltInRegistries.BLOCK.getKey(block).getPath(); + } + + public String itemName(Item item) { + return BuiltInRegistries.ITEM.getKey(item).getPath(); + } + + protected ResourceLocation texture(String name) { + return this.modLoc("block/" + name); + } + + protected ResourceLocation texture(String name, String location) { + return this.modLoc("block/" + location + name); + } + + public void item(Item item, String location) { + this.withExistingParent(this.itemName(item), mcLoc("item/generated")) + .texture("layer0", modLoc("item/" + location + this.itemName(item))); + } + + public void handheldItem(Item item, String location) { + this.withExistingParent(this.itemName(item), this.mcLoc("item/handheld")) + .texture("layer0", this.modLoc("item/" + location + this.itemName(item))); + } + + public void bowItem(Item item, String location) { + this.withExistingParent(this.itemName(item) + "_pulling_0", this.mcLoc("item/bow")).texture("layer0", this.modLoc("item/" + location + this.itemName(item) + "_pulling_0")); + this.withExistingParent(this.itemName(item) + "_pulling_1", this.mcLoc("item/bow")).texture("layer0", this.modLoc("item/" + location + this.itemName(item) + "_pulling_1")); + this.withExistingParent(this.itemName(item) + "_pulling_2", this.mcLoc("item/bow")).texture("layer0", this.modLoc("item/" + location + this.itemName(item) + "_pulling_2")); + this.withExistingParent(this.itemName(item), this.mcLoc("item/bow")) + .texture("layer0", this.modLoc("item/" + location + this.itemName(item))) + .override().predicate(new ResourceLocation("pulling"), 1).model(this.getExistingFile(this.modLoc("item/" + this.itemName(item) + "_pulling_0"))).end() + .override().predicate(new ResourceLocation("pulling"), 1).predicate(new ResourceLocation("pull"), 0.65F).model(this.getExistingFile(this.modLoc("item/" + this.itemName(item) + "_pulling_1"))).end() + .override().predicate(new ResourceLocation("pulling"), 1).predicate(new ResourceLocation("pull"), 0.9F).model(this.getExistingFile(this.modLoc("item/" + this.itemName(item) + "_pulling_2"))).end(); + } + + public void helmetItem(Item item, String location) { + this.armorItem(item, location, "helmet"); + } + + public void chestplateItem(Item item, String location) { + this.armorItem(item, location, "chestplate"); + } + + public void leggingsItem(Item item, String location) { + this.armorItem(item, location, "leggings"); + } + + public void bootsItem(Item item, String location) { + this.armorItem(item, location, "boots"); + } + + public void armorItem(Item item, String location, String type) { + ItemModelBuilder builder = this.withExistingParent(this.itemName(item), this.mcLoc("item/generated")).texture("layer0", this.modLoc("item/" + location + this.itemName(item))); + double index = 0.1; + for (ResourceKey trimMaterial : VANILLA_TRIM_MATERIALS) { + String material = trimMaterial.location().getPath(); + String name = this.itemName(item) + "_" + material + "_trim"; + this.withExistingParent(name, this.mcLoc("item/generated")) + .texture("layer0", this.modLoc("item/" + location + this.itemName(item))) + .texture("layer1", this.mcLoc("trims/items/" + type + "_trim_" + material)); + builder.override().predicate(new ResourceLocation("trim_type"), (float) index).model(this.getExistingFile(this.modLoc("item/" + name))).end(); + index += 0.1; + } + } + + public void dyedItem(Item item, String location) { + this.withExistingParent(this.itemName(item), this.mcLoc("item/generated")) + .texture("layer0", this.modLoc("item/" + location + this.itemName(item))) + .texture("layer1", this.modLoc("item/" + location + this.itemName(item) + "_overlay")); + } + + public void eggItem(Item item) { + this.withExistingParent(this.itemName(item), this.mcLoc("item/template_spawn_egg")); + } + + public void itemBlock(Block block) { + this.withExistingParent(this.blockName(block), this.texture(this.blockName(block))); + } + + public void itemBlock(Block block, String suffix) { + this.withExistingParent(this.blockName(block), this.texture(this.blockName(block) + suffix)); + } + + public void pane(Block block, Block glass, String location) { + this.withExistingParent(this.blockName(block), this.mcLoc("item/generated")) + .texture("layer0", this.texture(this.blockName(glass), location)) + .renderType(new ResourceLocation("translucent")); + } + + public void itemBlockFlat(Block block, String location) { + this.withExistingParent(this.blockName(block), this.mcLoc("item/generated")) + .texture("layer0", this.texture(this.blockName(block), location)); + } + + public void lookalikeBlock(Block block, ResourceLocation lookalike) { + this.withExistingParent(this.blockName(block), lookalike); + } + + public void itemFence(Block block, Block baseBlock, String location) { + this.withExistingParent(this.blockName(block), this.mcLoc("block/fence_inventory")) + .texture("texture", this.texture(this.blockName(baseBlock), location)); + } + + public void itemButton(Block block, Block baseBlock, String location) { + this.withExistingParent(this.blockName(block), this.mcLoc("block/button_inventory")) + .texture("texture", this.texture(this.blockName(baseBlock), location)); + } + + public void itemWallBlock(Block block, Block baseBlock, String location) { + this.wallInventory(this.blockName(block), this.texture(this.blockName(baseBlock), location)); + } + + public void translucentItemWallBlock(Block block, Block baseBlock, String location) { + this.singleTexture(this.blockName(block), new ResourceLocation(Nitrogen.MODID, BLOCK_FOLDER + "/template_translucent_wall_inventory"), "wall", this.texture(this.blockName(baseBlock), location)); + } + + public void itemLogWallBlock(Block block, Block baseBlock, String location, String modid) { + ResourceLocation baseTexture = new ResourceLocation(modid, "block/" + location + this.blockName(baseBlock)); + this.withExistingParent(this.blockName(block), this.mcLoc("block/block")) + .transforms() + .transform(ItemDisplayContext.GUI).rotation(30.0F, 135.0F, 0.0F).translation(0.0F, 0.0F, 0.0F).scale(0.625F, 0.625F, 0.625F).end() + .transform(ItemDisplayContext.FIXED).rotation(0.0F, 90.0F, 0.0F).translation(0.0F, 0.0F, 0.0F).scale(0.5F, 0.5F, 0.5F).end() + .end() + .texture("top", baseTexture + "_top").texture("side", baseTexture) + .element().from(4.0F, 0.0F, 4.0F).to(12.0F, 16.0F, 12.0F) + .face(Direction.DOWN).uvs(4.0F, 4.0F, 12.0F, 12.0F).texture("#top").cullface(Direction.DOWN).end() + .face(Direction.UP).uvs(4.0F, 4.0F, 12.0F, 12.0F).texture("#top").end() + .face(Direction.NORTH).uvs(4.0F, 0.0F, 12.0F, 16.0F).texture("#side").end() + .face(Direction.SOUTH).uvs(4.0F, 0.0F, 12.0F, 16.0F).texture("#side").end() + .face(Direction.WEST).uvs(4.0F, 0.0F, 12.0F, 16.0F).texture("#side").end() + .face(Direction.EAST).uvs(4.0F, 0.0F, 12.0F, 16.0F).texture("#side").end().end() + .element().from(5.0F, 0.0F, 0.0F).to(11.0F, 13.0F, 16.0F) + .face(Direction.DOWN).uvs(5.0F, 0.0F, 11.0F, 16.0F).texture("#top").cullface(Direction.DOWN).end() + .face(Direction.UP).uvs(5.0F, 0.0F, 11.0F, 16.0F).texture("#top").end() + .face(Direction.NORTH).uvs(5.0F, 3.0F, 11.0F, 16.0F).texture("#side").cullface(Direction.NORTH).end() + .face(Direction.SOUTH).uvs(5.0F, 3.0F, 11.0F, 16.0F).texture("#side").cullface(Direction.SOUTH).end() + .face(Direction.WEST).uvs(0.0F, 3.0F, 16.0F, 16.0F).texture("#side").end() + .face(Direction.EAST).uvs(0.0F, 3.0F, 16.0F, 16.0F).texture("#side").end().end(); + } + + public void itemWoodWallBlock(Block block, Block baseBlock, String location, String modid) { + this.wallInventory(this.blockName(block), new ResourceLocation(modid, "block/" + location + this.blockName(baseBlock))); + } +} diff --git a/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenRecipeProvider.java b/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenRecipeProvider.java index 78c8fe3..504be7d 100644 --- a/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenRecipeProvider.java +++ b/src/main/java/com/aetherteam/nitrogen/data/providers/NitrogenRecipeProvider.java @@ -1,6 +1,8 @@ package com.aetherteam.nitrogen.data.providers; import com.aetherteam.nitrogen.recipe.BlockPropertyPair; +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.data.PackOutput; import net.minecraft.data.recipes.*; import net.minecraft.resources.ResourceLocation; @@ -15,10 +17,10 @@ import java.util.function.Consumer; import java.util.function.Supplier; -public abstract class NitrogenRecipeProvider extends RecipeProvider { +public abstract class NitrogenRecipeProvider extends FabricRecipeProvider { protected final String id; - public NitrogenRecipeProvider(PackOutput output, String id) { + public NitrogenRecipeProvider(FabricDataOutput output, String id) { super(output); this.id = id; } diff --git a/src/main/java/com/aetherteam/nitrogen/network/BasePacket.java b/src/main/java/com/aetherteam/nitrogen/network/BasePacket.java new file mode 100644 index 0000000..79aaa9c --- /dev/null +++ b/src/main/java/com/aetherteam/nitrogen/network/BasePacket.java @@ -0,0 +1,10 @@ +package com.aetherteam.nitrogen.network; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.entity.player.Player; + +public interface BasePacket extends ServerPacket, ClientPacket { + void encode(FriendlyByteBuf buf); + + void execute(Player player); +} \ No newline at end of file diff --git a/src/main/java/com/aetherteam/nitrogen/network/PacketRelay.java b/src/main/java/com/aetherteam/nitrogen/network/PacketRelay.java index 9b8a562..a29f3dd 100644 --- a/src/main/java/com/aetherteam/nitrogen/network/PacketRelay.java +++ b/src/main/java/com/aetherteam/nitrogen/network/PacketRelay.java @@ -1,29 +1,32 @@ package com.aetherteam.nitrogen.network; +import io.github.fabricators_of_create.porting_lib.util.ServerLifecycleHooks; import me.pepperbell.simplenetworking.SimpleChannel; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; public class PacketRelay { - public static void sendToPlayer(SimpleChannel handler, MSG message, ServerPlayer player) { + public static void sendToPlayer(SimpleChannel handler, MSG message, ServerPlayer player) { handler.sendToClient(message, player); // Clientbound } - public static void sendToNear(SimpleChannel handler, MSG message, double x, double y, double z, double radius, ServerLevel dimension) { - handler.sendToClientsAround(message, dimension, new Vec3(x, y, z), radius); // Clientbound + public static void sendToNear(SimpleChannel handler, MSG message, double x, double y, double z, double radius, ResourceKey dimension) { + handler.sendToClientsAround(message, ServerLifecycleHooks.getCurrentServer().getLevel(dimension), new Vec3(x, y, z), radius); // Clientbound } - public static void sendToAll(SimpleChannel handler, MSG message, MinecraftServer server) { - handler.sendToClientsInServer(message, server); // Clientbound + public static void sendToAll(SimpleChannel handler, MSG message) { + handler.sendToClientsInCurrentServer(message); // Clientbound } - public static void sendToServer(SimpleChannel handler, MSG message) { + public static void sendToServer(SimpleChannel handler, MSG message) { handler.sendToServer(message); // Serverbound } - public static void sendToDimension(SimpleChannel handler, MSG message, ServerLevel dimension) { - handler.sendToClientsInWorld(message, dimension); // Clientbound + public static void sendToDimension(SimpleChannel handler, MSG message, ResourceKey dimension) { + handler.sendToClientsInWorld(message, ServerLifecycleHooks.getCurrentServer().getLevel(dimension)); // Clientbound } } diff --git a/src/main/java/com/aetherteam/nitrogen/network/packet/SyncEntityPacket.java b/src/main/java/com/aetherteam/nitrogen/network/packet/SyncEntityPacket.java index be98542..2853a3f 100644 --- a/src/main/java/com/aetherteam/nitrogen/network/packet/SyncEntityPacket.java +++ b/src/main/java/com/aetherteam/nitrogen/network/packet/SyncEntityPacket.java @@ -1,58 +1,59 @@ package com.aetherteam.nitrogen.network.packet; -//import com.aetherteam.nitrogen.capability.INBTSynchable; -//import net.minecraft.client.Minecraft; -//import net.minecraft.nbt.CompoundTag; -//import net.minecraft.network.FriendlyByteBuf; -//import net.minecraft.world.entity.Entity; -//import net.minecraft.world.entity.player.Player; -//import net.minecraftforge.common.util.LazyOptional; -//import org.apache.commons.lang3.tuple.Triple; -//import oshi.util.tuples.Quartet; -// -///** -// * An abstract packet used by entity capabilities for data syncing. -// */ -//public abstract class SyncEntityPacket> extends SyncPacket { -// private final int entityID; -// -// public SyncEntityPacket(Quartet values) { -// this(values.getA(), values.getB(), values.getC(), values.getD()); -// } -// -// public SyncEntityPacket(int entityID, String key, INBTSynchable.Type type, Object value) { -// super(key, type, value); -// this.entityID = entityID; -// } -// -// @Override -// public void encode(FriendlyByteBuf buf) { -// buf.writeInt(this.entityID); -// super.encode(buf); -// } -// -// public static Quartet decodeEntityValues(FriendlyByteBuf buf) { -// int entityID = buf.readInt(); -// Triple decodeBase = SyncPacket.decodeValues(buf); -// return new Quartet<>(entityID, decodeBase.getLeft(), decodeBase.getMiddle(), decodeBase.getRight()); -// } -// -// @Override -// public void execute(Player playerEntity) { -// if (playerEntity != null && playerEntity.getServer() != null && this.value != null) { -// Entity entity = playerEntity.level().getEntity(this.entityID); -// if (entity != null && !entity.level().isClientSide()) { -// this.getCapability(entity).ifPresent((synchable) -> synchable.getSynchableFunctions().get(this.key).getMiddle().accept(this.value)); -// } -// } else { -// if (Minecraft.getInstance().player != null && Minecraft.getInstance().level != null && this.value != null) { -// Entity entity = Minecraft.getInstance().level.getEntity(this.entityID); -// if (entity != null && entity.level().isClientSide()) { -// this.getCapability(entity).ifPresent((synchable) -> synchable.getSynchableFunctions().get(this.key).getMiddle().accept(this.value)); -// } -// } -// } -// } -// -// public abstract LazyOptional getCapability(Entity entity); -//} +import com.aetherteam.nitrogen.capability.INBTSynchable; +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import org.apache.commons.lang3.tuple.Triple; +import oshi.util.tuples.Quartet; + +import java.util.Optional; + +/** + * An abstract packet used by entity capabilities for data syncing. + */ +public abstract class SyncEntityPacket> extends SyncPacket { + private final int entityID; + + public SyncEntityPacket(Quartet values) { + this(values.getA(), values.getB(), values.getC(), values.getD()); + } + + public SyncEntityPacket(int entityID, String key, INBTSynchable.Type type, Object value) { + super(key, type, value); + this.entityID = entityID; + } + + @Override + public void encode(FriendlyByteBuf buf) { + buf.writeInt(this.entityID); + super.encode(buf); + } + + public static Quartet decodeEntityValues(FriendlyByteBuf buf) { + int entityID = buf.readInt(); + Triple decodeBase = SyncPacket.decodeValues(buf); + return new Quartet<>(entityID, decodeBase.getLeft(), decodeBase.getMiddle(), decodeBase.getRight()); + } + + @Override + public void execute(Player playerEntity) { + if (playerEntity != null && playerEntity.getServer() != null && this.value != null) { + Entity entity = playerEntity.level().getEntity(this.entityID); + if (entity != null && !entity.level().isClientSide()) { + this.getCapability(entity).ifPresent((synchable) -> synchable.getSynchableFunctions().get(this.key).getMiddle().accept(this.value)); + } + } else { + if (Minecraft.getInstance().player != null && Minecraft.getInstance().level != null && this.value != null) { + Entity entity = Minecraft.getInstance().level.getEntity(this.entityID); + if (entity != null && entity.level().isClientSide()) { + this.getCapability(entity).ifPresent((synchable) -> synchable.getSynchableFunctions().get(this.key).getMiddle().accept(this.value)); + } + } + } + } + + public abstract Optional getCapability(Entity entity); +} diff --git a/src/main/java/com/aetherteam/nitrogen/network/packet/SyncLevelPacket.java b/src/main/java/com/aetherteam/nitrogen/network/packet/SyncLevelPacket.java index 05cf339..30147be 100644 --- a/src/main/java/com/aetherteam/nitrogen/network/packet/SyncLevelPacket.java +++ b/src/main/java/com/aetherteam/nitrogen/network/packet/SyncLevelPacket.java @@ -1,36 +1,37 @@ package com.aetherteam.nitrogen.network.packet; -//import com.aetherteam.nitrogen.capability.CapabilityUtil; -//import com.aetherteam.nitrogen.capability.INBTSynchable; -//import net.minecraft.client.Minecraft; -//import net.minecraft.nbt.CompoundTag; -//import net.minecraft.world.entity.player.Player; -//import net.minecraft.world.level.Level; -//import net.minecraftforge.common.util.LazyOptional; -//import org.apache.commons.lang3.tuple.Triple; -// -///** -// * An abstract packet used by level capabilities for data syncing. -// */ -//public abstract class SyncLevelPacket> extends SyncPacket { -// public SyncLevelPacket(Triple values) { -// super(values); -// } -// -// public SyncLevelPacket(String key, INBTSynchable.Type type, Object value) { -// super(key, type, value); -// } -// -// @Override -// public void execute(Player playerEntity) { -// if (playerEntity != null && playerEntity.getServer() != null && this.value != null) { -// CapabilityUtil.syncLevelCapability(this, playerEntity, this.key, this.value, false); -// } else { -// if (Minecraft.getInstance().player != null && Minecraft.getInstance().level != null && this.value != null) { -// CapabilityUtil.syncLevelCapability(this, playerEntity, this.key, this.value, true); -// } -// } -// } -// -// public abstract LazyOptional getCapability(Level level); -//} +import com.aetherteam.nitrogen.capability.CapabilityUtil; +import com.aetherteam.nitrogen.capability.INBTSynchable; +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import org.apache.commons.lang3.tuple.Triple; + +import java.util.Optional; + +/** + * An abstract packet used by level capabilities for data syncing. + */ +public abstract class SyncLevelPacket> extends SyncPacket { + public SyncLevelPacket(Triple values) { + super(values); + } + + public SyncLevelPacket(String key, INBTSynchable.Type type, Object value) { + super(key, type, value); + } + + @Override + public void execute(Player playerEntity) { + if (playerEntity != null && playerEntity.getServer() != null && this.value != null) { + CapabilityUtil.syncLevelCapability(this, playerEntity, this.key, this.value, false); + } else { + if (Minecraft.getInstance().player != null && Minecraft.getInstance().level != null && this.value != null) { + CapabilityUtil.syncLevelCapability(this, playerEntity, this.key, this.value, true); + } + } + } + + public abstract Optional getCapability(Level level); +} diff --git a/src/main/java/com/aetherteam/nitrogen/network/packet/SyncPacket.java b/src/main/java/com/aetherteam/nitrogen/network/packet/SyncPacket.java index 37c6615..418a012 100644 --- a/src/main/java/com/aetherteam/nitrogen/network/packet/SyncPacket.java +++ b/src/main/java/com/aetherteam/nitrogen/network/packet/SyncPacket.java @@ -1,63 +1,63 @@ package com.aetherteam.nitrogen.network.packet; -//import com.aetherteam.nitrogen.capability.INBTSynchable; -//import com.aetherteam.nitrogen.network.BasePacket; -//import net.minecraft.network.FriendlyByteBuf; -//import org.apache.commons.lang3.tuple.Triple; -// -//import java.util.UUID; -// -///** -// * An abstract packet that is extended by other packets that are meant to be used for capability syncing through {@link INBTSynchable}. -// */ -//public abstract class SyncPacket implements BasePacket { -// protected final String key; -// protected final INBTSynchable.Type type; -// protected final Object value; -// -// public SyncPacket(Triple values) { -// this(values.getLeft(), values.getMiddle(), values.getRight()); -// } -// -// public SyncPacket(String key, INBTSynchable.Type type, Object value) { -// this.key = key; -// this.type = type; -// this.value = value; -// } -// -// @Override -// public void encode(FriendlyByteBuf buf) { -// buf.writeUtf(this.key); -// buf.writeInt(this.type.ordinal()); -// if (this.value != null) { -// buf.writeBoolean(true); -// switch (this.type) { -// case INT -> buf.writeInt((int) this.value); -// case FLOAT -> buf.writeFloat((float) this.value); -// case DOUBLE -> buf.writeDouble((double) this.value); -// case BOOLEAN -> buf.writeBoolean((boolean) this.value); -// case UUID -> buf.writeUUID((UUID) this.value); -// } -// } else { -// buf.writeBoolean(false); -// } -// } -// -// public static Triple decodeValues(FriendlyByteBuf buf) { -// String key = buf.readUtf(); -// int typeId = buf.readInt(); -// INBTSynchable.Type type = INBTSynchable.Type.values()[typeId]; -// Object value = null; -// boolean notNull = buf.readBoolean(); -// if (notNull) { -// switch (type) { -// case INT -> value = buf.readInt(); -// case FLOAT -> value = buf.readFloat(); -// case DOUBLE -> value = buf.readDouble(); -// case BOOLEAN -> value = buf.readBoolean(); -// case UUID -> value = buf.readUUID(); -// } -// } -// return Triple.of(key, type, value); -// } -//} +import com.aetherteam.nitrogen.capability.INBTSynchable; +import com.aetherteam.nitrogen.network.BasePacket; +import net.minecraft.network.FriendlyByteBuf; +import org.apache.commons.lang3.tuple.Triple; + +import java.util.UUID; + +/** + * An abstract packet that is extended by other packets that are meant to be used for capability syncing through {@link INBTSynchable}. + */ +public abstract class SyncPacket implements BasePacket { + protected final String key; + protected final INBTSynchable.Type type; + protected final Object value; + + public SyncPacket(Triple values) { + this(values.getLeft(), values.getMiddle(), values.getRight()); + } + + public SyncPacket(String key, INBTSynchable.Type type, Object value) { + this.key = key; + this.type = type; + this.value = value; + } + + @Override + public void encode(FriendlyByteBuf buf) { + buf.writeUtf(this.key); + buf.writeInt(this.type.ordinal()); + if (this.value != null) { + buf.writeBoolean(true); + switch (this.type) { + case INT -> buf.writeInt((int) this.value); + case FLOAT -> buf.writeFloat((float) this.value); + case DOUBLE -> buf.writeDouble((double) this.value); + case BOOLEAN -> buf.writeBoolean((boolean) this.value); + case UUID -> buf.writeUUID((UUID) this.value); + } + } else { + buf.writeBoolean(false); + } + } + + public static Triple decodeValues(FriendlyByteBuf buf) { + String key = buf.readUtf(); + int typeId = buf.readInt(); + INBTSynchable.Type type = INBTSynchable.Type.values()[typeId]; + Object value = null; + boolean notNull = buf.readBoolean(); + if (notNull) { + switch (type) { + case INT -> value = buf.readInt(); + case FLOAT -> value = buf.readFloat(); + case DOUBLE -> value = buf.readDouble(); + case BOOLEAN -> value = buf.readBoolean(); + case UUID -> value = buf.readUUID(); + } + } + return Triple.of(key, type, value); + } +} diff --git a/src/main/java/com/aetherteam/nitrogen/network/packet/clientbound/UpdateUserInfoPacket.java b/src/main/java/com/aetherteam/nitrogen/network/packet/clientbound/UpdateUserInfoPacket.java index 062fe84..d00a11d 100644 --- a/src/main/java/com/aetherteam/nitrogen/network/packet/clientbound/UpdateUserInfoPacket.java +++ b/src/main/java/com/aetherteam/nitrogen/network/packet/clientbound/UpdateUserInfoPacket.java @@ -2,7 +2,7 @@ import com.aetherteam.nitrogen.api.users.User; import com.aetherteam.nitrogen.api.users.UserData; -import com.aetherteam.nitrogen.network.ClientPacket; +import com.aetherteam.nitrogen.network.BasePacket; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.world.entity.player.Player; @@ -10,7 +10,7 @@ /** * Updates the {@link User} on the client. */ -public record UpdateUserInfoPacket(User user) implements ClientPacket { +public record UpdateUserInfoPacket(User user) implements BasePacket { @Override public void encode(FriendlyByteBuf buffer) { User.write(buffer, this.user()); diff --git a/src/main/java/com/aetherteam/nitrogen/network/packet/serverbound/TriggerUpdateInfoPacket.java b/src/main/java/com/aetherteam/nitrogen/network/packet/serverbound/TriggerUpdateInfoPacket.java index e394528..1f79966 100644 --- a/src/main/java/com/aetherteam/nitrogen/network/packet/serverbound/TriggerUpdateInfoPacket.java +++ b/src/main/java/com/aetherteam/nitrogen/network/packet/serverbound/TriggerUpdateInfoPacket.java @@ -1,20 +1,20 @@ package com.aetherteam.nitrogen.network.packet.serverbound; import com.aetherteam.nitrogen.api.users.UserData; -import com.aetherteam.nitrogen.network.ServerPacket; +import com.aetherteam.nitrogen.network.BasePacket; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; - import org.jetbrains.annotations.Nullable; + import java.util.UUID; /** * Triggers the server to query the Patreon database. * @see UserData.Server#sendUserRequest(MinecraftServer, ServerPlayer, UUID) */ -public record TriggerUpdateInfoPacket(int playerID) implements ServerPacket { +public record TriggerUpdateInfoPacket(int playerID) implements BasePacket { @Override public void encode(FriendlyByteBuf buffer) { buffer.writeInt(this.playerID());