From a89b0637a4f8eabec139cdb0e5e7f3817c3ca834 Mon Sep 17 00:00:00 2001 From: MegumiKasuga <1926195023@qq.com> Date: Mon, 25 Mar 2024 23:10:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=83=A8=E5=88=86=20javadoc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kasuga/lib/core/network/C2SPacket.java | 27 +- .../java/kasuga/lib/core/network/Packet.java | 15 +- .../kasuga/lib/core/network/S2CPacket.java | 21 +- .../kasuga/lib/core/util/data_type/Pair.java | 9 + .../java/kasuga/lib/registrations/TagReg.java | 4 - .../registrations/common/BlockEntityReg.java | 81 +++++- .../lib/registrations/common/BlockReg.java | 251 +++++++++++++++--- .../lib/registrations/common/BlockTagReg.java | 11 + .../lib/registrations/common/ChannelReg.java | 133 ++++++++-- .../registrations/common/CreativeTabReg.java | 42 +++ .../lib/registrations/common/EffectReg.java | 67 ++++- .../lib/registrations/common/EntityReg.java | 4 - .../lib/registrations/common/FluidReg.java | 5 + .../lib/registrations/common/RecipeReg.java | 2 +- .../lib/registrations/common/SoundReg.java | 2 +- 15 files changed, 578 insertions(+), 96 deletions(-) diff --git a/src/main/java/kasuga/lib/core/network/C2SPacket.java b/src/main/java/kasuga/lib/core/network/C2SPacket.java index c02f0252..d9839e16 100644 --- a/src/main/java/kasuga/lib/core/network/C2SPacket.java +++ b/src/main/java/kasuga/lib/core/network/C2SPacket.java @@ -1,19 +1,42 @@ package kasuga.lib.core.network; +import kasuga.lib.core.annos.Inner; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; import net.minecraftforge.network.NetworkDirection; import net.minecraftforge.network.NetworkEvent; +/** + * This packet should be sent by logical client and received by logical server. + * It is used for your custom packets that transmit custom data from client to server. + * To register one of this, see {@link kasuga.lib.registrations.common.ChannelReg} + */ public abstract class C2SPacket extends Packet { - public C2SPacket() {super();} - public C2SPacket(FriendlyByteBuf buf) {} + /** + * This function is the deserializer of your packet. + * See {@link Packet} for more constructor info. + * @param buf data bytes you got from the network. + */ + public C2SPacket(FriendlyByteBuf buf) {super(buf);} + + @Inner public boolean onReach(NetworkEvent.Context context) { context.enqueueWork(() -> handle(context)); return true; } + /** + * The handler of your packet. After this packet has been received by + * logical server, we would handle this packet in this method. + * @param context some server info, such level, player and so on. + */ public abstract void handle(NetworkEvent.Context context); + + /** + * The encoder of your packet. You must put all your data into this + * byte buffer in order to transmit them. + * @param buf the data container buffer, push your data into it. + */ abstract public void encode(FriendlyByteBuf buf); } diff --git a/src/main/java/kasuga/lib/core/network/Packet.java b/src/main/java/kasuga/lib/core/network/Packet.java index 23f92ede..00aa87f7 100644 --- a/src/main/java/kasuga/lib/core/network/Packet.java +++ b/src/main/java/kasuga/lib/core/network/Packet.java @@ -1,5 +1,6 @@ package kasuga.lib.core.network; +import kasuga.lib.core.annos.Inner; import net.minecraft.network.FriendlyByteBuf; import net.minecraftforge.network.NetworkEvent; @@ -9,8 +10,20 @@ * For packages from server to client, use {@link S2CPacket} */ public abstract class Packet { - public Packet(){} + + /** + * This constructor is also used as decoder. While the program get data from network, it would + * use this deserializer to create our packet. + * @param buf the bytes we got from network. + */ public Packet(FriendlyByteBuf buf) {} + + @Inner abstract public boolean onReach(NetworkEvent.Context context); + + /** + * The encoder of your packet, you must push all your data into this byte buffer. + * @param buf the data container buffer, push your data into it. + */ abstract public void encode(FriendlyByteBuf buf); } diff --git a/src/main/java/kasuga/lib/core/network/S2CPacket.java b/src/main/java/kasuga/lib/core/network/S2CPacket.java index 33351760..9041b2ef 100644 --- a/src/main/java/kasuga/lib/core/network/S2CPacket.java +++ b/src/main/java/kasuga/lib/core/network/S2CPacket.java @@ -1,19 +1,38 @@ package kasuga.lib.core.network; +import kasuga.lib.core.annos.Inner; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; import net.minecraftforge.network.NetworkEvent; +/** + * This packet should be sent by logical server and received by logical client. + * It is used for your custom packets that transmit custom data from server to client. + * To register one of this, see {@link kasuga.lib.registrations.common.ChannelReg} + */ public abstract class S2CPacket extends Packet { - public S2CPacket() {super();} + /** + * The decoder constructor of your packet. Take all your data out from the byte buffer here. + * @param buf the received byte buffer. + */ public S2CPacket(FriendlyByteBuf buf) {super(buf);} @Override + @Inner public boolean onReach(NetworkEvent.Context context) { context.enqueueWork(() -> handle(Minecraft.getInstance())); return true; } + /** + * The handler of your packet, the packet would be handled here. + * @param minecraft Your minecraft client. + */ public abstract void handle(Minecraft minecraft); + + /** + * Push your data into the byte buffer here. + * @param buf the data container buffer, push your data into it. + */ public abstract void encode(FriendlyByteBuf buf); } diff --git a/src/main/java/kasuga/lib/core/util/data_type/Pair.java b/src/main/java/kasuga/lib/core/util/data_type/Pair.java index 79c7d88c..6658d64f 100644 --- a/src/main/java/kasuga/lib/core/util/data_type/Pair.java +++ b/src/main/java/kasuga/lib/core/util/data_type/Pair.java @@ -1,5 +1,13 @@ package kasuga.lib.core.util.data_type; +import kasuga.lib.core.annos.Util; + +/** + * A simple data struct that contains two elements. + * @param Type of first data. + * @param Type of second data. + */ +@Util public class Pair { K first; V second; @@ -12,6 +20,7 @@ public static Pair of(K first, V second) { return new Pair(first, second); } + public K getFirst() { return first; } diff --git a/src/main/java/kasuga/lib/registrations/TagReg.java b/src/main/java/kasuga/lib/registrations/TagReg.java index f294dbc9..3ce8b444 100644 --- a/src/main/java/kasuga/lib/registrations/TagReg.java +++ b/src/main/java/kasuga/lib/registrations/TagReg.java @@ -23,8 +23,4 @@ public TagReg(String registrationKey) { * @return the location. */ public ResourceLocation location() {return location;} - - public interface TagProvider { - TagKey provide(); - } } diff --git a/src/main/java/kasuga/lib/registrations/common/BlockEntityReg.java b/src/main/java/kasuga/lib/registrations/common/BlockEntityReg.java index 4aad530e..c461cb7c 100644 --- a/src/main/java/kasuga/lib/registrations/common/BlockEntityReg.java +++ b/src/main/java/kasuga/lib/registrations/common/BlockEntityReg.java @@ -10,11 +10,20 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.registries.RegistryObject; import java.util.ArrayList; import java.util.List; +/** + * The registration element of block entity. Block entity is a custom block data container, which makes us can + * customize the block action or renderer. It is spawn and destroy as same as the block's lifecycle. + * If you want to storage your custom data or your custom function, use a block entity. To use a block entity, + * Your block must be a subClass of BaseEntityBlock, See + * {@link net.minecraft.world.level.block.BaseEntityBlock} and {@link BlockEntity} for more info. + * @param the type of blockEntity, + */ public class BlockEntityReg extends Reg { private ArrayList> blockInvokerList; private RegistryObject> registryObject; @@ -22,41 +31,85 @@ public class BlockEntityReg extends Reg { private BlockEntityType.BlockEntitySupplier builder; private BlockEntityRendererBuilder rendererBuilder = null; + /** + * Use this to create a block entity reg. + * @param registrationKey the registration key of your block entity + */ public BlockEntityReg(String registrationKey) { super(registrationKey); blockInvokerList = new ArrayList<>(); } + /** + * The instance supplier of your block entity. It is used to provide a block entity instance for the game. + * @param blockEntity Your Block Entity supplier. + * @return self. + */ @Mandatory public BlockEntityReg blockEntityType(BlockEntityType.BlockEntitySupplier blockEntity) { this.builder =(BlockEntityType.BlockEntitySupplier) blockEntity; return this; } + /** + * Which blocks could have this block entity ? Block Entity would be destroyed if + * there's an invalid block in its block pos. + * @param block The block suppliers. + * @return self. + */ @Optional public BlockEntityReg withBlocks(BlockProvider... block) { blockInvokerList.addAll(List.of(block)); return this; } + /** + * Aaa a block to block entity's valid block list. + * @param block the block supplier. + * @return self + */ @Optional public BlockEntityReg addBlock(BlockProvider block) { this.blockInvokerList.add(block); return this; } + /** + * The block entity may have a block entity renderer. + * Block entity renderer is used for customize block rendering. + * It would only be applied in client side. + * @param builder your block entity renderer supplier. + * @return self. + */ @Optional public BlockEntityReg withRenderer(BlockEntityRendererBuilder builder) { this.rendererBuilder = (BlockEntityRendererBuilder) builder; return this; } + /** + * Other vanilla data you would like to apply to this block entity. + * @param dataType data you would like to give. + * @return self. + */ @Optional public BlockEntityReg dataType(com.mojang.datafixers.types.Type dataType) { this.dataType = dataType; return this; } + /** + * You must call this after your config completed. It would handle your reg to forge and minecraft. + * @param registry the mod SimpleRegistry. + * @return self + */ + @Mandatory + public BlockEntityReg submit(SimpleRegistry registry) { + registryObject = registry.blockEntity() + .register(registrationKey, () -> BlockEntityType.Builder.of(builder, getBlockList()).build(dataType)); + return this; + } + public Block[] getBlockList() { Block[] result = new Block[blockInvokerList.size()]; int counter = 0; @@ -83,28 +136,40 @@ public String getIdentifier() { return "block_entity"; } - - @Mandatory - public BlockEntityReg submit(SimpleRegistry registry) { - registryObject = registry.blockEntity() - .register(registrationKey, () -> BlockEntityType.Builder.of(builder, getBlockList()).build(dataType)); - return this; - } - @Inner public void registerRenderer(SimpleRegistry registry) { if(this.rendererBuilder != null) registry.registerBlockEntityRenderer(() -> registryObject.get(), rendererBuilder); } + /** + * A function interface that provides a block. It is important that you must get your block from an vaild + * registration object like BlockReg in Kasuga Reg or RegistryObject in minecraftforge. + * The game needs blocks that has their own registration data. If you just provide this by calling a new instance + * For example, we could write "() -> exampleBlockReg.instance()" or "exampleBlockReg::get" + * to get this. For more info, see {@link BlockReg#instance()} and {@link RegistryObject#get()} + * @param Type of your block. + */ public interface BlockProvider { T provide(); } + /** + * A function interface that provides a bLock entity. It is a initializer of your block entity. Pass a + * constructor method in this, like "ExampleBlockEntity::new" or "() -> new ExampleBlockEntity()". + * @param Type of your block entity. + */ public interface BlockEntityProvider { BlockEntityType provide(); } + /** + * A function interface that provides a block entity renderer. If you want to use a block entity renderer on your block and + * block entity, you should first override the {@link Block#getRenderShape(BlockState)} method under your block class. + * Then, pass a block entity renderer builder into {@link BlockEntityReg#withRenderer(BlockEntityRendererBuilder)} method. + * The lib would deal with it for you. + * @param the block entity your renderer belongs to. + */ public interface BlockEntityRendererBuilder { BlockEntityRenderer build(BlockEntityRendererProvider.Context context); } diff --git a/src/main/java/kasuga/lib/registrations/common/BlockReg.java b/src/main/java/kasuga/lib/registrations/common/BlockReg.java index 3e7b6201..7a2334e2 100644 --- a/src/main/java/kasuga/lib/registrations/common/BlockReg.java +++ b/src/main/java/kasuga/lib/registrations/common/BlockReg.java @@ -1,5 +1,9 @@ package kasuga.lib.registrations.common; +import kasuga.lib.core.annos.Beta; +import kasuga.lib.core.annos.Inner; +import kasuga.lib.core.annos.Mandatory; +import kasuga.lib.core.annos.Optional; import kasuga.lib.registrations.Reg; import kasuga.lib.registrations.registry.SimpleRegistry; import net.minecraft.client.gui.screens.MenuScreens; @@ -23,9 +27,18 @@ import java.util.ArrayList; import java.util.List; + +/** + * Block is the base element of the game. You would bind your block with item, block entity, + * block entity renderer or menus easily with this reg. See {@link BlockEntityReg} for more info + * about block entity registration, {@link MenuReg} for more info about menu reg, {@link ItemReg} + * for more info about item reg. See {@link Block} about minecraft blocks. + * @param Class of your block. + */ public class BlockReg extends Reg { private Material material = Material.AIR; private MaterialColor color = MaterialColor.NONE; + public BlockBehaviour.Properties properties = BlockBehaviour.Properties.of(Material.AIR); private BlockBuilder builder; private ItemReg itemReg = null; @@ -35,46 +48,105 @@ public class BlockReg extends Reg { private RegistryObject registryObject; private final List> tags; + /** + * Use this to create a BlockReg. + * @param registrationKey your block registration key. + */ public BlockReg(String registrationKey) { super(registrationKey); this.tags = new ArrayList<>(); } + /** + * Material controls what color the block would display on your map. + * @param material The material you want to apply. + * @return self. + */ + @Mandatory public BlockReg material(Material material) { this.material = material; return this; } + /** + * Meterial color also controls what color the block would display on your map. + * @param color The color your block would have on the map. + * @return self. + */ + @Mandatory + public BlockReg materialColor(MaterialColor color) { + this.color = color; + return this; + } + + /** + * The initializer of your block. You should pass a block constructor function into this. For example write + * "ExampleBlock::new" or "prop -> new ExampleBlock(prop)" in this method. + * @param builder initializer of your block. + * @return self. + */ + @Mandatory public BlockReg blockType(BlockBuilder builder) { this.builder = builder; return this; } + /** + * Generate a default item for your block. + * @param modelLocation your item model location, if your item's model is just under the namespace:models/item/ + * folder, you could pass null into this or use the method {@link BlockReg#defaultBlockItem()} + * below. While the model lies in the other place under your model folder, pass a valid resource + * location here. + * @return self. + */ + @Optional public BlockReg defaultBlockItem(ResourceLocation modelLocation) { this.itemReg = ItemReg.defaultBlockItem(this, modelLocation); return this; } + /** + * Generate a default item for your block. + * @return self. + */ + @Optional public BlockReg defaultBlockItem() { this.itemReg = ItemReg.defaultBlockItem(this); return this; } - public BlockReg materialColor(MaterialColor color) { - this.color = color; - return this; - } - + /** + * Add other custom property to your block. + * @param identifier A function interface that provides the block property to you, you could apply your custom + * config to the property in tha lambda. + * @return self. + */ + @Optional public BlockReg addProperty(PropertyIdentifier identifier) { this.identifier = identifier; return this; } + /** + * The game would play this sound when it is broken by any source. + * @param sound the breaking sound. + * @return self + */ + @Optional public BlockReg withSound(SoundType sound) { this.properties.sound(sound); return this; } + /** + * Provide a block entity for the block. If you want your block to spawn a block entity, it must be a subClass of + * BaseEntityBlock, see {@link net.minecraft.world.level.block.BaseEntityBlock}. + * @param beRegistrationKey your block entity reg name. + * @param supplier Your block entity initializer. + * @return self. + * @param Type of your block entity. + */ + @Optional public BlockReg withBlockEntity(String beRegistrationKey, BlockEntityType.BlockEntitySupplier supplier) { this.blockEntityReg = new BlockEntityReg(beRegistrationKey) .blockEntityType(supplier) @@ -82,16 +154,42 @@ public BlockReg withBlockEntity(String beRegistration return this; } + /** + * Provide a block entity for your block. + * @param blockEntityReg registration of your block entity. + * @return self. + */ + @Optional public BlockReg withBlockEntity(BlockEntityReg blockEntityReg) { this.blockEntityReg = blockEntityReg.addBlock(() -> this.registryObject.get()); return this; } + /** + * Provide a block entity renderer for your block entity (only if you have a block entity in this registration.) + * To use this, make sure your block is a subClass of {@link net.minecraft.world.MenuProvider} + * @param builder Your block entity renderer provider. + * @return self. + */ + @Optional public BlockReg withBlockEntityRenderer(BlockEntityReg.BlockEntityRendererBuilder builder) { + if (blockEntityReg == null) return this; blockEntityReg.withRenderer(builder); return this; } + /** + * Provide a menu for your block. Menus (and screens) are used for GUIs. + * To use this, make sure your block is a subClass of {@link net.minecraft.world.MenuProvider} + * @param registrationKey the registration key of your menu. + * @param menu the constructor function of your menu. + * @param screen the constructor function of your screen. + * @return self. + * @param your menu class. + * @param your screen class. + * @param your screen class. + */ + @Optional public > BlockReg withMenu(String registrationKey, IContainerFactory menu, MenuScreens.ScreenConstructor screen) { menuReg = new MenuReg(registrationKey) @@ -99,90 +197,146 @@ public BlockReg withBlockEntityRenderer(BlockEntityReg.BlockEntityRendererBui return this; } + /** + * Provide a menu for your block. See {@link MenuReg} for more info. To use this, make sure that your block + * is a subClass of {@link net.minecraft.world.MenuProvider} + * @param menuReg your menu registration. + * @return self. + */ + @Optional public BlockReg withMenu(MenuReg menuReg) { this.menuReg = menuReg; return this; } + /** + * Provide a menu for your item (only if you have a item registration). + * To use this, make sure your item is a subClass of {@link net.minecraft.world.MenuProvider} + * @param registrationKey the registration key of your menu. + * @param menu your menu initializer. + * @param screen your screen initializer. + * @return self. + * @param Your menu class. + * @param Your screen class. + * @param Your screen class. + */ + @Optional public > BlockReg withItemMenu(String registrationKey, IContainerFactory menu, MenuScreens.ScreenConstructor screen) { + if (itemReg == null) return this; itemReg.withMenu(registrationKey, menu, screen); return this; } + /** + * Provide a menu for your item (only if you ha a item registration). + * To use this, make sure your item is a subClass of {@link net.minecraft.world.MenuProvider} + * @param menuReg the menu you would apply. + * @return self. + */ + @Optional public BlockReg withItemMenu(MenuReg menuReg) { + if (itemReg == null) return this; itemReg.withMenu(menuReg); return this; } + /** + * Provide a item for your block. The item you provide must be a subClass of {@link net.minecraft.world.item.BlockItem} + * Player could use this item to place your block down. + * @param builder your item provider. + * @param itemModelLocation your item model location, if your item's model is just under the namespace:models/item/ + * folder, you could pass null into this or use the method {@link BlockReg#defaultBlockItem()} + * below. While the model lies in the other place under your model folder, pass a valid resource + * location here. + * @return self. + * @param the item class. + */ + @Optional public BlockReg withItem(ItemReg.ItemBuilder builder, ResourceLocation itemModelLocation) { itemReg = new ItemReg(registrationKey, itemModelLocation); itemReg.itemType(builder); return this; } + /** + * Is your item renderer by your custom renderer? If you want to create a custom rendered item, see + * {@link kasuga.lib.core.base.CustomRenderedItem} + * @param flag should your item be custom rendered. + * @return self. + */ + @Optional public BlockReg shouldCustomRenderItem(boolean flag) { itemReg.shouldCustomRender(flag); return this; } + /** + * Apply custom property to your block item(only if there's a item reg) + * @param identifier pass your custom item config here. + * @return self. + */ + @Optional public BlockReg itemProperty(ItemReg.PropertyIdentifier identifier) { itemReg = itemReg.withProperty(identifier); return this; } + + /** + * Your block item would stack to this tab, + * @param tab The tab you'd like to put your item in. + * @return self. + */ + @Optional public BlockReg tabTo(CreativeModeTab tab) { if(itemReg != null) itemReg.tab(tab); return this; } + /** + * Your block item would stack to this tab. + * @param reg The tab you'd like to put your item in. + * @return self. + */ + @Optional public BlockReg tabTo(CreativeTabReg reg) { if(itemReg != null) itemReg.tab(reg); return this; } + /** + * Set the max stack size of your block item. + * @param size max stack size. + * @return self. + */ + @Optional public BlockReg stackSize(int size) { if(itemReg != null) itemReg.stackTo(size); return this; } + /** + * Apply block tags to your block. + * @param tag block tag. + * @return self. + */ + @Optional public BlockReg withTags(TagKey tag) { this.tags.add(tag); return this; } - public ItemReg getItemReg() { - return itemReg; - } - - public MenuReg getMenuReg() { - return menuReg; - } - - public BlockEntityReg getBlockEntityReg() { - return blockEntityReg; - } - - private void initProperties() { - properties = BlockBehaviour.Properties.of(material, color); - if(identifier != null) identifier.apply(properties); - } - - public RegistryObject getRegistryObject() { - return registryObject; - } - - public T getBlock() { - return registryObject == null ? null : registryObject.get(); - } - - public String getIdentifier() { - return "block"; - } - + /** + * Call this after all config has been applied. + * @param registry the mod SimpleRegistry. + * @return self. + */ + @Mandatory + @Override public BlockReg submit(SimpleRegistry registry) { initProperties(); registryObject = registry.block().register(registrationKey, () -> builder.build(properties)); @@ -203,6 +357,18 @@ public BlockReg submit(SimpleRegistry registry) { return this; } + public ItemReg getItemReg() { + return itemReg; + } + + public MenuReg getMenuReg() { + return menuReg; + } + + public BlockEntityReg getBlockEntityReg() { + return blockEntityReg; + } + public T instance() { return registryObject == null ? null : registryObject.get(); } @@ -211,6 +377,23 @@ public Item itemInstance() { return itemReg != null ? itemReg.getItem() : null; } + public RegistryObject getRegistryObject() { + return registryObject; + } + + public T getBlock() { + return registryObject == null ? null : registryObject.get(); + } + public String getIdentifier() { + return "block"; + } + + @Inner + private void initProperties() { + properties = BlockBehaviour.Properties.of(material, color); + if(identifier != null) identifier.apply(properties); + } + public interface PropertyIdentifier { void apply(BlockBehaviour.Properties properties); } diff --git a/src/main/java/kasuga/lib/registrations/common/BlockTagReg.java b/src/main/java/kasuga/lib/registrations/common/BlockTagReg.java index 209fca1c..64ff7e90 100644 --- a/src/main/java/kasuga/lib/registrations/common/BlockTagReg.java +++ b/src/main/java/kasuga/lib/registrations/common/BlockTagReg.java @@ -1,5 +1,6 @@ package kasuga.lib.registrations.common; +import kasuga.lib.core.annos.Mandatory; import kasuga.lib.registrations.registry.SimpleRegistry; import kasuga.lib.registrations.TagReg; import net.minecraft.resources.ResourceLocation; @@ -8,16 +9,26 @@ import net.minecraft.world.level.block.Block; import org.jetbrains.annotations.Nullable; +/** + * BlockTag is a static attribute of a block. For example minecraft:stone or minecraft:sand tag. + * It marks a block and groups different blocks. See {@link TagKey}. + */ public class BlockTagReg extends TagReg { TagKey tag = null; private final String path; + /** + * Use this to create a new block tag registration. + * @param registrationKey the name of your tag key. + * @param path the path of your tag file. Root folder is namespace:tag (It's usually under the "resource/data" folder) + */ public BlockTagReg(String registrationKey, String path) { super(registrationKey); this.path = path; } @Override + @Mandatory public BlockTagReg submit(SimpleRegistry registry) { location = new ResourceLocation(registry.namespace, path); tag = BlockTags.create(location); diff --git a/src/main/java/kasuga/lib/registrations/common/ChannelReg.java b/src/main/java/kasuga/lib/registrations/common/ChannelReg.java index 9add08b5..78622567 100644 --- a/src/main/java/kasuga/lib/registrations/common/ChannelReg.java +++ b/src/main/java/kasuga/lib/registrations/common/ChannelReg.java @@ -1,5 +1,8 @@ package kasuga.lib.registrations.common; +import kasuga.lib.core.annos.Inner; +import kasuga.lib.core.annos.Mandatory; +import kasuga.lib.core.annos.Optional; import kasuga.lib.core.network.C2SPacket; import kasuga.lib.core.network.Packet; import kasuga.lib.core.network.S2CPacket; @@ -22,33 +25,89 @@ import java.util.function.Function; import java.util.function.Predicate; +/** + * Channel is used for network packages. If you have some custom data need to be transmitted between + * Logical Client and Logical Server, for more info about Logical Side, see {@link net.minecraftforge.fml.LogicalSide} + * After registration, You could use this channel to transmit your packets. + * For packets from client to server, see {@link C2SPacket}. + * For packets from server to client, see {@link S2CPacket} + */ public class ChannelReg extends Reg { private SimpleChannel channel = null; private String brand = registrationKey; private int id = 0; - private final HashSet> packetBuilders; + private final HashSet> packetBuilders; Predicate clientVersions = ((input) -> true), serverVersions = ((input) -> true); + + /** + * Create a registry. + * @param registrationKey name of your channel reg. + */ public ChannelReg(String registrationKey) { super(registrationKey); this.packetBuilders = new HashSet<>(); } + /** + * Your channel's version. + * @param brand version. + * @return self. + */ + @Mandatory + public ChannelReg brand(String brand) { + this.brand = brand; + return this; + } + + /** + * Pass a predicate method here. Different player may use different version of your mod in multiplayer. + * The game would use this function to examine different versions of your packet. + * If this method return false, the game will reject the packet. + * @param clientVersions the predicate method. Usually a lambda, just return True in default. + * @return self. + */ + @Optional public ChannelReg clientVersions(@Nonnull Predicate clientVersions) { this.clientVersions = Objects.requireNonNull(clientVersions); return this; } + /** + * Pass a predicate method here. Different player may use different version of your mod in multiplayer. + * The game would use this function to examine different versions of your packet. + * If this method return false, the game will reject the packet. + * @param serverVersions the predicate method. Usually a lambda, just return True in default. + * @return self. + */ + @Optional public ChannelReg serverVersions(@Nonnull Predicate serverVersions) { this.serverVersions = Objects.requireNonNull(serverVersions); return this; } - public ChannelReg brand(String brand) { - this.brand = brand; + /** + * Register a packet into this channel. Client to server packet, see {@link C2SPacket}, + * server to client packet, see {@link S2CPacket} + * @param packetClass Class of your packet. + * @param decoder The decoder method of your packet. + * @return self. + */ + @Optional + public ChannelReg loadPacket(Class packetClass, Function decoder) { + boolean flag0 = C2SPacket.class.isAssignableFrom(packetClass); + boolean flag1 = S2CPacket.class.isAssignableFrom(packetClass); + if(!flag0 && !flag1) return this; + loadPacket(Pair.of(packetClass, decoder)); return this; } + /** + * Submit your registration to forge and minecraft. + * @param registry the mod SimpleRegistry. + * @return self. + */ @Override + @Mandatory public ChannelReg submit(SimpleRegistry registry) { channel = NetworkRegistry.newSimpleChannel( new ResourceLocation(registry.namespace, registrationKey), @@ -65,53 +124,57 @@ public ChannelReg submit(SimpleRegistry registry) { return this; } - public ChannelReg loadPacket(Pair, Function> pair) { - if(channel == null) { - packetBuilders.add(() -> loadPacket(pair)); - } else { - channel.messageBuilder((Class) pair.getFirst(), id) - .encoder(Packet::encode) - .decoder((Function) pair.getSecond()) - .consumerNetworkThread((first, second) -> (first.onReach(second.get()) || false)) - .add(); - } - return this; - } - - public ChannelReg loadPacket(Class packetClass, Function decoder) { - boolean flag0 = C2SPacket.class.isAssignableFrom(packetClass); - boolean flag1 = S2CPacket.class.isAssignableFrom(packetClass); - if(!flag0 && !flag1) return this; - loadPacket(Pair.of(packetClass, decoder)); - return this; - } - public SimpleChannel getChannel() { return channel; } - // Client Only + /** + * You could use this method only in the logical client. Use this to send a {@link C2SPacket} to the server. + * @param msg Your packet. + */ public void sendToServer(C2SPacket msg) { if(channel == null) return; channel.sendToServer(msg); } + /** + * Send your packet to specific side via given connection. + * @param msg Your packet + * @param connection The connection you use. + * @param direction The network direction to send to. + */ public void sendTo(Packet msg, Connection connection, NetworkDirection direction) { if(channel == null) return; channel.sendTo(msg, connection, direction); } - // Server Only + /** + * You could only use this method in the logical server. Send your {@link S2CPacket} from the server + * to a client. + * @param msg your packet. + * @param connection Connection you use. + */ public void sendToClient(S2CPacket msg, Connection connection) { channel.sendTo(msg, connection, NetworkDirection.PLAY_TO_CLIENT); } - // Server Only + /** + * You could only use this method in the logical server. Send your {@link S2CPacket} from the server + * to a single player's client. + * @param msg your packet. + * @param player player you would send. + */ public void sendToClient(S2CPacket msg, ServerPlayer player) { sendToClient(msg, player.connection.getConnection()); } - // Server Only + /** + * You could only use this method in the logical server. Send your {@link S2CPacket} from the server + * to all connected client. + * @param msg your packet. + * @param level The server level. + * @param pos the block pos you sent this packet. + */ public void boardcastToClients(S2CPacket msg, ServerLevel level, BlockPos pos) { level.getChunkSource().chunkMap.getPlayers(level.getChunk(pos).getPos(), false) .forEach(player -> sendToClient(msg, player)); @@ -122,6 +185,20 @@ public String getIdentifier() { return "channel"; } + @Inner + private ChannelReg loadPacket(Pair, Function> pair) { + if(channel == null) { + packetBuilders.add(() -> loadPacket(pair)); + } else { + channel.messageBuilder((Class) pair.getFirst(), id) + .encoder(Packet::encode) + .decoder((Function) pair.getSecond()) + .consumerNetworkThread((first, second) -> (first.onReach(second.get()) || false)) + .add(); + } + return this; + } + interface PacketBuilder { void build(); } diff --git a/src/main/java/kasuga/lib/registrations/common/CreativeTabReg.java b/src/main/java/kasuga/lib/registrations/common/CreativeTabReg.java index ab267200..3a20efc6 100644 --- a/src/main/java/kasuga/lib/registrations/common/CreativeTabReg.java +++ b/src/main/java/kasuga/lib/registrations/common/CreativeTabReg.java @@ -1,37 +1,79 @@ package kasuga.lib.registrations.common; +import kasuga.lib.core.annos.Mandatory; import kasuga.lib.core.base.SimpleCreativeTab; import kasuga.lib.registrations.Reg; import kasuga.lib.registrations.registry.SimpleRegistry; +import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraftforge.registries.RegistryObject; import java.util.function.Supplier; +/** + * This is the registration for the creative mode tab. We firmly suggest that you should use this to register + * your creative tab because the minecraft tab reg would be changed violently in 1.19.3. If you use the original + * minecraft registration, it would be a big trouble for you to deal with your items with their tabs. + * If you use this to create your tab, call {@link ItemReg#tab(CreativeTabReg)}, {@link BlockReg#tabTo(CreativeTabReg)} + * or {@link FluidReg#tab(CreativeTabReg)} to register your item to this tab. This reg would create an + * {@link SimpleCreativeTab} instance for you. + */ public class CreativeTabReg extends Reg { public SimpleCreativeTab tab = null; public Supplier iconSupplier = null; + + /** + * Use this to create your tab registration. + * @param registrationKey the name or translation key of your tab. + */ public CreativeTabReg(String registrationKey) { super(registrationKey); } + /** + * Pass an ItemStack in to use it as your tab's icon. + * If the item has an itemReg, use that reg with {@link CreativeTabReg#icon(ItemReg)} + * @param icon the icon itemStack. + * @return self. + */ + @Mandatory public CreativeTabReg icon(Supplier icon) { iconSupplier = icon; return this; } + /** + * Pass an itemStack in to use it as your tab's icon. + * If your item is registered in other way, use {@link CreativeTabReg#icon(Supplier)} + * @param reg the item registration. + * @return self. + */ + @Mandatory public CreativeTabReg icon(ItemReg reg) { iconSupplier = () -> new ItemStack(reg.getItem()); return this; } + /** + * If your icon is registered from original forge registry, use this method to use it as icon. + * For other usage, see {@link CreativeTabReg#icon(Supplier)} or {@link CreativeTabReg#icon(ItemReg)} + * @param itemRegistry the registry object of your item. + * @return self. + */ + @Mandatory public CreativeTabReg icon(RegistryObject itemRegistry) { iconSupplier = () -> new ItemStack(itemRegistry.get()); return this; } + /** + * Pass your configs to forge and minecraft registry. + * @param registry the mod SimpleRegistry. + * @return self. + */ @Override + @Mandatory public CreativeTabReg submit(SimpleRegistry registry) { tab = new SimpleCreativeTab(registrationKey, iconSupplier); registry.tab().put(registrationKey, tab); diff --git a/src/main/java/kasuga/lib/registrations/common/EffectReg.java b/src/main/java/kasuga/lib/registrations/common/EffectReg.java index b2570dcc..8fd5ccaa 100644 --- a/src/main/java/kasuga/lib/registrations/common/EffectReg.java +++ b/src/main/java/kasuga/lib/registrations/common/EffectReg.java @@ -1,5 +1,7 @@ package kasuga.lib.registrations.common; +import kasuga.lib.core.annos.Mandatory; +import kasuga.lib.core.annos.Optional; import kasuga.lib.registrations.Reg; import kasuga.lib.registrations.registry.SimpleRegistry; import net.minecraft.world.effect.MobEffect; @@ -9,40 +11,76 @@ import javax.annotation.Nonnull; import java.util.Objects; +/** + * This registration is used for poison effect registration. You could register your custom poison effect with it. + * @param The poison effect class. + */ public class EffectReg extends Reg { private MobEffectCategory category = MobEffectCategory.NEUTRAL; private RegistryObject registryObject = null; private EffectBuilder builder = null; private int color = 0xffffff; - public String getIdentifier() { - return "effect"; - } - + /** + * Use this to create a poison effect reg. + * @param registrationKey The registration key of your poison effect. + */ public EffectReg(String registrationKey) { super(registrationKey); } - public EffectReg category(MobEffectCategory category) { - this.category = category; + /** + * The constructor lambda of your poison effect. + * @param builder constructor lambda. + * @return self + */ + @Mandatory + public EffectReg effectType(@Nonnull EffectBuilder builder) { + this.builder = (EffectBuilder) builder; return this; } - public EffectReg color(int integerColor) { - this.color = integerColor; + /** + * The type of your effect. It's an enum with 3 values : BENEFICIAL, HARMFUL and NEUTRAL. + * see {@link MobEffectCategory} for more info. + * @param category the type of your effect. + * @return self. + */ + @Mandatory + public EffectReg category(MobEffectCategory category) { + this.category = category; return this; } - public EffectReg effectType(@Nonnull EffectBuilder builder) { - this.builder = (EffectBuilder) builder; + /** + * The color of your effect's particles. 0xffffff (white) in default. + * @param r red (0-255). + * @param g green (0-255). + * @param b blue (0-255). + * @return self. + */ + @Optional + public EffectReg color(int r, int g, int b) { + this.color = r * 256 * 256 + g * 256 + b; return this; } - public EffectReg color(int r, int g, int b) { - this.color = r * 256 * 256 + g * 256 + b; + /** + * The color of your effect's particles. 0xffffff (white) in default. + * @param integerColor the color value (0x000000 - 0xffffff) + * @return self. + */ + @Optional + public EffectReg color(int integerColor) { + this.color = integerColor; return this; } + /** + * Submit your config to forge and minecraft. + * @param registry the mod SimpleRegistry. + * @return self. + */ @Override public Reg submit(SimpleRegistry registry) { Objects.requireNonNull(builder); @@ -66,6 +104,11 @@ public int getThemeColor() { return color; } + public String getIdentifier() { + return "effect"; + } + + public interface EffectBuilder { T build(MobEffectCategory category, int color); } diff --git a/src/main/java/kasuga/lib/registrations/common/EntityReg.java b/src/main/java/kasuga/lib/registrations/common/EntityReg.java index c5031bf6..e8293f6a 100644 --- a/src/main/java/kasuga/lib/registrations/common/EntityReg.java +++ b/src/main/java/kasuga/lib/registrations/common/EntityReg.java @@ -97,8 +97,4 @@ public interface EntityPropertyIdentifier { public interface EntityAttributeBuilder { AttributeSupplier.Builder get(); } - - public interface byRegistryObjectGetter> { - T get(); - } } diff --git a/src/main/java/kasuga/lib/registrations/common/FluidReg.java b/src/main/java/kasuga/lib/registrations/common/FluidReg.java index 5bbaaca6..9f01fa0a 100644 --- a/src/main/java/kasuga/lib/registrations/common/FluidReg.java +++ b/src/main/java/kasuga/lib/registrations/common/FluidReg.java @@ -99,6 +99,11 @@ public FluidReg tab(CreativeModeTab tab) { return this; } + public FluidReg tab(CreativeTabReg reg) { + itemProperties.tab(reg.getTab()); + return this; + } + public FluidReg stacksTo(int size) { itemProperties.stacksTo(size); return this; diff --git a/src/main/java/kasuga/lib/registrations/common/RecipeReg.java b/src/main/java/kasuga/lib/registrations/common/RecipeReg.java index d6f4521d..e9b5e56e 100644 --- a/src/main/java/kasuga/lib/registrations/common/RecipeReg.java +++ b/src/main/java/kasuga/lib/registrations/common/RecipeReg.java @@ -41,7 +41,7 @@ public RecipeType getRecipeType() { @Override - public Reg submit(SimpleRegistry registry) { + public RecipeReg submit(SimpleRegistry registry) { this.recipeRegistryObject = registry.recipe().register(registrationKey, () -> new RecipeType() { @Override public String toString() {return registrationKey;} diff --git a/src/main/java/kasuga/lib/registrations/common/SoundReg.java b/src/main/java/kasuga/lib/registrations/common/SoundReg.java index 886a1ae3..692e9d54 100644 --- a/src/main/java/kasuga/lib/registrations/common/SoundReg.java +++ b/src/main/java/kasuga/lib/registrations/common/SoundReg.java @@ -17,7 +17,7 @@ public SoundReg(String registrationKey, @Nonnull ResourceLocation soundFileLocat } @Override - public Reg submit(SimpleRegistry registry) { + public SoundReg submit(SimpleRegistry registry) { registryObject = registry.sound().register(registrationKey, () -> new SoundEvent(soundFile)); return this; }