Last 1.18 initial work. Getting ready for 1.19

This commit is contained in:
2022-06-10 18:58:26 +02:00
parent a49903cc69
commit 94e13cc65d
35 changed files with 639 additions and 97 deletions

View File

@@ -4,7 +4,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Constants {
public static final String MOD_ID = "craterlib";
public static final String MOD_NAME = "CraterLib";
public static final Logger LOG = LogManager.getLogger(MOD_NAME);
public static final String MOD_ID = "craterlib";
public static final String MOD_NAME = "CraterLib";
public static final Logger LOG = LogManager.getLogger(MOD_NAME);
}

View File

@@ -5,9 +5,29 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
/**
* Helper Interface for BlockEntities that tick both Client and Server Side
*/
public interface ISidedTickable {
/**
* Server Tick Event
*
* @param level
* @param pos
* @param state
* @param blockEntity
*/
public void serverTick(Level level, BlockPos pos, BlockState state, BlockEntity blockEntity);
/**
* Client Tick Event
*
* @param level
* @param pos
* @param state
* @param blockEntity
*/
public void clientTick(Level level, BlockPos pos, BlockState state, BlockEntity blockEntity);
}

View File

@@ -5,8 +5,19 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
/**
* Helper Interface for BlockEntities that only tick on a single side
*/
public interface ITickable {
/**
* The Tick Event. Can be either Server or Client Sided
*
* @param level
* @param pos
* @param state
* @param blockEntity
*/
public void tick(Level level, BlockPos pos, BlockState state, BlockEntity blockEntity);
}

View File

@@ -1,9 +1,17 @@
package me.hypherionmc.craterlib.api.rendering;
import net.minecraft.client.renderer.entity.layers.RenderLayer;
import net.minecraft.client.renderer.RenderType;
/**
* Helper Interface for defining Block render types
*/
public interface CustomRenderType {
RenderLayer getCustomRenderType();
/**
* Get the render type of the block
*
* @return
*/
RenderType getCustomRenderType();
}

View File

@@ -1,12 +1,25 @@
package me.hypherionmc.craterlib.api.rendering;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.color.block.BlockColor;
import net.minecraft.world.item.DyeColor;
/**
* Helper Interface for Dyable Blocks
*/
public interface DyableBlock {
BlockColors dyeHandler();
/**
* Get the BlockColor handler for the block
*
* @return
*/
BlockColor dyeHandler();
/**
* Get the default Dye Color for Un-dyed states
*
* @return
*/
DyeColor defaultDyeColor();
}

View File

@@ -2,8 +2,16 @@ package me.hypherionmc.craterlib.api.rendering;
import net.minecraft.world.item.DyeColor;
/**
* Helper Interface for Dyable Items
*/
public interface ItemDyable {
/**
* Get the DyeColor of the Item
*
* @return
*/
public DyeColor getColor();
}

View File

