diff --git a/.gitignore b/.gitignore index d5f737e..d3954a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # User-specific stuff .idea/ +*.pxo + *.iml *.ipr *.iws diff --git a/README.md b/README.md index dfb30d2..88df832 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,9 @@ Explore parallel worlds, bond with your daemon, uncover the mysteries of Dust, a 2. Place the mod `.jar` file in your `mods` folder. 3. Launch Minecraft with the Forge profile. +--- +## Wiki +https://github.com/dragonruler1000/hdm-mod/wiki --- ## Contributing diff --git a/build.gradle b/build.gradle index 49abd54..816dfc4 100644 --- a/build.gradle +++ b/build.gradle @@ -31,6 +31,7 @@ minecraft { // Use non-default mappings at your own risk. They may not always work. // Simply re-run your setup task after changing the mappings to update your workspace. mappings channel: mapping_channel, version: mapping_version + accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game. // In most cases, it is not necessary to enable. @@ -120,11 +121,6 @@ dependencies { // then special handling is done to allow a setup of a vanilla dependency without the use of an external repository. minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" - // Example mod dependency with JEI - using fg.deobf() ensures the dependency is remapped to your development mappings - // The JEI API is declared for compile time use, while the full JEI artifact is used at runtime - // compileOnly fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}") - // compileOnly fg.deobf("mezz.jei:jei-${mc_version}-forge-api:${jei_version}") - // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}-forge:${jei_version}") // Example mod dependency using a mod jar from ./libs with a flat dir repository // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar @@ -146,7 +142,7 @@ tasks.named('processResources', ProcessResources).configure { forge_version : forge_version, forge_version_range: forge_version_range, loader_version_range: loader_version_range, mod_id : mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, - mod_authors : mod_authors, mod_description: mod_description,] + mod_authors : mod_authors, credits:credits, mod_description: mod_description,] inputs.properties replaceProperties diff --git a/gradle.properties b/gradle.properties index e005d87..0213130 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ org.gradle.jvmargs=-Xmx3G -org.gradle.daemon=false +org.gradle.daemon=flase # The Minecraft version must agree with the Forge version to get a valid artifact minecraft_version=1.16.5 # The Minecraft version range can use any release version of Minecraft as bounds. @@ -38,12 +38,14 @@ mod_name=Hdm Mod # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=MIT # The mod version. See https://semver.org/ -mod_version=1.1 +mod_version=1.2.3 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html mod_group_id=us.minecraftchest2 # The authors of the mod. This is a simple text string that is used for display purposes in the mod list. mod_authors=Minecraftchest2 +# The mod credits. +credits=Everyone on the Tardis Mod Discord and on the hackclub slack that helped me debug my mod # The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. mod_description=A Mod Inspired by "His Dark Materials" By Philip Pullman diff --git a/src/main/java/us/minecraftchest2/hdm_mod/Hdm_mod.java b/src/main/java/us/minecraftchest2/hdm_mod/Hdm_mod.java index 69b2566..d9e4bea 100644 --- a/src/main/java/us/minecraftchest2/hdm_mod/Hdm_mod.java +++ b/src/main/java/us/minecraftchest2/hdm_mod/Hdm_mod.java @@ -2,12 +2,16 @@ package us.minecraftchest2.hdm_mod; import net.minecraft.block.Block; import net.minecraft.block.Blocks; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.RenderTypeLookup; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.InterModComms; +import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; @@ -18,6 +22,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import us.minecraftchest2.hdm_mod.block.ModBlocks; import us.minecraftchest2.hdm_mod.item.ModItems; +import us.minecraftchest2.hdm_mod.world.structure.ModStructures; //import us.minecraftchest2.hdm_mod.init.ItemInit; import java.util.stream.Collectors; @@ -37,6 +42,8 @@ public class Hdm_mod { ModItems.register(modEventBus1); ModBlocks.register(modEventBus1); + ModStructures.register(modEventBus1); + modEventBus1.addListener(this::setup); // Register the enqueueIMC method for modloading modEventBus1.addListener(this::enqueueIMC); @@ -44,6 +51,7 @@ public class Hdm_mod { modEventBus1.addListener(this::processIMC); // Register the doClientStuff method for modloading modEventBus1.addListener(this::doClientStuff); +// ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ModConfig.GENERAL_SPEC, "modconfig.toml"); // Register ourselves for server and other game events we are interested in MinecraftForge.EVENT_BUS.register(this); @@ -59,10 +67,16 @@ public class Hdm_mod { // some preinit code LOGGER.info("HELLO FROM PREINIT"); LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName()); + + event.enqueueWork(() ->{ + ModStructures.setupStructures(); + }); } private void doClientStuff(final FMLClientSetupEvent event) { // do something that can only be done on the client + event.enqueueWork(() -> { + }); } private void enqueueIMC(final InterModEnqueueEvent event) { diff --git a/src/main/java/us/minecraftchest2/hdm_mod/block/ModBlocks.java b/src/main/java/us/minecraftchest2/hdm_mod/block/ModBlocks.java index 61f2017..6849074 100644 --- a/src/main/java/us/minecraftchest2/hdm_mod/block/ModBlocks.java +++ b/src/main/java/us/minecraftchest2/hdm_mod/block/ModBlocks.java @@ -2,6 +2,8 @@ package us.minecraftchest2.hdm_mod.block; import net.minecraft.block.AbstractBlock; import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.block.material.Material; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; @@ -10,33 +12,62 @@ import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import us.minecraftchest2.hdm_mod.Hdm_mod; +import us.minecraftchest2.hdm_mod.block.custom.Window; import us.minecraftchest2.hdm_mod.item.ModItems; import us.minecraftchest2.hdm_mod.item.ModItemGroup; import java.util.function.Supplier; +import java.util.function.ToIntFunction; public class ModBlocks { + // Function to determine the light level for the "dust" block + public static ToIntFunction dustLightLevel = BlockState -> 10; // Fixed value of 10 + + // Function to set the light level for the "portal" block + public static ToIntFunction PORTAL_LIGHT_LEVEL = BlockState -> 15; // Fixed value of 15 + + // DeferredRegister to register blocks with Forge, using your mod ID public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Hdm_mod.MOD_ID); - + // Registering a "block of dust" with specific properties public static final RegistryObject DUST_BLOCK = registerBlock("block_of_dust", - () -> new Block(AbstractBlock.Properties.create(Material.ROCK).doesNotBlockMovement().harvestLevel(0) - .hardnessAndResistance(5f))); + () -> new Block( + AbstractBlock.Properties.create(Material.ROCK) // Base material is rock + .doesNotBlockMovement() // Entities can move through this block + .harvestLevel(0) // Harvest level + .hardnessAndResistance(500f, 100f) // Hardness and blast resistance + .setLightLevel(dustLightLevel) // Provides light using the dustLightLevel function + ) + ); + // Registering a "portal" block called "window" with different properties + public static final RegistryObject PORTAL_BLOCK = registerBlock("window", + () -> new Window( + AbstractBlock.Properties.create(Material.PORTAL) // Base material is portal + .doesNotBlockMovement() // Entities can move through this block + .harvestLevel(10) // High harvest level + .hardnessAndResistance(1000f, 1000f) // Very hard and blast resistant + .setLightLevel(PORTAL_LIGHT_LEVEL) // Maximum light level + ) + ); - private static RegistryObject registerBlock(String name, Supplier block) { - RegistryObject toReturn = BLOCKS.register(name, block); - registerBlockItem(name, toReturn); + // Helper method to register a block and its corresponding BlockItem at once + private static RegistryObject registerBlock(String name, Supplier block) { + RegistryObject toReturn = BLOCKS.register(name, block); // Register the block itself + registerBlockItem(name, toReturn); // Register the block as an item return toReturn; } + // Helper method to register the item form of a block, belonging to a custom item group private static void registerBlockItem(String name, RegistryObject block) { - ModItems.ITEMS.register(name, () -> new BlockItem(block.get(), - new Item.Properties().group(ModItemGroup.HDM_BLOCK_GROUP))); + ModItems.ITEMS.register(name, () -> new BlockItem( + block.get(), + new Item.Properties().group(ModItemGroup.HDM_BLOCK_GROUP) // Assigns to the HDM block group + )); } + // This method is called to register all blocks with the mod event bus public static void register(IEventBus eventBus){ BLOCKS.register(eventBus); } - -} +} \ No newline at end of file diff --git a/src/main/java/us/minecraftchest2/hdm_mod/block/custom/Window.java b/src/main/java/us/minecraftchest2/hdm_mod/block/custom/Window.java new file mode 100644 index 0000000..09ef11d --- /dev/null +++ b/src/main/java/us/minecraftchest2/hdm_mod/block/custom/Window.java @@ -0,0 +1,173 @@ +package us.minecraftchest2.hdm_mod.block.custom; + +// Import statements... + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.HorizontalBlock; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItemUseContext; +import net.minecraft.server.MinecraftServer; +import net.minecraft.state.StateContainer; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.shapes.IBooleanFunction; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.math.shapes.VoxelShapes; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; +import us.minecraftchest2.hdm_mod.world.dimension.ModDimensions; +import us.minecraftchest2.hdm_mod.world.dimension.SimpleTeleporter; + +import javax.annotation.Nullable; +import java.util.stream.Stream; + +/** + * Custom window block class, serving as a dimensional portal between worlds. + * Inherits directional placement capabilities from HorizontalBlock. + */ +public class Window extends HorizontalBlock { + /** + * Constructor for Window block; forwards the properties to the parent constructor. + */ + public Window(Properties builder) { + super(builder); + } + + // VoxelShapes for visually and physically shaping the block based on orientation. + // Each direction (N/E/S/W) has a custom composition of rectangular regions. + + /** Shape for the block facing NORTH. */ + private static final VoxelShape SHAPE_N = Stream.of( + Block.makeCuboidShape(5, 11, 5, 6, 13, 11), // Window frame elements (left, etc.) + Block.makeCuboidShape(4, 0, 4, 12, 1, 12), // Base of window + Block.makeCuboidShape(5, 1, 5, 11, 2, 11), // Lower window frame + Block.makeCuboidShape(6, 2, 6, 10, 10, 10), // Glass pane + Block.makeCuboidShape(5, 10, 4, 11, 11, 12), // Top frame + Block.makeCuboidShape(5, 11, 4, 11, 12, 5), // Decorative details + Block.makeCuboidShape(5, 11, 11, 11, 14, 12),// Upper right details + Block.makeCuboidShape(10, 11, 5, 11, 13, 11) // Right vertical side + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); + + /** Shape for the block facing EAST (rotated). */ + private static final VoxelShape SHAPE_E = Stream.of( + Block.makeCuboidShape(5, 11, 5, 11, 13, 6), + Block.makeCuboidShape(4, 0, 4, 12, 1, 12), + Block.makeCuboidShape(5, 1, 5, 11, 2, 11), + Block.makeCuboidShape(6, 2, 6, 10, 10, 10), + Block.makeCuboidShape(4, 10, 5, 12, 11, 11), + Block.makeCuboidShape(11, 11, 5, 12, 12, 11), + Block.makeCuboidShape(4, 11, 5, 5, 14, 11), + Block.makeCuboidShape(5, 11, 10, 11, 13, 11) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); + + /** Shape for the block facing SOUTH. */ + private static final VoxelShape SHAPE_S = Stream.of( + Block.makeCuboidShape(10, 11, 5, 11, 13, 11), + Block.makeCuboidShape(4, 0, 4, 12, 1, 12), + Block.makeCuboidShape(5, 1, 5, 11, 2, 11), + Block.makeCuboidShape(6, 2, 6, 10, 10, 10), + Block.makeCuboidShape(5, 10, 4, 11, 11, 12), + Block.makeCuboidShape(5, 11, 11, 11, 12, 12), + Block.makeCuboidShape(5, 11, 4, 11, 14, 5), + Block.makeCuboidShape(5, 11, 5, 6, 13, 11) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); + + /** Shape for the block facing WEST. */ + private static final VoxelShape SHAPE_W = Stream.of( + Block.makeCuboidShape(5, 11, 10, 11, 13, 11), + Block.makeCuboidShape(4, 0, 4, 12, 1, 12), + Block.makeCuboidShape(5, 1, 5, 11, 2, 11), + Block.makeCuboidShape(6, 2, 6, 10, 10, 10), + Block.makeCuboidShape(4, 10, 5, 12, 11, 11), + Block.makeCuboidShape(4, 11, 5, 5, 12, 11), + Block.makeCuboidShape(11, 11, 5, 12, 14, 11), + Block.makeCuboidShape(5, 11, 5, 11, 13, 6) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); + + /** + * Handles when a player right-clicks/interacts with this block. + * Triggers portal teleportation if conditions are met. + */ + @SuppressWarnings("deprecation") + @Override + public ActionResultType onBlockActivated( + BlockState state, + World worldIn, + BlockPos pos, + PlayerEntity player, + Hand handIn, + BlockRayTraceResult hit + ) { + if (!worldIn.isRemote() && !player.isCrouching()) { + MinecraftServer server = worldIn.getServer(); + if (server == null) return ActionResultType.PASS; + + boolean goingToCustom = worldIn.getDimensionKey() != ModDimensions.World1; + + ServerWorld targetWorld = (worldIn.getDimensionKey() == ModDimensions.World1) + ? server.getWorld(World.OVERWORLD) + : server.getWorld(ModDimensions.World1); + + if (worldIn.getDimensionKey() == ModDimensions.World1) { + ServerWorld overWorld = server.getWorld(World.OVERWORLD); + if (overWorld != null) { + player.changeDimension(overWorld, new SimpleTeleporter(pos, false)); + } + } + + if (targetWorld != null) { + SimpleTeleporter teleporter = new SimpleTeleporter(pos, goingToCustom); + player.changeDimension(targetWorld, teleporter); + } + return ActionResultType.SUCCESS; + + } + return super.onBlockActivated(state, worldIn, pos, player, handIn, hit); + } + + /** + * Returns the block's physical outline for rendering and collision. + * The shape depends on the current facing direction of the block. + */ + @Override + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + switch (state.get(HORIZONTAL_FACING)) { + case NORTH: + return SHAPE_N; + case SOUTH: + return SHAPE_S; + case WEST: + return SHAPE_W; + case EAST: + return SHAPE_E; + default: + return SHAPE_N; + } + } + + /** + * Registers the horizontal facing property with the block state container, + * enabling the block to store which direction it is facing. + */ + @Override + protected void fillStateContainer(StateContainer.Builder builder) { + builder.add(HORIZONTAL_FACING); + } + + /** + * Determines the block's initial facing based on the placement context. + * The block will face opposite to the player's direction when placed. + */ + @Nullable + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + return this.getDefaultState().with(HORIZONTAL_FACING, context.getPlacementHorizontalFacing().getOpposite()); + } +} \ No newline at end of file diff --git a/src/main/java/us/minecraftchest2/hdm_mod/config/ModConfig.java b/src/main/java/us/minecraftchest2/hdm_mod/config/ModConfig.java new file mode 100644 index 0000000..07aa724 --- /dev/null +++ b/src/main/java/us/minecraftchest2/hdm_mod/config/ModConfig.java @@ -0,0 +1,18 @@ +//package us.minecraftchest2.hdm_mod.config; +// +//import net.minecraftforge.common.ForgeConfigSpec; +// +//public class ModConfig { +//public static final ForgeConfigSpec GENERAL_SPEC; +// +//static { +// ForgeConfigSpec.Builder configBuilder = new ForgeConfigSpec.Builder(); +// setupConfig(configBuilder); +// GENERAL_SPEC = configBuilder.build(); +//} +//public static ForgeConfigSpec.IntValue exampleIntConfigEntry; +// +//private static void setupConfig(ForgeConfigSpec.Builder builder) { +// exampleIntConfigEntry = builder.defineInRange("exampleIntConfigEntry", 5, 2, 50); +//} +//} diff --git a/src/main/java/us/minecraftchest2/hdm_mod/config/modconfig.toml b/src/main/java/us/minecraftchest2/hdm_mod/config/modconfig.toml new file mode 100644 index 0000000..7c482ca --- /dev/null +++ b/src/main/java/us/minecraftchest2/hdm_mod/config/modconfig.toml @@ -0,0 +1,18 @@ +package us.minecraftchest2.hdm_mod.config; + +import net.minecraftforge.common.ForgeConfigSpec; + +public class ModConfig { +public static final ForgeConfigSpec GENERAL_SPEC; + +static { +ForgeConfigSpec.Builder configBuilder = new ForgeConfigSpec.Builder(); +setupConfig(configBuilder); +GENERAL_SPEC = configBuilder.build(); +} +public static ForgeConfigSpec.IntValue exampleIntConfigEntry; + +private static void setupConfig(ForgeConfigSpec.Builder builder) { +exampleIntConfigEntry = builder.defineInRange("exampleIntConfigEntry", 5, 2, 50); +} +} diff --git a/src/main/java/us/minecraftchest2/hdm_mod/item/ModItems.java b/src/main/java/us/minecraftchest2/hdm_mod/item/ModItems.java index f7b0f54..21d7357 100644 --- a/src/main/java/us/minecraftchest2/hdm_mod/item/ModItems.java +++ b/src/main/java/us/minecraftchest2/hdm_mod/item/ModItems.java @@ -1,11 +1,17 @@ package us.minecraftchest2.hdm_mod.item; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Food; import net.minecraft.item.Item; +import net.minecraft.potion.Effect; +import net.minecraft.potion.EffectInstance; +import net.minecraft.potion.Effects; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import us.minecraftchest2.hdm_mod.Hdm_mod; +import us.minecraftchest2.hdm_mod.block.ModBlocks; import us.minecraftchest2.hdm_mod.item.custom.SubtleKnife; public class ModItems { @@ -18,12 +24,13 @@ public class ModItems { public static final RegistryObject OMELET = ITEMS.register("omelet", - () -> new Item(new Item.Properties().group(ModItemGroup.HDM_ITEM_GROUP))); + () -> new Item(new Item.Properties().food(new Food.Builder().hunger(5).fastToEat().saturation(20) + .effect(() -> new EffectInstance(Effects.HUNGER, 40, 4), 0.75f).build()).group(ModItemGroup.HDM_ITEM_GROUP))); public static final RegistryObject KNIFE = ITEMS.register("subtle_knife", () -> new SubtleKnife(new Item.Properties().maxStackSize(1).group(ModItemGroup.HDM_ITEM_GROUP).maxDamage(2000))); - - + public static final RegistryObject OMELET_COOKED = ITEMS.register("omelet-cooked", + () -> new Item(new Item.Properties().food(new Food.Builder().hunger(5).fastToEat().saturation(20).build()).group(ModItemGroup.HDM_ITEM_GROUP))); public static void register(IEventBus eventBus) { ITEMS.register(eventBus); diff --git a/src/main/java/us/minecraftchest2/hdm_mod/item/custom/StructureLocator.java b/src/main/java/us/minecraftchest2/hdm_mod/item/custom/StructureLocator.java new file mode 100644 index 0000000..bab98f8 --- /dev/null +++ b/src/main/java/us/minecraftchest2/hdm_mod/item/custom/StructureLocator.java @@ -0,0 +1,51 @@ +//package us.minecraftchest2.hdm_mod.item.custom; +// +//import net.minecraft.entity.player.PlayerEntity; +//import net.minecraft.item.Item; +//import net.minecraft.item.ItemStack; +//import net.minecraft.util.*; +//import net.minecraft.util.text.StringTextComponent; +//import net.minecraft.world.World; +//import net.minecraft.world.gen.feature.structure.Structure; +////import net.minecraft.world.gen.feature.structure.StructureFeature; +//import net.minecraft.util.math.BlockPos; +//import net.minecraft.world.server.ServerWorld; +// +//public class StructureLocatorItem extends Item { +// +// public StructureLocatorItem(Properties properties) { +// super(properties); +// } +// +// @Override +// public ActionResult use(World world, PlayerEntity player, Hand hand) { +// if (!world.isClientSide && world instanceof ServerWorld) { +// ServerWorld serverWorld = (ServerWorld) world; +// BlockPos playerPos = player.blockPosition(); +// +// // Replace this with your own structure, or any StructureFeature +// Structure structureToFind = Structure.STRONGHOLD; +// +// BlockPos structurePos = serverWorld.getStructureLocation( +// structureToFind, +// playerPos, +// 100, // search radius in chunks +// false +// ); +// +// if (structurePos != null) { +// player.sendMessage( +// new StringTextComponent("Nearest structure at: " + structurePos.getX() + ", " + structurePos.getY() + ", " + structurePos.getZ()), +// player.getUUID() +// ); +// } else { +// player.sendMessage( +// new StringTextComponent("No structure found nearby."), +// player.getUUID() +// ); +// } +// } +// +// return ActionResult.resultSuccess(player.getItemInHand(hand)); +// } +//} diff --git a/src/main/java/us/minecraftchest2/hdm_mod/item/custom/SubtleKnife.java b/src/main/java/us/minecraftchest2/hdm_mod/item/custom/SubtleKnife.java index d8a8c66..5c17750 100644 --- a/src/main/java/us/minecraftchest2/hdm_mod/item/custom/SubtleKnife.java +++ b/src/main/java/us/minecraftchest2/hdm_mod/item/custom/SubtleKnife.java @@ -1,13 +1,14 @@ package us.minecraftchest2.hdm_mod.item.custom; -import jdk.nashorn.internal.ir.Block; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import us.minecraftchest2.hdm_mod.block.ModBlocks; public class SubtleKnife extends Item { @@ -20,14 +21,25 @@ public class SubtleKnife extends Item { @Override public ActionResultType onItemUseFirst(ItemStack stack, ItemUseContext context) { World world = context.getWorld(); -// BlockPos pos = PlayerEntity player = context.getPlayer(); - if(world.isRemote) { -// world.setBlockState() + if (player == null) return ActionResultType.PASS; + + // Get the block being clicked + BlockPos blockPos = context.getPos(); + Direction face = context.getFace(); // The face the player clicked + + // Offset to the block face to place the block on the adjacent block (like right-clicking a wall places on it) + BlockPos placePos = blockPos.offset(face); + + // Server-side logic only: place a block + if (!world.isRemote) { + world.setBlockState(placePos, ModBlocks.PORTAL_BLOCK.get().getDefaultState()); } - return super.onItemUseFirst(stack, context); + + return ActionResultType.SUCCESS; } + } diff --git a/src/main/java/us/minecraftchest2/hdm_mod/world/ModWorldEvents.java b/src/main/java/us/minecraftchest2/hdm_mod/world/ModWorldEvents.java new file mode 100644 index 0000000..2c7dd3f --- /dev/null +++ b/src/main/java/us/minecraftchest2/hdm_mod/world/ModWorldEvents.java @@ -0,0 +1,33 @@ +package us.minecraftchest2.hdm_mod.world; + +import com.mojang.serialization.Codec; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import us.minecraftchest2.hdm_mod.Hdm_mod; + +import java.lang.reflect.Method; + +@Mod.EventBusSubscriber(modid = Hdm_mod.MOD_ID) +public class ModWorldEvents { + @SubscribeEvent + public static void addDimensinalSpacing(final WorldEvent.Load event) { + if(event.getWorld() instanceof ServerWorld) { + ServerWorld serverWorld = (ServerWorld) event.getWorld(); + + try { + Method GETCODEC_METHOD = + ObfuscationReflectionHelper.findMethod(ChunkGenerator.class, "func_230347_a_"); + ResourceLocation cgRL = Registry.CHUNK_GENERATOR_CODEC.getKey( + (Codec)GETCODEC_METHOD.invoke(serverWorld.getChunkProvider().generator)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/us/minecraftchest2/hdm_mod/world/dimension/ModDimensions.java b/src/main/java/us/minecraftchest2/hdm_mod/world/dimension/ModDimensions.java index 74d4232..7c38fdc 100644 --- a/src/main/java/us/minecraftchest2/hdm_mod/world/dimension/ModDimensions.java +++ b/src/main/java/us/minecraftchest2/hdm_mod/world/dimension/ModDimensions.java @@ -9,4 +9,6 @@ import us.minecraftchest2.hdm_mod.Hdm_mod; public class ModDimensions { public static RegistryKey TestDim = RegistryKey.getOrCreateKey(Registry.WORLD_KEY, new ResourceLocation(Hdm_mod.MOD_ID, "testdim")); + public static RegistryKey World1 = RegistryKey.getOrCreateKey(Registry.WORLD_KEY, + new ResourceLocation(Hdm_mod.MOD_ID, "world1")); } diff --git a/src/main/java/us/minecraftchest2/hdm_mod/world/dimension/SimpleTeleporter.java b/src/main/java/us/minecraftchest2/hdm_mod/world/dimension/SimpleTeleporter.java index 26a1531..9337c1f 100644 --- a/src/main/java/us/minecraftchest2/hdm_mod/world/dimension/SimpleTeleporter.java +++ b/src/main/java/us/minecraftchest2/hdm_mod/world/dimension/SimpleTeleporter.java @@ -1,60 +1,149 @@ -//package us.minecraftchest2.hdm_mod.world.dimension; -// -//import net.minecraft.block.material.Material; -//import net.minecraft.entity.Entity; -//import net.minecraft.fluid.Fluids; -//import net.minecraft.util.math.BlockPos; -//import net.minecraft.world.server.ServerWorld; -//import net.minecraftforge.common.util.ITeleporter; -//import us.minecraftchest2.hdm_mod. -// -//import java.util.function.Function; -// -//public class KJTeleporter implements ITeleporter { -// public static BlockPos thisPos = BlockPos.ZERO; -// public static boolean insideDimension = true; -// -// public KJTeleporter(BlockPos pos, boolean insideDim) { -// thisPos = pos; -// insideDimension = insideDim; -// } -// -// @Override -// public Entity placeEntity(Entity entity, ServerWorld currentWorld, ServerWorld destinationWorld, -// float yaw, Function repositionEntity) { -// entity = repositionEntity.apply(false); -// double y = 61; -// -// if (!insideDimension) { -// y = thisPos.getY(); -// } -// -// BlockPos destinationPos = new BlockPos(thisPos.getX(), y, thisPos.getZ()); -// -// int tries = 0; -// while ((destinationWorld.getBlockState(destinationPos).getMaterial() != Material.AIR) && -// !destinationWorld.getBlockState(destinationPos).isReplaceable(Fluids.WATER) && -// destinationWorld.getBlockState(destinationPos.up()).getMaterial() != Material.AIR && -// !destinationWorld.getBlockState(destinationPos.up()).isReplaceable(Fluids.WATER) && tries < 25) { -// destinationPos = destinationPos.up(2); -// tries++; -// } -// -// entity.setPositionAndUpdate(destinationPos.getX(), destinationPos.getY(), destinationPos.getZ()); -// -// if (insideDimension) { -// boolean doSetBlock = true; -// for (BlockPos checkPos : BlockPos.getAllInBoxMutable(destinationPos.down(10).west(10), destinationPos.up(10).east(10))) { -// if (destinationWorld.getBlockState(checkPos).getBlock() instanceof KaupenAltarBlock) { -// doSetBlock = false; -// break; -// } -// } -// if (doSetBlock) { -// destinationWorld.setBlockState(destinationPos, ModBlocks.KAUPEN_ALTAR.get().getDefaultState()); -// } -// } -// -// return entity; -// } -//} +package us.minecraftchest2.hdm_mod.world.dimension; + +// Imports omitted for brevity + +import net.minecraft.block.BlockState; +import net.minecraft.block.material.Material; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.Fluids; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.common.util.ITeleporter; +import us.minecraftchest2.hdm_mod.block.ModBlocks; +import us.minecraftchest2.hdm_mod.block.custom.Window; + +import java.util.function.Function; + +/** + * Handles teleportation of entities between dimensions, with custom logic for portals and safety. + */ +public class SimpleTeleporter implements ITeleporter { + // The destination position for the teleport + public static BlockPos thisPos = BlockPos.ZERO; + + // True if teleporting into the custom dimension, false if to overworld + public static boolean insideDimension = true; + + // Records if the most recent teleport was successful + private boolean success = false; + + /** + * @return True if the last teleportation was successful (a safe landing spot found), false otherwise + */ + public boolean wasSuccessful() { + return success; + } + + /** + * Constructor sets the target position and whether we're inside our custom dimension. + * @param pos Destination position + * @param insideDim Are we inside the custom dimension after teleport? + */ + public SimpleTeleporter(BlockPos pos, boolean insideDim) { + thisPos = pos; + insideDimension = insideDim; + } + + /** + * Checks if a block position is unsafe (solid, unreplaceable, lava, or fire). + * @param world The world to check in + * @param pos The position to check + * @return True if the position is unsafe, false if safe + */ + private boolean isUnsafe(ServerWorld world, BlockPos pos){ + BlockState state = world.getBlockState(pos); + Material material = state.getMaterial(); + // Not air AND not easily replaced (by water/etc) OR is lava or fire is considered unsafe + return material != Material.AIR && + !state.isReplaceable(Fluids.WATER) && + !material.isReplaceable() || + material == Material.LAVA || + material == Material.FIRE; + } + + /** + * Handles the actual placing of the entity when teleporting between dimensions. + * Will try to find a safe spot upwards, up to 25 tries. + * Also, optionally places a portal block at the destination. + */ + @Override + public Entity placeEntity(Entity entity, ServerWorld currentWorld, ServerWorld destinationWorld, + float yaw, Function repositionEntity) { + // Move entity to the origin position + entity = repositionEntity.apply(false); + + // Default target y coordinate for the destination + double y = 61; + + // If not going inside the custom dimension, use the saved Y + if (!insideDimension) { + y = thisPos.getY(); + } + + // Calculate the intended destination block position + BlockPos destinationPos = new BlockPos(thisPos.getX(), y, thisPos.getZ()); + + // Try to find a safe spot (air, replaceable, not lava/fire) by moving up, max 25 attempts + int tries = 0; + while ((isUnsafe(destinationWorld, destinationPos) || isUnsafe(destinationWorld, destinationPos.up())) && tries < 25) { + destinationPos = destinationPos.up(2); + tries++; + } + + // If it couldn't find a safe spot after 25 attempts, fail teleport + if (tries >= 25) { + this.success = false; + return entity; + } + + // Move entity to found safe location + entity.setPositionAndUpdate(destinationPos.getX(), destinationPos.getY(), destinationPos.getZ()); + this.success = true; + + // When entering a custom dimension, make a portal block at the destination unless one already exists nearby + if (insideDimension) { + boolean doSetBlock = true; + for (BlockPos checkPos : BlockPos.getAllInBoxMutable(destinationPos.down(10).west(10), destinationPos.up(10).east(10))) { + if (destinationWorld.getBlockState(checkPos).getBlock() instanceof Window) { + doSetBlock = false; + break; + } + } + if (doSetBlock) { + destinationWorld.setBlockState(destinationPos, ModBlocks.PORTAL_BLOCK.get().getDefaultState()); + } + } + + if (entity instanceof PlayerEntity) { + PlayerEntity player = (PlayerEntity) entity; + ResourceLocation dimensionKey = destinationWorld.getDimensionKey().getLocation(); + // Only send the welcome message if NOT the overworld + if (!dimensionKey.getPath().equals("overworld")) { + // (Same nice formatting as before) + String path = dimensionKey.getPath(); + String dimensionName; + switch (path) { + case "the_nether": + dimensionName = "the Nether"; + break; + case "the_end": + dimensionName = "the End"; + break; + case "hdm_dimension": + dimensionName = "HDM Dimension"; + break; + default: + dimensionName = path.replace('_', ' '); + dimensionName = dimensionName.substring(0, 1).toUpperCase() + dimensionName.substring(1); + break; + } + player.sendMessage(new StringTextComponent("Welcome to " + dimensionName + "!"), player.getUniqueID()); + } + } + + return entity; + } +} \ No newline at end of file diff --git a/src/main/java/us/minecraftchest2/hdm_mod/world/gen/ModStructureGeneration.java b/src/main/java/us/minecraftchest2/hdm_mod/world/gen/ModStructureGeneration.java new file mode 100644 index 0000000..e083aa1 --- /dev/null +++ b/src/main/java/us/minecraftchest2/hdm_mod/world/gen/ModStructureGeneration.java @@ -0,0 +1,27 @@ +package us.minecraftchest2.hdm_mod.world.gen; + +import net.minecraft.util.RegistryKey; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.feature.IFeatureConfig; +import net.minecraft.world.gen.feature.StructureFeature; +import net.minecraftforge.common.BiomeDictionary; +import net.minecraftforge.event.world.BiomeLoadingEvent; +import us.minecraftchest2.hdm_mod.world.structure.ModStructures; + +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; + +public class ModStructureGeneration { + public static void generateStructures(final BiomeLoadingEvent event) { + RegistryKey key = RegistryKey.getOrCreateKey(Registry.BIOME_KEY, event.getName()); + Set types = BiomeDictionary.getTypes(key); + + if(types.contains(BiomeDictionary.Type.PLAINS)) { + List>> structures = event.getGeneration().getStructures(); + + structures.add(() -> ModStructures.HOUSE.get().withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG)); + } + } +} \ No newline at end of file diff --git a/src/main/java/us/minecraftchest2/hdm_mod/world/structure/ModStructures.java b/src/main/java/us/minecraftchest2/hdm_mod/world/structure/ModStructures.java new file mode 100644 index 0000000..a7927f5 --- /dev/null +++ b/src/main/java/us/minecraftchest2/hdm_mod/world/structure/ModStructures.java @@ -0,0 +1,113 @@ +package us.minecraftchest2.hdm_mod.world.structure; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import net.minecraft.util.registry.WorldGenRegistries; +import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraft.world.gen.feature.structure.Structure; +import net.minecraft.world.gen.settings.DimensionStructuresSettings; +import net.minecraft.world.gen.settings.StructureSeparationSettings; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import us.minecraftchest2.hdm_mod.Hdm_mod; +import us.minecraftchest2.hdm_mod.world.structure.structures.HouseStructure; + +import java.util.HashMap; +import java.util.Map; + +public class ModStructures { + public static final DeferredRegister> STRUCTURES = + DeferredRegister.create(ForgeRegistries.STRUCTURE_FEATURES, Hdm_mod.MOD_ID); + + public static final RegistryObject> HOUSE = + STRUCTURES.register("house", HouseStructure::new); + + /* average distance apart in chunks between spawn attempts */ + /* minimum distance apart in chunks between spawn attempts. MUST BE LESS THAN ABOVE VALUE*/ + /* this modifies the seed of the structure so no two structures always spawn over each-other. + Make this large and unique. */ + public static void setupStructures() { + setupMapSpacingAndLand(HOUSE.get(), + new StructureSeparationSettings(100,50, 1234567890), + true); + } + + /** + * Adds the provided structure to the registry, and adds the separation settings. + * The rarity of the structure is determined based on the values passed into + * this method in the structureSeparationSettings argument. + * This method is called by setupStructures above. + **/ + public static > void setupMapSpacingAndLand(F structure, StructureSeparationSettings structureSeparationSettings, + boolean transformSurroundingLand) { + //add our structures into the map in Structure class + Structure.NAME_STRUCTURE_BIMAP.put(structure.getRegistryName().toString(), structure); + + /* + * Whether surrounding land will be modified automatically to conform to the bottom of the structure. + * Basically, it adds land at the base of the structure like it does for Villages and Outposts. + * Doesn't work well on structure that have pieces stacked vertically or change in heights. + * + */ + if (transformSurroundingLand) { + Structure.field_236384_t_ = ImmutableList.>builder() + .addAll(Structure.field_236384_t_) + .add(structure) + .build(); + } + + /* + * This is the map that holds the default spacing of all structures. + * Always add your structure to here so that other mods can utilize it if needed. + * + * However, while it does propagate the spacing to some correct dimensions from this map, + * it seems it doesn't always work for code made dimensions as they read from this list beforehand. + * + * Instead, we will use the WorldEvent.Load event in ModWorldEvents to add the structure + * spacing from this list into that dimension or to do dimension blacklisting properly. + * We also use our entry in DimensionStructuresSettings.DEFAULTS in WorldEvent.Load as well. + * + * DEFAULTS requires AccessTransformer (See resources/META-INF/accesstransformer.cfg) + */ + DimensionStructuresSettings.field_236191_b_ = + ImmutableMap., StructureSeparationSettings>builder() + .putAll(DimensionStructuresSettings.field_236191_b_) + .put(structure, structureSeparationSettings) + .build(); + + /* + * There are very few mods that relies on seeing your structure in the + * noise settings registry before the world is made. + * + * You may see some mods add their spacings to DimensionSettings.BUILTIN_OVERWORLD instead of the + * NOISE_GENERATOR_SETTINGS loop below but that field only applies for the default overworld and + * won't add to other worldtypes or dimensions (like amplified or Nether). + * So yeah, don't do DimensionSettings.BUILTIN_OVERWORLD. Use the NOISE_GENERATOR_SETTINGS loop + * below instead if you must. + */ + WorldGenRegistries.NOISE_SETTINGS.getEntries().forEach(settings -> { + Map, StructureSeparationSettings> structureMap = + settings.getValue().getStructures().func_236195_a_(); + /* + * Pre-caution in case a mod makes the structure map immutable like datapacks do. + * I take no chances myself. You never know what another mods does... + * + * structureConfig requires AccessTransformer (See resources/META-INF/accesstransformer.cfg) + */ + if (structureMap instanceof ImmutableMap) { + Map, StructureSeparationSettings> tempMap = new HashMap<>(structureMap); + tempMap.put(structure, structureSeparationSettings); + settings.getValue().getStructures().func_236195_a_(); + + } else { + structureMap.put(structure, structureSeparationSettings); + } + }); + } + + public static void register(IEventBus eventBus) { + STRUCTURES.register(eventBus); + } +} \ No newline at end of file diff --git a/src/main/java/us/minecraftchest2/hdm_mod/world/structure/structures/HouseStructure.java b/src/main/java/us/minecraftchest2/hdm_mod/world/structure/structures/HouseStructure.java new file mode 100644 index 0000000..9a65477 --- /dev/null +++ b/src/main/java/us/minecraftchest2/hdm_mod/world/structure/structures/HouseStructure.java @@ -0,0 +1,90 @@ +package us.minecraftchest2.hdm_mod.world.structure.structures; + +import net.minecraft.block.BlockState; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SharedSeedRandom; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.MutableBoundingBox; +import net.minecraft.util.registry.DynamicRegistries; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.provider.BiomeProvider; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.GenerationStage; +import net.minecraft.world.gen.Heightmap; +import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraft.world.gen.feature.jigsaw.JigsawManager; +import net.minecraft.world.gen.feature.structure.AbstractVillagePiece; +import net.minecraft.world.gen.feature.structure.Structure; +import net.minecraft.world.gen.feature.structure.StructureStart; +import net.minecraft.world.gen.feature.structure.VillageConfig; +import net.minecraft.world.gen.feature.template.TemplateManager; +import us.minecraftchest2.hdm_mod.Hdm_mod; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; + +public class HouseStructure extends Structure { + public HouseStructure() { + super(NoFeatureConfig.CODEC); + } + + @Override + public GenerationStage.Decoration getDecorationStage() { + return GenerationStage.Decoration.SURFACE_STRUCTURES; + } + + @Override + protected boolean func_230363_a_(ChunkGenerator chunkGenerator, BiomeProvider biomeSource, + long seed, SharedSeedRandom chunkRandom, int chunkX, int chunkZ, + Biome biome, ChunkPos chunkPos, NoFeatureConfig featureConfig) { + BlockPos centerOfChunk = new BlockPos((chunkX << 4) + 7, 0, (chunkZ << 4) + 7); + int landHeight = chunkGenerator.getHeight(centerOfChunk.getX(), centerOfChunk.getZ(), + Heightmap.Type.WORLD_SURFACE_WG); + + IBlockReader columnOfBlocks = chunkGenerator.func_230348_a_(centerOfChunk.getX(), centerOfChunk.getZ()); + BlockState topBlock = columnOfBlocks.getBlockState(centerOfChunk.up(landHeight)); + + return topBlock.getFluidState().isEmpty(); + } + + @Override + public IStartFactory getStartFactory() { + return HouseStructure.Start::new; + } + + public static class Start extends StructureStart { + public Start(Structure structureIn, int chunkX, int chunkZ, + MutableBoundingBox mutableBoundingBox, int referenceIn, long seedIn) { + super(structureIn, chunkX, chunkZ, mutableBoundingBox, referenceIn, seedIn); + } + + @Override // generatePieces + public void func_230364_a_(DynamicRegistries dynamicRegistryManager, ChunkGenerator chunkGenerator, + TemplateManager templateManagerIn, int chunkX, int chunkZ, Biome biomeIn, + NoFeatureConfig config) { + // Turns the chunk coordinates into actual coordinates we can use. (Gets center of that chunk) + int x = (chunkX << 4) + 7; + int z = (chunkZ << 4) + 7; + BlockPos blockpos = new BlockPos(x, 0, z); + + //addpieces() + JigsawManager.func_242837_a(dynamicRegistryManager, + new VillageConfig(() -> dynamicRegistryManager.getRegistry(Registry.JIGSAW_POOL_KEY) + .getOrDefault(new ResourceLocation(Hdm_mod.MOD_ID, "house/start_pool")), + 10), AbstractVillagePiece::new, chunkGenerator, templateManagerIn, + blockpos, this.components, this.rand,false,true); + + this.components.forEach(piece -> piece.offset(0, 1, 0)); + this.components.forEach(piece -> piece.getBoundingBox().minY -= 1); + + this.recalculateStructureSize(); + + LogManager.getLogger().log(Level.DEBUG, "House at " + + this.components.get(0).getBoundingBox().minX + " " + + this.components.get(0).getBoundingBox().minY + " " + + this.components.get(0).getBoundingBox().minZ); + } + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 0000000..b134280 --- /dev/null +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1,4 @@ +public-f net.minecraft.world.gen.feature.structure.Structure field_236384_t_ #LAND_TRANSFORMING_STRUCTURES +public-f net.minecraft.world.gen.settings.DimensionStructuresSettings field_236191_b_ #DEFAULT_STRUCTURE_CONFIGS +public-f net.minecraft.world.gen.FlatGenerationSettings field_202247_j #STRUCTURES +public-f net.minecraft.world.gen.settings.DimensionStructuresSettings field_236193_d_ #structures \ No newline at end of file diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index e0d6b70..e557235 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -30,6 +30,7 @@ displayName = "${mod_name}" #mandatory #credits="Thanks for this example mod goes to Java" #optional # A text field displayed in the mod UI authors = "${mod_authors}" #optional +credits="${credits}" # The description text for the mod (multi line!) (#mandatory) description = '''${mod_description}''' # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. diff --git a/src/main/resources/assets/hdm_mod/blockstates/block_of_dust.json b/src/main/resources/assets/hdm_mod/blockstates/block_of_dust.json index e693a6d..2e143c2 100644 --- a/src/main/resources/assets/hdm_mod/blockstates/block_of_dust.json +++ b/src/main/resources/assets/hdm_mod/blockstates/block_of_dust.json @@ -1,5 +1,7 @@ { "variants": { - "": {"model": "hdm_mod:block/block_of_dust" } + "":[ + {"model": "hdm_mod:block/block_of_dust" } + ] } } \ No newline at end of file diff --git a/src/main/resources/assets/hdm_mod/blockstates/window.json b/src/main/resources/assets/hdm_mod/blockstates/window.json new file mode 100644 index 0000000..5741ab8 --- /dev/null +++ b/src/main/resources/assets/hdm_mod/blockstates/window.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": [ + {"model": "hdm_mod:block/window" } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/hdm_mod/lang/en_us.json b/src/main/resources/assets/hdm_mod/lang/en_us.json index 5bfcdda..30eb76e 100644 --- a/src/main/resources/assets/hdm_mod/lang/en_us.json +++ b/src/main/resources/assets/hdm_mod/lang/en_us.json @@ -4,6 +4,8 @@ "item.hdm_mod.subtle_knife": "Subtle Knife", "item.hdm_mod.omelet": "Omelet", + "item.hdm_mod.omelet-cooked": "Omelet", "item.hdm_mod.dust": "Dust", - "block.hdm_mod.block_of_dust": "Block of Dust" + "block.hdm_mod.block_of_dust": "Block of Dust", + "block.hdm_mod.window": "Window" } \ No newline at end of file diff --git a/src/main/resources/assets/hdm_mod/models/block/window.json b/src/main/resources/assets/hdm_mod/models/block/window.json new file mode 100644 index 0000000..f302f99 --- /dev/null +++ b/src/main/resources/assets/hdm_mod/models/block/window.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures" : { + "all": "hdm_mod:block/portalblock" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/hdm_mod/models/block/window1.json b/src/main/resources/assets/hdm_mod/models/block/window1.json new file mode 100644 index 0000000..54c9c09 --- /dev/null +++ b/src/main/resources/assets/hdm_mod/models/block/window1.json @@ -0,0 +1,151 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "1": "hdm_mod:block/brown", + "2": "hdm_mod:block/grey", + "particle": "hdm_mod:block/red" + }, + "elements": [ + { + "from": [5, 11, 5], + "to": [6, 13, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8.3125, 8]}, + "faces": { + "north": {"uv": [0, 0, 1, 6], "texture": "#2"}, + "east": {"uv": [0, 0, 1, 6], "texture": "#2"}, + "south": {"uv": [0, 0, 1, 6], "texture": "#2"}, + "west": {"uv": [0, 0, 1, 6], "texture": "#2"}, + "up": {"uv": [0, 0, 1, 6], "texture": "#2"}, + "down": {"uv": [0, 0, 1, 6], "texture": "#2"} + } + }, + { + "from": [4, 0, 4], + "to": [12, 1, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8.3125, 8]}, + "faces": { + "north": {"uv": [0, 0, 8, 8], "texture": "#1"}, + "east": {"uv": [0, 0, 8, 8], "texture": "#1"}, + "south": {"uv": [0, 0, 8, 8], "texture": "#1"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#1"}, + "up": {"uv": [0, 0, 8, 8], "texture": "#1"}, + "down": {"uv": [0, 0, 8, 8], "texture": "#1"} + } + }, + { + "from": [5, 1, 5], + "to": [11, 2, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8.3125, 8]}, + "faces": { + "north": {"uv": [0, 0, 6, 1], "texture": "#1"}, + "east": {"uv": [0, 0, 6, 1], "texture": "#1"}, + "south": {"uv": [0, 0, 6, 1], "texture": "#1"}, + "west": {"uv": [0, 0, 6, 1], "texture": "#1"}, + "up": {"uv": [0, 0, 6, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 6, 1], "texture": "#1"} + } + }, + { + "from": [6, 2, 6], + "to": [10, 10, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8.3125, 8]}, + "faces": { + "north": {"uv": [0, 0, 4, 8], "texture": "#1"}, + "east": {"uv": [0, 0, 4, 8], "texture": "#1"}, + "south": {"uv": [0, 0, 4, 8], "texture": "#1"}, + "west": {"uv": [0, 0, 4, 8], "texture": "#1"}, + "up": {"uv": [0, 0, 4, 8], "texture": "#1"}, + "down": {"uv": [0, 0, 4, 8], "texture": "#1"} + } + }, + { + "from": [5, 10, 4], + "to": [11, 11, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8.3125, 8]}, + "faces": { + "north": {"uv": [0, 0, 6, 8], "texture": "#2"}, + "east": {"uv": [0, 0, 6, 8], "texture": "#2"}, + "south": {"uv": [0, 0, 6, 8], "texture": "#2"}, + "west": {"uv": [0, 0, 6, 8], "texture": "#2"}, + "up": {"uv": [0, 0, 6, 8], "texture": "#2"}, + "down": {"uv": [0, 0, 6, 8], "texture": "#2"} + } + }, + { + "from": [5, 11, 4], + "to": [11, 12, 5], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8.3125, 8]}, + "faces": { + "north": {"uv": [0, 0, 6, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 6, 1], "texture": "#2"}, + "south": {"uv": [0, 0, 6, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 6, 1], "texture": "#2"}, + "up": {"uv": [0, 0, 6, 1], "texture": "#2"}, + "down": {"uv": [0, 0, 6, 1], "texture": "#2"} + } + }, + { + "from": [5, 11, 11], + "to": [11, 14, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8.3125, 8]}, + "faces": { + "north": {"uv": [0, 0, 6, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 6, 1], "texture": "#2"}, + "south": {"uv": [0, 0, 6, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 6, 1], "texture": "#2"}, + "up": {"uv": [0, 0, 6, 1], "texture": "#2"}, + "down": {"uv": [0, 0, 6, 1], "texture": "#2"} + } + }, + { + "from": [10, 11, 5], + "to": [11, 13, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8.3125, 8]}, + "faces": { + "north": {"uv": [0, 0, 1, 6], "texture": "#2"}, + "east": {"uv": [0, 0, 1, 6], "texture": "#2"}, + "south": {"uv": [0, 0, 1, 6], "texture": "#2"}, + "west": {"uv": [0, 0, 1, 6], "texture": "#2"}, + "up": {"uv": [0, 0, 1, 6], "texture": "#2"}, + "down": {"uv": [0, 0, 1, 6], "texture": "#2"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [0, -180, 0], + "scale": [0.5, 0.69, 0.5] + }, + "thirdperson_lefthand": { + "rotation": [0, -180, 0], + "scale": [0.5, 0.69, 0.5] + }, + "firstperson_righthand": { + "translation": [0, 4, 2.5], + "scale": [0.5, 0.5, 0.5] + }, + "firstperson_lefthand": { + "translation": [0, 4, 2.5], + "scale": [0.5, 0.5, 0.5] + }, + "ground": { + "translation": [0, 2.25, 0], + "scale": [0.75, 0.75, 0.75] + }, + "gui": { + "rotation": [55, -125, 0], + "scale": [0.75, 0.75, 0.75] + }, + "head": { + "translation": [0, 14, 0] + } + }, + "groups": [ + { + "name": "VoxelShapes", + "origin": [8, 8, 8], + "color": 0, + "children": [0, 1, 2, 3, 4, 5, 6, 7] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/hdm_mod/models/item/omelet-cooked.json b/src/main/resources/assets/hdm_mod/models/item/omelet-cooked.json new file mode 100644 index 0000000..2dccee3 --- /dev/null +++ b/src/main/resources/assets/hdm_mod/models/item/omelet-cooked.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "hdm_mod:item/omelet" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/hdm_mod/models/item/omelet.json b/src/main/resources/assets/hdm_mod/models/item/omelet.json index e08920c..2dccee3 100644 --- a/src/main/resources/assets/hdm_mod/models/item/omelet.json +++ b/src/main/resources/assets/hdm_mod/models/item/omelet.json @@ -1,6 +1,6 @@ { "parent": "item/generated", "textures": { - "layer0": "hdm_mod:items/omelet" + "layer0": "hdm_mod:item/omelet" } } \ No newline at end of file diff --git a/src/main/resources/assets/hdm_mod/models/item/subtle_knife.json b/src/main/resources/assets/hdm_mod/models/item/subtle_knife.json index ab9881b..981cf10 100644 --- a/src/main/resources/assets/hdm_mod/models/item/subtle_knife.json +++ b/src/main/resources/assets/hdm_mod/models/item/subtle_knife.json @@ -1,6 +1,6 @@ { "parent": "item/generated", "textures": { - "layer0": "hdm_mod:items/knife" + "layer0": "hdm_mod:item/knife" } } \ No newline at end of file diff --git a/src/main/resources/assets/hdm_mod/models/item/window.json b/src/main/resources/assets/hdm_mod/models/item/window.json new file mode 100644 index 0000000..97f1558 --- /dev/null +++ b/src/main/resources/assets/hdm_mod/models/item/window.json @@ -0,0 +1,3 @@ +{ + "parent": "hdm_mod:block/window" +} \ No newline at end of file diff --git a/src/main/resources/assets/hdm_mod/textures/block/brown.png b/src/main/resources/assets/hdm_mod/textures/block/brown.png new file mode 100644 index 0000000..f1372e7 Binary files /dev/null and b/src/main/resources/assets/hdm_mod/textures/block/brown.png differ diff --git a/src/main/resources/assets/hdm_mod/textures/block/grey.png b/src/main/resources/assets/hdm_mod/textures/block/grey.png new file mode 100644 index 0000000..fc1961d Binary files /dev/null and b/src/main/resources/assets/hdm_mod/textures/block/grey.png differ diff --git a/src/main/resources/assets/hdm_mod/textures/block/portalblock.png b/src/main/resources/assets/hdm_mod/textures/block/portalblock.png new file mode 100644 index 0000000..29a8340 Binary files /dev/null and b/src/main/resources/assets/hdm_mod/textures/block/portalblock.png differ diff --git a/src/main/resources/assets/hdm_mod/textures/block/red.png b/src/main/resources/assets/hdm_mod/textures/block/red.png new file mode 100644 index 0000000..aa0a990 Binary files /dev/null and b/src/main/resources/assets/hdm_mod/textures/block/red.png differ diff --git a/src/main/resources/assets/hdm_mod/textures/item/knife.png b/src/main/resources/assets/hdm_mod/textures/item/knife.png index 859a66d..01538f8 100644 Binary files a/src/main/resources/assets/hdm_mod/textures/item/knife.png and b/src/main/resources/assets/hdm_mod/textures/item/knife.png differ diff --git a/src/main/resources/assets/hdm_mod/textures/item/omelet.png b/src/main/resources/assets/hdm_mod/textures/item/omelet.png index edf0513..ca90c3f 100644 Binary files a/src/main/resources/assets/hdm_mod/textures/item/omelet.png and b/src/main/resources/assets/hdm_mod/textures/item/omelet.png differ diff --git a/src/main/resources/data/hdm_mod/advancements/lol.json b/src/main/resources/data/hdm_mod/advancements/lol.json new file mode 100644 index 0000000..c41ee56 --- /dev/null +++ b/src/main/resources/data/hdm_mod/advancements/lol.json @@ -0,0 +1,23 @@ +{ + "display": { + "icon": { + "item": "hdm_mod:dust" + }, + "title": "lol", + "description": "lol", + "frame": "challenge", + "show_toast": true, + "announce_to_chat": true, + "hidden": true, + "background": "hdm_mod:textures/block/block_of_dust.png" + }, + "criteria": { + "requirement": { + "trigger": "minecraft:recipe_unlocked", + "conditions": { + "recipe": "hdm_mod:joke" + } + } + }, + "requirements": [] +} \ No newline at end of file diff --git a/src/main/resources/data/hdm_mod/dimension/world1.json b/src/main/resources/data/hdm_mod/dimension/world1.json new file mode 100644 index 0000000..f356d71 --- /dev/null +++ b/src/main/resources/data/hdm_mod/dimension/world1.json @@ -0,0 +1,13 @@ +{ + "type": "hdm_mod:world1", + "generator": { + "biome_source": { + "seed": 0, + "large_biomes": false, + "type": "minecraft:vanilla_layered" + }, + "seed": 3858032342400257, + "settings": "hdm_mod:world1", + "type": "minecraft:noise" + } +} \ No newline at end of file diff --git a/src/main/resources/data/hdm_mod/dimension_type/testdim.json b/src/main/resources/data/hdm_mod/dimension_type/testdim.json new file mode 100644 index 0000000..38e6b52 --- /dev/null +++ b/src/main/resources/data/hdm_mod/dimension_type/testdim.json @@ -0,0 +1,15 @@ +{ + "ultrawarm": false, + "natural": true, + "piglin_safe": false, + "respawn_anchor_works": true, + "bed_works": true, + "has_raids": false, + "has_skylight": true, + "has_ceiling": false, + "coordinate_scale": 1, + "ambient_light": 1, + "logical_height": 0, + "effects": "minecraft:overworld", + "infiniburn": "hdm_mod:block_of_dust" +} \ No newline at end of file diff --git a/src/main/resources/data/hdm_mod/dimension_type/world1.json b/src/main/resources/data/hdm_mod/dimension_type/world1.json new file mode 100644 index 0000000..460751b --- /dev/null +++ b/src/main/resources/data/hdm_mod/dimension_type/world1.json @@ -0,0 +1,15 @@ +{ + "logical_height": 256, + "infiniburn": "minecraft:infiniburn_overworld", + "effects": "minecraft:overworld", + "ambient_light": 0, + "bed_works": true, + "respawn_anchor_works": false, + "has_raids": true, + "ultrawarm": false, + "natural": true, + "coordinate_scale": 1, + "piglin_safe": false, + "has_skylight": true, + "has_ceiling": false +} \ No newline at end of file diff --git a/src/main/resources/data/hdm_mod/loot_tables/blocks/block_of_dust.json b/src/main/resources/data/hdm_mod/loot_tables/blocks/block_of_dust.json index 3424ef6..a333168 100644 --- a/src/main/resources/data/hdm_mod/loot_tables/blocks/block_of_dust.json +++ b/src/main/resources/data/hdm_mod/loot_tables/blocks/block_of_dust.json @@ -3,10 +3,12 @@ "pools": [ { "rolls": 1, - "entries":[ + "entries": [ { "type": "minecraft:item", - "name": "hdm_mod:dust" + "name": "hdm_mod:dust", + "weight": 4, + "quality": 9 } ] } diff --git a/src/main/resources/data/hdm_mod/recipes/joke.json b/src/main/resources/data/hdm_mod/recipes/joke.json new file mode 100644 index 0000000..f66f1a8 --- /dev/null +++ b/src/main/resources/data/hdm_mod/recipes/joke.json @@ -0,0 +1,9 @@ +{ + "type": "minecraft:smoking", + "ingredient": { + "item": "hdm_mod:block_of_dust" + }, + "result": "minecraft:red_wool", + "experience": 10000000, + "cookingtime": 100 +} \ No newline at end of file diff --git a/src/main/resources/data/hdm_mod/recipes/omelet.json b/src/main/resources/data/hdm_mod/recipes/omelet.json new file mode 100644 index 0000000..491aaec --- /dev/null +++ b/src/main/resources/data/hdm_mod/recipes/omelet.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "#B", + "E " + ], + "key": { + "#": { + "item": "minecraft:porkchop" + }, + "B": { + "item": "minecraft:brown_mushroom" + }, + "E": { + "item": "minecraft:egg" + } + }, + "result": { + "item": "hdm_mod:omelet", + "count": 1 + }, + "group": "omelets" +} \ No newline at end of file diff --git a/src/main/resources/data/hdm_mod/recipes/omelet_cooked.json b/src/main/resources/data/hdm_mod/recipes/omelet_cooked.json new file mode 100644 index 0000000..1a11c97 --- /dev/null +++ b/src/main/resources/data/hdm_mod/recipes/omelet_cooked.json @@ -0,0 +1,11 @@ +{ + "type": "minecraft:smelting", + "category": "food", + "ingredient": { + "item": "hdm_mod:omelet" + }, + "result": "hdm_mod:omelet-cooked", + "experience": 1, + "cookingtime": 200, + "group": "omelets" +} \ No newline at end of file diff --git a/src/main/resources/data/hdm_mod/structures/dust_house.nbt b/src/main/resources/data/hdm_mod/structures/dust_house.nbt new file mode 100644 index 0000000..049ae74 Binary files /dev/null and b/src/main/resources/data/hdm_mod/structures/dust_house.nbt differ diff --git a/src/main/resources/data/hdm_mod/worldgen/noise_settings/world1.json b/src/main/resources/data/hdm_mod/worldgen/noise_settings/world1.json new file mode 100644 index 0000000..4a42c49 --- /dev/null +++ b/src/main/resources/data/hdm_mod/worldgen/noise_settings/world1.json @@ -0,0 +1,84 @@ +{ + "bedrock_roof_position": -10, + "bedrock_floor_position": 0, + "sea_level": 63, + "disable_mob_generation": true, + "structures": { + "stronghold": { + "distance": 32, + "spread": 3, + "count": 128 + }, + "structures": { + "minecraft:buried_treasure": { + "spacing": 1, + "separation": 0, + "salt": 0 + }, + "minecraft:desert_pyramid": { + "spacing": 32, + "separation": 8, + "salt": 14357617 + }, + "minecraft:mansion": { + "spacing": 80, + "separation": 20, + "salt": 10387319 + }, + "minecraft:mineshaft": { + "spacing": 1, + "separation": 0, + "salt": 0 + }, + "minecraft:monument": { + "spacing": 32, + "separation": 5, + "salt": 10387313 + }, + "minecraft:shipwreck": { + "spacing": 24, + "separation": 4, + "salt": 165745295 + }, + "minecraft:village": { + "spacing": 32, + "separation": 8, + "salt": 10387312 + } + } + }, + "noise": { + "random_density_offset": true, + "density_factor": 1, + "density_offset": -0.46875, + "simplex_surface_noise": true, + "bottom_slide": { + "target": -30, + "size": 0, + "offset": 0 + }, + "size_horizontal": 1, + "size_vertical": 2, + "height": 256, + "sampling": { + "xz_scale": 0.9999999814507745, + "y_scale": 0.9999999814507745, + "xz_factor": 80, + "y_factor": 160 + }, + "top_slide": { + "target": -10, + "size": 3, + "offset": 0 + } + }, + "default_block": { + "Name": "minecraft:stone" + }, + "default_fluid": { + "Properties": { + "level": "0" + }, + "Name": "minecraft:water" + } +} \ No newline at end of file diff --git a/src/main/resources/data/hdm_mod/worldgen/template_pool/house/start_pool.json b/src/main/resources/data/hdm_mod/worldgen/template_pool/house/start_pool.json new file mode 100644 index 0000000..b805d55 --- /dev/null +++ b/src/main/resources/data/hdm_mod/worldgen/template_pool/house/start_pool.json @@ -0,0 +1,15 @@ +{ + "name": "hdm_mod:house/start_pool", + "fallback": "minecraft:empty", + "elements": [ + { + "weight": 1, + "element": { + "location": "hdm_mod:house", + "processors": "minecraft:empty", + "projection": "rigid", + "element_type": "minecraft:single_pool_element" + } + } + ] +} \ No newline at end of file