@@ -4,6 +4,9 @@ import net.minecraft.client.gui.components.AbstractSliderButton;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
/**
* A custom slider widget used for Time. Mostly used by the Hyper Lighting Smoke Machine
*/
public class TimeSliderWidget extends AbstractSliderButton {
private final double maxValue;

View File

@@ -0,0 +1,45 @@
package me.hypherionmc.craterlib.client.registry;
import me.hypherionmc.craterlib.api.rendering.DyableBlock;
import me.hypherionmc.craterlib.api.rendering.ItemDyable;
import me.hypherionmc.craterlib.client.rendering.ItemColorHandler;
import me.hypherionmc.craterlib.systems.reg.RegistrationProvider;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.color.item.ItemColors;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
/**
* Helper for registering Block and Item color handlers
*/
public class ClientRegistry {
/**
* Register Block Color Handlers
*
* @param colors
* @param blocks
*/
public static void registerBlockColors(BlockColors colors, RegistrationProvider<Block> blocks) {
blocks.getEntries().forEach(blockRegistryObject -> {
if (blockRegistryObject.get() instanceof DyableBlock dyableBlock) {
colors.register(dyableBlock.dyeHandler(), (Block) dyableBlock);
}
});
}
/**
* Register Item Color Handlers
*
* @param colors
* @param items
*/
public static void registerItemColors(ItemColors colors, RegistrationProvider<Item> items) {
items.getEntries().forEach(itemRegistryObject -> {
if (itemRegistryObject.get() instanceof ItemDyable itemDyable) {
colors.register(new ItemColorHandler(), (Item) itemDyable);
}
});
}
}

View File

@@ -1,18 +1,31 @@
package me.hypherionmc.craterlib.client.rendering;
import me.hypherionmc.craterlib.api.rendering.DyableBlock;
import me.hypherionmc.craterlib.api.rendering.ItemDyable;
import me.hypherionmc.craterlib.common.item.BlockItemDyable;
import net.minecraft.client.color.item.ItemColors;
import net.minecraft.client.color.item.ItemColor;
import net.minecraft.world.item.ItemStack;
public class ItemColorHandler extends ItemColors {
/**
* Helper Class for Dyable Items implementing a simple color handler
*/
public class ItemColorHandler implements ItemColor {
/***
* Get the color for the Item/ItemStack
* @param stack
* @param tintIndex
* @return
*/
@Override
public int getColor(ItemStack stack, int tintIndex) {
return this.getColorFromStack(stack);
}
/**
* Get the color for the specific items stack, or return BLACK (0)
*
* @param stack
* @return
*/
private int getColorFromStack(ItemStack stack) {
if (stack.getItem() instanceof ItemDyable itemDyable) {
return itemDyable.getColor().getMaterialColor().col;

View File

@@ -0,0 +1,42 @@
package me.hypherionmc.craterlib.common.config;
import me.hypherionmc.craterlib.Constants;
import me.hypherionmc.nightconfig.core.file.FileWatcher;
import java.io.Serializable;
import java.util.HashMap;
/**
* Controls Config File Reloads and Events
*/
public class ConfigController implements Serializable {
/**
* Cache of registered configs
*/
private static final HashMap<Object, FileWatcher> monitoredConfigs = new HashMap<>();
/**
* INTERNAL METHOD - Register and watch the config
*
* @param config - The config class to register and watch
*/
static void register_config(ModuleConfig config) {
if (monitoredConfigs.containsKey(config)) {
Constants.LOG.error("Failed to register " + config.getConfigPath().getName() + ". Config already registered");
} else {
FileWatcher configWatcher = new FileWatcher();
try {
configWatcher.setWatch(config.getConfigPath(), () -> {
Constants.LOG.info("Sending Reload Event for: " + config.getConfigPath().getName());
config.configReloaded();
});
} catch (Exception e) {
Constants.LOG.error("Failed to register " + config.getConfigPath().getName() + " for auto reloading. " + e.getMessage());
}
monitoredConfigs.put(config, configWatcher);
Constants.LOG.info("Registered " + config.getConfigPath().getName() + " successfully!");
}
}
}

View File

@@ -0,0 +1,147 @@
package me.hypherionmc.craterlib.common.config;
import me.hypherionmc.nightconfig.core.CommentedConfig;
import me.hypherionmc.nightconfig.core.Config;
import me.hypherionmc.nightconfig.core.conversion.ObjectConverter;
import me.hypherionmc.nightconfig.core.file.CommentedFileConfig;
import java.io.File;
/**
* Base Config class containing the save, upgrading and loading logic. All config classes must extend this class
*/
public class ModuleConfig {
/* Final Variables */
private final transient File configPath;
private final transient String networkID;
/**
* Set up the config
*
* @param modId - The ID of the Mod/Module the config belongs to
* @param configName - The name of the config file, excluding extension
*/
public ModuleConfig(String modId, String configName) {
this(modId, "", configName);
}
public ModuleConfig(String modId, String subFolder, String configName) {
/* Preserve the order of the config values */
Config.setInsertionOrderPreserved(true);
/* Configure Paths and Network SYNC ID */
File configDir = new File("config" + (subFolder.isEmpty() ? "" : File.separator + subFolder));
configPath = new File(configDir + File.separator + configName + ".toml");
networkID = modId + ":conf_" + configName.replace("-", "_");
/* Check if the required directories exists, otherwise we create them */
if (!configDir.exists()) {
configDir.mkdirs();
}
/* Register the Config for Watching and events */
ConfigController.register_config(this);
}
/**
* This method has to be called in the config constructor. This creates or upgrades the config file as needed
*
* @param config - The config class to use
*/
public void registerAndSetup(ModuleConfig config) {
if (!configPath.exists() || configPath.length() < 10) {
saveConfig(config);
} else {
migrateConfig(config);
}
}
/**
* Save the config to the disk
*
* @param conf - The config class to serialize and save
*/
public void saveConfig(ModuleConfig conf) {
/* Set up the Serializer and Config Object */
ObjectConverter converter = new ObjectConverter();
CommentedFileConfig config = CommentedFileConfig.builder(configPath).build();
/* Save the config and fire the reload event */
converter.toConfig(conf, config);
config.save();
}
/**
* Load the config from the file into a Class
*
* @param conf - The config Class to load
* @return - Returns the loaded version of the class
*/
public <T> T loadConfig(Object conf) {
/* Set up the Serializer and Config Object */
ObjectConverter converter = new ObjectConverter();
CommentedFileConfig config = CommentedFileConfig.builder(configPath).build();
config.load();
/* Load the config and return the loaded config */
converter.toObject(config, conf);
return (T) conf;
}
/**
* INTERNAL METHOD - Upgrades the config files in the event the config structure changes
*
* @param conf - The config class to load
*/
private void migrateConfig(ModuleConfig conf) {
/* Set up the Serializer and Config Objects */
CommentedFileConfig config = CommentedFileConfig.builder(configPath).build();
CommentedFileConfig newConfig = CommentedFileConfig.builder(configPath).build();
config.load();
/* Upgrade the config */
new ObjectConverter().toConfig(conf, newConfig);
updateConfigValues(config, newConfig, CommentedConfig.copy(newConfig), "");
newConfig.save();
}
private void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) {
/* Loop over the config keys and check what has changed */
newConfig.valueMap().forEach((key, value) -> {
String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key;
if (value instanceof CommentedConfig commentedConfig) {
updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey);
} else {
outputConfig.set(finalKey,
oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value);
}
});
}
/**
* Get the location of the config file
*
* @return - The FILE object containing the config file
*/
public File getConfigPath() {
return configPath;
}
/**
* Get the NETWORK SYNC ID
*
* @return - Returns the Sync ID in format modid:config_name
*/
public String getNetworkID() {
return networkID;
}
/**
* Fired whenever changes to the config are detected
*/
public void configReloaded() {
}
}

View File

@@ -0,0 +1,11 @@
package me.hypherionmc.craterlib.common.config.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Syncable {
}

View File

@@ -6,12 +6,20 @@ import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.Block;
/**
* Base Item for Blocks that implement @link {DyableBlock}.
*/
public class BlockItemDyable extends BlockItem implements ItemDyable {
public BlockItemDyable(Block block, Properties properties) {
super(block, properties);
}
/**
* Get the Item Color from the block
*
* @return
*/
@Override
public DyeColor getColor() {
if (this.getBlock() instanceof DyableBlock dyableBlock) {

View File

@@ -17,6 +17,9 @@ import net.minecraft.world.level.gameevent.GameEvent;
import java.util.List;
/**
* Custom Water Bottle item that supports Dye and can be used as Dye
*/
public class DyableWaterBottle extends DyeItem implements ItemDyable {
private final DyeColor color;
@@ -28,16 +31,35 @@ public class DyableWaterBottle extends DyeItem implements ItemDyable {
this.isGlowing = isGlowing;
}
/**
* Normally this is used for enchanted items, in this case, it's used to check if the fluid is a glowing fluid
*
* @param stack
* @return
*/
@Override
public boolean isFoil(ItemStack stack) {
return this.isGlowing;
}
/**
* Return the color of the item for the Color Handler
*
* @return
*/
@Override
public DyeColor getColor() {
return this.color;
}
/**
* This is basically the same as the vanilla method for water bottles
*
* @param stack
* @param level
* @param user
* @return
*/
@Override
public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity user) {
Player playerEntity;

View File

@@ -6,6 +6,9 @@ import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.material.Fluid;
/**
* A custom water bucket that supports Dye Colors
*/
public class DyableWaterBucket extends BucketItem implements ItemDyable {
private final DyeColor color;
@@ -17,6 +20,12 @@ public class DyableWaterBucket extends BucketItem implements ItemDyable {
this.isGlowing = isGlowing;
}
/**
* Normally this is used for enchanted items, in this case, it's used to check if the fluid is a glowing fluid
*
* @param stack
* @return
*/
@Override
public boolean isFoil(ItemStack stack) {
return this.isGlowing;

View File

@@ -0,0 +1,28 @@
package me.hypherionmc.craterlib.common.network;
import me.hypherionmc.craterlib.Constants;
import net.minecraft.Util;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.Level;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
// TODO: FINISH NETWORK IMPLEMENTATION
public interface BaseNetworkPacket {
Map<String, Handler<?>> PACKETS = Util.make(new HashMap<>(), map -> {
Constants.LOG.info("Registering Config Packets");
});
void write(FriendlyByteBuf buf);
void handle(Level level);
record Handler<T extends BaseNetworkPacket>(Class<T> clazz, BiConsumer<T, FriendlyByteBuf> write,
Function<FriendlyByteBuf, T> read,
BiConsumer<T, Level> handle) {
}
}

View File

@@ -0,0 +1,13 @@
package me.hypherionmc.craterlib.common.particles;
import net.minecraft.core.particles.SimpleParticleType;
/**
* Helper Class for exposing a hidden constructor in the vanilla particle type
*/
public class WrappedSimpleParticleType extends SimpleParticleType {
public WrappedSimpleParticleType(boolean alwaysShow) {
super(alwaysShow);
}
}

View File

@@ -7,4 +7,5 @@ public interface IPlatformHelper {
boolean isModLoaded(String modId);
boolean isDevelopmentEnvironment();
}

View File

@@ -0,0 +1,6 @@
/**
* So, if you got here, most probably you want to see the registration system of this mod.
* Well, you are in the wrong place. This mod uses <a href="https://github.com/Matyrobbrt/RegistrationUtils">RegistrationUtils</a> for
* all its registration needs.
*/
package me.hypherionmc.craterlib.systems.reg;

View File

@@ -9,11 +9,11 @@ import net.minecraft.world.phys.shapes.VoxelShape;
public class MathUtils {
public static VoxelShape rotateShape(Direction from, Direction to, VoxelShape shape) {
VoxelShape[] buffer = new VoxelShape[]{ shape, Shapes.empty() };
VoxelShape[] buffer = new VoxelShape[]{shape, Shapes.empty()};
int times = (to.ordinal() - from.ordinal() + 4) % 4;
for (int i = 0; i < times; i++) {
buffer[0].forAllBoxes((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = Shapes.or(buffer[1], Shapes.box(1-maxZ, minY, minX, 1-minZ, maxY, maxX)));
buffer[0].forAllBoxes((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = Shapes.or(buffer[1], Shapes.box(1 - maxZ, minY, minX, 1 - minZ, maxY, maxX)));
buffer[0] = buffer[1];
buffer[1] = Shapes.empty();
}

View File

@@ -25,7 +25,8 @@ public class OptifineUtils {
Class ofConfigClass = Class.forName("net.optifine.Config");
Method rrField = ofConfigClass.getMethod("isRenderRegions");
return (boolean) rrField.invoke(null);
} catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
} catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException |
IllegalAccessException e) {
// Optifine is probably not present. Ignore the error
return false;
} catch (Exception e) {

View File

@@ -39,12 +39,15 @@ public class RenderUtils {
public static int alpha(int pPackedColor) {
return pPackedColor >>> 24;
}
public static int red(int pPackedColor) {
return pPackedColor >> 16 & 255;
}
public static int green(int pPackedColor) {
return pPackedColor >> 8 & 255;
}
public static int blue(int pPackedColor) {
return pPackedColor & 255;
}