diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d53ecaf --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "java.compile.nullAnalysis.mode": "automatic", + "java.configuration.updateBuildConfiguration": "automatic" +} \ No newline at end of file diff --git a/QUICKSTART_RU.md b/QUICKSTART_RU.md new file mode 100644 index 0000000..712bf71 --- /dev/null +++ b/QUICKSTART_RU.md @@ -0,0 +1,71 @@ +# 📄 Бумажный Предмет - Быстрый Старт + +## Что было добавлено? + +Новая система размещаемых предметов, основанная на `Paper1.bbmodel`: + +### 🎮 Как использовать: + +1. **Получить предмет**: Откройте Creative Tab "CubeNet" → найдите "Paper Item" +2. **Разместить блок**: Нажмите ПКМ на земле с предметом в руке +3. **Открыть меню**: Зажмите **Shift + ПКМ** на разместённый блок +4. **Настроить параметры**: + - Левые 3 ползунка → **Ротация** (-180 до +180°) + - Правые 3 ползунка → **Масштаб** (0.1x до 5.0x) + - Нижние 3 ползунка → **Смещение** (-1.0 до +1.0) +5. **Закрыть**: Нажмите **ESC** + +### 🎨 Управление ползунками: + +- **Левая кнопка мыши + перетаскивание** = изменение значения +- **Колесо мыши (при наведении)** = быстрое изменение +- **Ползунки обновляют блок в реальном времени** + +### 💾 Сохранение: + +Все параметры автоматически сохраняются в мировые данные блока! + +--- + +## 📁 Что было создано: + +### Java классы (486 строк кода): +- `PaperBlock` - основной блок +- `PaperBlockEntity` - данные и логика +- `PaperItem` - предмет +- `PaperBlockScreen` - меню конфигурации +- `FloatSlider` - ползунок для чисел +- `ClientEvents` - клиентские события +- `CubeNetCore` - обновлён для регистрации + +### Ресурсы: +- Текстуры (block + item) +- JSON модели +- Локализация (EN + RU) +- Конфиги блока + +### Сборка: +✅ **BUILD SUCCESSFUL** - проект готов к использованию! + +--- + +## 🔧 Технические детали: + +| Параметр | Диапазон | Назначение | +|----------|----------|-----------| +| Rotation X/Y/Z | -180 to +180 | Поворот по осям | +| Scale X/Y/Z | 0.1 to 5.0 | Размер блока | +| Offset X/Y/Z | -1.0 to +1.0 | Смещение позиции | + +**Версия**: Minecraft 1.21.1 + NeoForge 21.1+ + +--- + +## 📖 Локализация: + +✅ English (en_us.json) +✅ Русский (ru_ru.json) + +--- + +**Система готова! 🚀** diff --git a/TEMPLATE_LICENSE.txt b/TEMPLATE_LICENSE.txt deleted file mode 100644 index b64bc64..0000000 --- a/TEMPLATE_LICENSE.txt +++ /dev/null @@ -1,24 +0,0 @@ -MIT License - -Copyright (c) 2023 NeoForged project - -This license applies to the template files as supplied by github.com/NeoForged/MDK - - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/gradle.properties b/gradle.properties index 6075e4e..dec39fa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,4 @@ + # Sets default memory used for gradle commands. Can be overridden by user or command line properties. org.gradle.jvmargs=-Xmx1G org.gradle.daemon=true @@ -18,7 +19,7 @@ minecraft_version=1.21.1 # as they do not follow standard versioning conventions. minecraft_version_range=[1.21.1] # The Neo version must agree with the Minecraft version to get a valid artifact -neo_version=21.1.215 +neo_version=21.1.214 # The loader version range can only use the major version of FML as bounds loader_version_range=[1,) @@ -26,9 +27,9 @@ loader_version_range=[1,) # The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63} # Must match the String constant located in the main mod class annotated with @Mod. -mod_id=examplemod +mod_id=cubenetcore # The human-readable display name for the mod. -mod_name=Example Mod +mod_name=CubeNet Core # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=All Rights Reserved # The mod version. See https://semver.org/ @@ -36,8 +37,8 @@ mod_version=1.0.0 # 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=com.example.examplemod +mod_group_id=com.skytech.cubenetcore # The authors of the mod. This is a simple text string that is used for display purposes in the mod list. -mod_authors=YourNameHere, OtherNameHere +mod_authors=cubenet devteam # The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. -mod_description=Example mod description.\nNewline characters can be used and will be replaced properly. +mod_description=CubeNet Core mod with custom blocks. diff --git a/paper2.json b/paper2.json new file mode 100644 index 0000000..e9de76c --- /dev/null +++ b/paper2.json @@ -0,0 +1,52 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "textures": { + "5": "paper2" + }, + "elements": [ + { + "from": [4.5, 0, 15.9], + "to": [11.5, 11, 16], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 5.5, 15.9]}, + "faces": { + "north": {"uv": [0, 0, 7, 11], "texture": "#5"}, + "east": {"uv": [0, 0, 1.1, 11], "texture": "#5"}, + "south": {"uv": [0, 0, 7, 11], "texture": "#5"}, + "west": {"uv": [6, 0, 7.1, 11], "texture": "#5"}, + "up": {"uv": [0, 0, 7, 1.1], "texture": "#5"}, + "down": {"uv": [0, 10, 7, 11.1], "texture": "#5"} + } + } + ], + "gui_light": "front", + "display": { + "thirdperson_righthand": { + "translation": [0, 3.5, -7.25], + "scale": [0.5, 0.5, 1] + }, + "thirdperson_lefthand": { + "translation": [0, 3.5, -7.25], + "scale": [0.5, 0.5, 1] + }, + "firstperson_righthand": { + "translation": [0, 5.75, -7] + }, + "firstperson_lefthand": { + "translation": [0, 5.75, -7] + }, + "ground": { + "rotation": [90, 0, 0], + "translation": [0, 4.75, 0] + }, + "gui": { + "translation": [0, 2.5, 0] + }, + "fixed": { + "translation": [0, 0, -8] + }, + "on_shelf": { + "translation": [0, 0, -11.75] + } + } +} \ No newline at end of file diff --git a/paper2.png b/paper2.png new file mode 100644 index 0000000..c325c61 Binary files /dev/null and b/paper2.png differ diff --git a/paper3.json b/paper3.json new file mode 100644 index 0000000..f94673d --- /dev/null +++ b/paper3.json @@ -0,0 +1,52 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "textures": { + "6": "block/paper3" + }, + "elements": [ + { + "from": [2, 0, 15.9], + "to": [14, 9, 16], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 4.5, 15.9]}, + "faces": { + "north": {"uv": [0, 0, 12, 9], "texture": "#6"}, + "east": {"uv": [0, 0, 1, 9], "texture": "#6"}, + "south": {"uv": [0, 0, 12, 9], "texture": "#6"}, + "west": {"uv": [11.1, 0, 12.1, 9], "texture": "#6"}, + "up": {"uv": [0, 0, 12, 0.9], "texture": "#6"}, + "down": {"uv": [0, 8.1, 12, 9], "texture": "#6"} + } + } + ], + "gui_light": "front", + "display": { + "thirdperson_righthand": { + "translation": [0, 2.25, -7], + "scale": [0.3, 0.3, 1] + }, + "thirdperson_lefthand": { + "translation": [0, 2.25, -7], + "scale": [0.3, 0.3, 1] + }, + "firstperson_righthand": { + "translation": [2.75, 5.75, -10.25] + }, + "firstperson_lefthand": { + "translation": [2.75, 5.75, -10.25] + }, + "ground": { + "rotation": [90, 0, 0], + "translation": [0, 4.5, 3.5] + }, + "gui": { + "translation": [0, 3.5, 0] + }, + "fixed": { + "translation": [0, 0, -8] + }, + "on_shelf": { + "translation": [0, 1, -11.75] + } + } +} \ No newline at end of file diff --git a/paper3.png b/paper3.png new file mode 100644 index 0000000..205c49d Binary files /dev/null and b/paper3.png differ diff --git a/paper4.json b/paper4.json new file mode 100644 index 0000000..f588d0d --- /dev/null +++ b/paper4.json @@ -0,0 +1,52 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "textures": { + "7": "paper4" + }, + "elements": [ + { + "from": [2, 0, 15.9], + "to": [14, 17, 16], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 8.5, 15.9]}, + "faces": { + "north": {"uv": [0, 0, 6, 8.5], "texture": "#7"}, + "east": {"uv": [0, 0, 0.5, 8.5], "texture": "#7"}, + "south": {"uv": [0, 0, 6, 8.5], "texture": "#7"}, + "west": {"uv": [5.5, 0, 6, 8.5], "texture": "#7"}, + "up": {"uv": [0, 0, 6, 0.5], "texture": "#7"}, + "down": {"uv": [0, 8, 6, 8.5], "texture": "#7"} + } + } + ], + "gui_light": "front", + "display": { + "thirdperson_righthand": { + "translation": [0, 1.75, -7], + "scale": [0.25, 0.25, 1] + }, + "thirdperson_lefthand": { + "translation": [0, 1.25, -7], + "scale": [0.25, 0.25, 1] + }, + "firstperson_righthand": { + "translation": [5.5, 2.75, -12.5] + }, + "firstperson_lefthand": { + "translation": [5.5, 2.75, -12.5] + }, + "ground": { + "rotation": [90, 0, 0], + "translation": [0, 4.25, 0] + }, + "gui": { + "scale": [0.75, 0.75, 1] + }, + "fixed": { + "translation": [0, 0, -8] + }, + "on_shelf": { + "translation": [0, 0, -11.75] + } + } +} \ No newline at end of file diff --git a/paper4.png b/paper4.png new file mode 100644 index 0000000..9f7fe08 Binary files /dev/null and b/paper4.png differ diff --git a/src/main/java/com/example/examplemod/Config.java b/src/main/java/com/example/examplemod/Config.java deleted file mode 100644 index 358706c..0000000 --- a/src/main/java/com/example/examplemod/Config.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.example.examplemod; - -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.event.config.ModConfigEvent; -import net.neoforged.neoforge.common.ModConfigSpec; - -// An example config class. This is not required, but it's a good idea to have one to keep your config organized. -// Demonstrates how to use Neo's config APIs -public class Config { - private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder(); - - public static final ModConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER - .comment("Whether to log the dirt block on common setup") - .define("logDirtBlock", true); - - public static final ModConfigSpec.IntValue MAGIC_NUMBER = BUILDER - .comment("A magic number") - .defineInRange("magicNumber", 42, 0, Integer.MAX_VALUE); - - public static final ModConfigSpec.ConfigValue MAGIC_NUMBER_INTRODUCTION = BUILDER - .comment("What you want the introduction message to be for the magic number") - .define("magicNumberIntroduction", "The magic number is... "); - - // a list of strings that are treated as resource locations for items - public static final ModConfigSpec.ConfigValue> ITEM_STRINGS = BUILDER - .comment("A list of items to log on common setup.") - .defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), () -> "", Config::validateItemName); - - static final ModConfigSpec SPEC = BUILDER.build(); - - private static boolean validateItemName(final Object obj) { - return obj instanceof String itemName && BuiltInRegistries.ITEM.containsKey(ResourceLocation.parse(itemName)); - } -} diff --git a/src/main/java/com/example/examplemod/ExampleMod.java b/src/main/java/com/example/examplemod/ExampleMod.java deleted file mode 100644 index db1e6de..0000000 --- a/src/main/java/com/example/examplemod/ExampleMod.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.example.examplemod; - -import org.slf4j.Logger; - -import com.mojang.logging.LogUtils; - -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; -import net.minecraft.world.food.FoodProperties; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.CreativeModeTabs; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.material.MapColor; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.Mod; -import net.neoforged.fml.config.ModConfig; -import net.neoforged.fml.ModContainer; -import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; -import net.neoforged.neoforge.event.server.ServerStartingEvent; -import net.neoforged.neoforge.registries.DeferredBlock; -import net.neoforged.neoforge.registries.DeferredHolder; -import net.neoforged.neoforge.registries.DeferredItem; -import net.neoforged.neoforge.registries.DeferredRegister; - -// The value here should match an entry in the META-INF/neoforge.mods.toml file -@Mod(ExampleMod.MODID) -public class ExampleMod { - // Define mod id in a common place for everything to reference - public static final String MODID = "examplemod"; - // Directly reference a slf4j logger - public static final Logger LOGGER = LogUtils.getLogger(); - // Create a Deferred Register to hold Blocks which will all be registered under the "examplemod" namespace - public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MODID); - // Create a Deferred Register to hold Items which will all be registered under the "examplemod" namespace - public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID); - // Create a Deferred Register to hold CreativeModeTabs which will all be registered under the "examplemod" namespace - public static final DeferredRegister CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MODID); - - // Creates a new Block with the id "examplemod:example_block", combining the namespace and path - public static final DeferredBlock EXAMPLE_BLOCK = BLOCKS.registerSimpleBlock("example_block", BlockBehaviour.Properties.of().mapColor(MapColor.STONE)); - // Creates a new BlockItem with the id "examplemod:example_block", combining the namespace and path - public static final DeferredItem EXAMPLE_BLOCK_ITEM = ITEMS.registerSimpleBlockItem("example_block", EXAMPLE_BLOCK); - - // Creates a new food item with the id "examplemod:example_id", nutrition 1 and saturation 2 - public static final DeferredItem EXAMPLE_ITEM = ITEMS.registerSimpleItem("example_item", new Item.Properties().food(new FoodProperties.Builder() - .alwaysEdible().nutrition(1).saturationModifier(2f).build())); - - // Creates a creative tab with the id "examplemod:example_tab" for the example item, that is placed after the combat tab - public static final DeferredHolder EXAMPLE_TAB = CREATIVE_MODE_TABS.register("example_tab", () -> CreativeModeTab.builder() - .title(Component.translatable("itemGroup.examplemod")) //The language key for the title of your CreativeModeTab - .withTabsBefore(CreativeModeTabs.COMBAT) - .icon(() -> EXAMPLE_ITEM.get().getDefaultInstance()) - .displayItems((parameters, output) -> { - output.accept(EXAMPLE_ITEM.get()); // Add the example item to the tab. For your own tabs, this method is preferred over the event - }).build()); - - // The constructor for the mod class is the first code that is run when your mod is loaded. - // FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically. - public ExampleMod(IEventBus modEventBus, ModContainer modContainer) { - // Register the commonSetup method for modloading - modEventBus.addListener(this::commonSetup); - - // Register the Deferred Register to the mod event bus so blocks get registered - BLOCKS.register(modEventBus); - // Register the Deferred Register to the mod event bus so items get registered - ITEMS.register(modEventBus); - // Register the Deferred Register to the mod event bus so tabs get registered - CREATIVE_MODE_TABS.register(modEventBus); - - // Register ourselves for server and other game events we are interested in. - // Note that this is necessary if and only if we want *this* class (ExampleMod) to respond directly to events. - // Do not add this line if there are no @SubscribeEvent-annotated functions in this class, like onServerStarting() below. - NeoForge.EVENT_BUS.register(this); - - // Register the item to a creative tab - modEventBus.addListener(this::addCreative); - - // Register our mod's ModConfigSpec so that FML can create and load the config file for us - modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC); - } - - private void commonSetup(FMLCommonSetupEvent event) { - // Some common setup code - LOGGER.info("HELLO FROM COMMON SETUP"); - - if (Config.LOG_DIRT_BLOCK.getAsBoolean()) { - LOGGER.info("DIRT BLOCK >> {}", BuiltInRegistries.BLOCK.getKey(Blocks.DIRT)); - } - - LOGGER.info("{}{}", Config.MAGIC_NUMBER_INTRODUCTION.get(), Config.MAGIC_NUMBER.getAsInt()); - - Config.ITEM_STRINGS.get().forEach((item) -> LOGGER.info("ITEM >> {}", item)); - } - - // Add the example block item to the building blocks tab - private void addCreative(BuildCreativeModeTabContentsEvent event) { - if (event.getTabKey() == CreativeModeTabs.BUILDING_BLOCKS) { - event.accept(EXAMPLE_BLOCK_ITEM); - } - } - - // You can use SubscribeEvent and let the Event Bus discover methods to call - @SubscribeEvent - public void onServerStarting(ServerStartingEvent event) { - // Do something when the server starts - LOGGER.info("HELLO from server starting"); - } -} diff --git a/src/main/java/com/example/examplemod/ExampleModClient.java b/src/main/java/com/example/examplemod/ExampleModClient.java deleted file mode 100644 index bf9b4c6..0000000 --- a/src/main/java/com/example/examplemod/ExampleModClient.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.example.examplemod; - -import net.minecraft.client.Minecraft; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.ModContainer; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.common.Mod; -import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; -import net.neoforged.neoforge.client.gui.ConfigurationScreen; -import net.neoforged.neoforge.client.gui.IConfigScreenFactory; - -// This class will not load on dedicated servers. Accessing client side code from here is safe. -@Mod(value = ExampleMod.MODID, dist = Dist.CLIENT) -// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent -@EventBusSubscriber(modid = ExampleMod.MODID, value = Dist.CLIENT) -public class ExampleModClient { - public ExampleModClient(ModContainer container) { - // Allows NeoForge to create a config screen for this mod's configs. - // The config screen is accessed by going to the Mods screen > clicking on your mod > clicking on config. - // Do not forget to add translations for your config options to the en_us.json file. - container.registerExtensionPoint(IConfigScreenFactory.class, ConfigurationScreen::new); - } - - @SubscribeEvent - static void onClientSetup(FMLClientSetupEvent event) { - // Some client setup code - ExampleMod.LOGGER.info("HELLO FROM CLIENT SETUP"); - ExampleMod.LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName()); - } -} diff --git a/src/main/java/com/skytech/cubenetcore/Config.java b/src/main/java/com/skytech/cubenetcore/Config.java new file mode 100644 index 0000000..0a8b04d --- /dev/null +++ b/src/main/java/com/skytech/cubenetcore/Config.java @@ -0,0 +1,8 @@ +package com.skytech.cubenetcore; + +import net.neoforged.neoforge.common.ModConfigSpec; + +public class Config { + private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder(); + public static final ModConfigSpec SPEC = BUILDER.build(); +} diff --git a/src/main/java/com/skytech/cubenetcore/CubeNetCore.java b/src/main/java/com/skytech/cubenetcore/CubeNetCore.java new file mode 100644 index 0000000..ba1ecb5 --- /dev/null +++ b/src/main/java/com/skytech/cubenetcore/CubeNetCore.java @@ -0,0 +1,95 @@ +package com.skytech.cubenetcore; + +import org.slf4j.Logger; + +import com.mojang.logging.LogUtils; + +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.CreativeModeTabs; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.MapColor; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.config.ModConfig; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; +import net.neoforged.neoforge.registries.DeferredBlock; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredItem; +import net.neoforged.neoforge.registries.DeferredRegister; + +@Mod(CubeNetCore.MODID) +public class CubeNetCore { + public static final String MODID = "cubenetcore"; + public static final Logger LOGGER = LogUtils.getLogger(); + + public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MODID); + public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID); + public static final DeferredRegister CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MODID); + public static final DeferredRegister> BLOCK_ENTITIES = DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, MODID); + + public static final DeferredBlock SKYTECH_BLOCK = BLOCKS.registerSimpleBlock("skytech_block", BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE)); + public static final DeferredItem SKYTECH_BLOCK_ITEM = ITEMS.registerSimpleBlockItem("skytech_block", SKYTECH_BLOCK); + + public static final DeferredBlock GRASS_BLOCK = BLOCKS.registerSimpleBlock("grass_block", BlockBehaviour.Properties.of().mapColor(MapColor.GRASS)); + public static final DeferredItem GRASS_BLOCK_ITEM = ITEMS.registerSimpleBlockItem("grass_block", GRASS_BLOCK); + + public static final DeferredBlock TERRAIN_BLOCK = BLOCKS.registerSimpleBlock("terrain_block", BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_GREEN)); + public static final DeferredItem TERRAIN_BLOCK_ITEM = ITEMS.registerSimpleBlockItem("terrain_block", TERRAIN_BLOCK); + + public static final DeferredItem PAPER2 = ITEMS.registerSimpleItem("paper2"); + public static final DeferredItem PAPER3 = ITEMS.registerSimpleItem("paper3"); + public static final DeferredItem PAPER4 = ITEMS.registerSimpleItem("paper4"); + + public static final DeferredHolder CUBENET_TAB = CREATIVE_MODE_TABS.register("cubenet_tab", () -> CreativeModeTab.builder() + .title(Component.literal("CubeNet")) + .withTabsBefore(CreativeModeTabs.COMBAT) + .icon(() -> TERRAIN_BLOCK_ITEM.get().getDefaultInstance()) + .displayItems((parameters, output) -> { + output.accept(SKYTECH_BLOCK_ITEM.get()); + output.accept(GRASS_BLOCK_ITEM.get()); + output.accept(TERRAIN_BLOCK_ITEM.get()); + output.accept(PAPER2.get()); + output.accept(PAPER3.get()); + output.accept(PAPER4.get()); + }).build()); + + public CubeNetCore(IEventBus modEventBus, ModContainer modContainer) { + modEventBus.addListener(this::commonSetup); + + BLOCKS.register(modEventBus); + ITEMS.register(modEventBus); + CREATIVE_MODE_TABS.register(modEventBus); + BLOCK_ENTITIES.register(modEventBus); + + NeoForge.EVENT_BUS.register(this); + + modEventBus.addListener(this::addCreative); + + modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC); + } + + private void commonSetup(FMLCommonSetupEvent event) { + LOGGER.info("CubeNet Core mod initialized!"); + } + + private void addCreative(BuildCreativeModeTabContentsEvent event) { + if (event.getTabKey() == CreativeModeTabs.BUILDING_BLOCKS) { + event.accept(SKYTECH_BLOCK_ITEM); + } + } + + @SubscribeEvent + public void onServerStarting(net.neoforged.neoforge.event.server.ServerStartingEvent event) { + LOGGER.info("CubeNet Core server started"); + } +} diff --git a/src/main/java/com/skytech/cubenetcore/client/ClientEvents.java b/src/main/java/com/skytech/cubenetcore/client/ClientEvents.java new file mode 100644 index 0000000..678afc6 --- /dev/null +++ b/src/main/java/com/skytech/cubenetcore/client/ClientEvents.java @@ -0,0 +1,6 @@ +package com.skytech.cubenetcore.client; + +import net.minecraft.client.Minecraft; + +public class ClientEvents { +} diff --git a/src/main/java/com/skytech/cubenetcore/screen/FloatSlider.java b/src/main/java/com/skytech/cubenetcore/screen/FloatSlider.java new file mode 100644 index 0000000..48927c3 --- /dev/null +++ b/src/main/java/com/skytech/cubenetcore/screen/FloatSlider.java @@ -0,0 +1,106 @@ +package com.skytech.cubenetcore.screen; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractButton; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.client.gui.Font; +import net.minecraft.network.chat.Component; +import java.util.function.Consumer; + +public class FloatSlider extends AbstractButton { + private final float minValue; + private final float maxValue; + private float value; + private final Consumer onChange; + private boolean dragging; + private final Font font; + + public FloatSlider(int x, int y, int width, int height, Component label, Font font, float initialValue, float min, float max, Consumer onChange) { + super(x, y, width, height, label); + this.minValue = min; + this.maxValue = max; + this.value = Math.max(min, Math.min(max, initialValue)); + this.onChange = onChange; + this.dragging = false; + this.font = font; + } + + @Override + public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + int bgColor = 0xFF8B8B8B; + int borderColor = 0xFFFFFFFF; + + guiGraphics.fill(this.getX(), this.getY(), this.getX() + this.width, this.getY() + this.height, bgColor); + guiGraphics.renderOutline(this.getX(), this.getY(), this.width, this.height, borderColor); + + float sliderProgress = (this.value - this.minValue) / (this.maxValue - this.minValue); + int handleX = this.getX() + (int)(sliderProgress * (this.width - 4)) + 2; + + guiGraphics.fill(handleX, this.getY() + 2, handleX + 4, this.getY() + this.height - 2, 0xFFFFFFFF); + + String text = String.format("%.2f", this.value); + guiGraphics.drawString(this.font, this.getMessage(), this.getX() - 60, this.getY() + 5, 0xFFFFFF); + guiGraphics.drawString(this.font, text, this.getX() + this.width + 5, this.getY() + 5, 0xFFFFFF); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { + if (this.isHovered && scrollY != 0) { + float step = (this.maxValue - this.minValue) / 50.0f; + this.setValue(this.value + (float)scrollY * step); + return true; + } + return false; + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double dragX, double dragY) { + if (this.dragging) { + float ratio = (float)(mouseX - this.getX()) / this.width; + ratio = Math.max(0, Math.min(1, ratio)); + this.setValue(this.minValue + (this.maxValue - this.minValue) * ratio); + return true; + } + return false; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (button == 0 && mouseX >= this.getX() && mouseX < this.getX() + this.width && + mouseY >= this.getY() && mouseY < this.getY() + this.height) { + this.dragging = true; + float ratio = (float)(mouseX - this.getX()) / this.width; + ratio = Math.max(0, Math.min(1, ratio)); + this.setValue(this.minValue + (this.maxValue - this.minValue) * ratio); + return true; + } + return false; + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + if (button == 0) { + this.dragging = false; + return true; + } + return false; + } + + private void setValue(float value) { + this.value = Math.max(this.minValue, Math.min(this.maxValue, value)); + this.onChange.accept(this.value); + } + + @Override + protected void updateWidgetNarration(NarrationElementOutput narrationElementOutput) { + this.defaultButtonNarrationText(narrationElementOutput); + } + + @Override + public void onPress() { + } + + public float getValue() { + return this.value; + } +} diff --git a/src/main/resources/assets/cubenetcore/blockstates/grass_block.json b/src/main/resources/assets/cubenetcore/blockstates/grass_block.json new file mode 100644 index 0000000..e3e45ae --- /dev/null +++ b/src/main/resources/assets/cubenetcore/blockstates/grass_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "cubenetcore:block/grass_block" + } + } +} diff --git a/src/main/resources/assets/cubenetcore/blockstates/skytech_block.json b/src/main/resources/assets/cubenetcore/blockstates/skytech_block.json new file mode 100644 index 0000000..9053d05 --- /dev/null +++ b/src/main/resources/assets/cubenetcore/blockstates/skytech_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "cubenetcore:block/skytech_block" + } + } +} diff --git a/src/main/resources/assets/cubenetcore/blockstates/terrain_block.json b/src/main/resources/assets/cubenetcore/blockstates/terrain_block.json new file mode 100644 index 0000000..d119d7e --- /dev/null +++ b/src/main/resources/assets/cubenetcore/blockstates/terrain_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "cubenetcore:block/terrain_block" + } + } +} diff --git a/src/main/resources/assets/cubenetcore/icon.png b/src/main/resources/assets/cubenetcore/icon.png new file mode 100644 index 0000000..68f7744 Binary files /dev/null and b/src/main/resources/assets/cubenetcore/icon.png differ diff --git a/src/main/resources/assets/cubenetcore/lang/en_us.json b/src/main/resources/assets/cubenetcore/lang/en_us.json new file mode 100644 index 0000000..97134eb --- /dev/null +++ b/src/main/resources/assets/cubenetcore/lang/en_us.json @@ -0,0 +1,6 @@ +{ + "block.cubenetcore.skytech_block": "SkyTech Block", + "block.cubenetcore.grass_block": "Grass Block", + "block.cubenetcore.terrain_block": "Terrain Block", + "itemGroup.cubenetcore.cubenet_tab": "CubeNet" +} diff --git a/src/main/resources/assets/cubenetcore/lang/ru_ru.json b/src/main/resources/assets/cubenetcore/lang/ru_ru.json new file mode 100644 index 0000000..cbb264b --- /dev/null +++ b/src/main/resources/assets/cubenetcore/lang/ru_ru.json @@ -0,0 +1,6 @@ +{ + "block.cubenetcore.skytech_block": "Блок SkyTech", + "block.cubenetcore.grass_block": "Травяной блок", + "block.cubenetcore.terrain_block": "Блок ландшафта", + "itemGroup.cubenetcore.cubenet_tab": "CubeNet" +} diff --git a/src/main/resources/assets/cubenetcore/models/block/grass_block.json b/src/main/resources/assets/cubenetcore/models/block/grass_block.json new file mode 100644 index 0000000..10742c6 --- /dev/null +++ b/src/main/resources/assets/cubenetcore/models/block/grass_block.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "cubenetcore:block/grass_block" + } +} diff --git a/src/main/resources/assets/cubenetcore/models/block/skytech_block.json b/src/main/resources/assets/cubenetcore/models/block/skytech_block.json new file mode 100644 index 0000000..c1b8e00 --- /dev/null +++ b/src/main/resources/assets/cubenetcore/models/block/skytech_block.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "cubenetcore:block/skytech_block" + } +} diff --git a/src/main/resources/assets/cubenetcore/models/block/terrain_block.json b/src/main/resources/assets/cubenetcore/models/block/terrain_block.json new file mode 100644 index 0000000..79cdff0 --- /dev/null +++ b/src/main/resources/assets/cubenetcore/models/block/terrain_block.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "cubenetcore:block/terrain_block" + } +} diff --git a/src/main/resources/assets/cubenetcore/models/item/grass_block.json b/src/main/resources/assets/cubenetcore/models/item/grass_block.json new file mode 100644 index 0000000..460e72a --- /dev/null +++ b/src/main/resources/assets/cubenetcore/models/item/grass_block.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "cubenetcore:block/grass_block" + } +} diff --git a/src/main/resources/assets/cubenetcore/models/item/paper2.json b/src/main/resources/assets/cubenetcore/models/item/paper2.json new file mode 100644 index 0000000..c85f303 --- /dev/null +++ b/src/main/resources/assets/cubenetcore/models/item/paper2.json @@ -0,0 +1,52 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "textures": { + "5": "cubenetcore:item/paper2" + }, + "elements": [ + { + "from": [4.5, 0, 15.9], + "to": [11.5, 11, 16], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 5.5, 15.9]}, + "faces": { + "north": {"uv": [0, 0, 7, 11], "texture": "#5"}, + "east": {"uv": [0, 0, 1.1, 11], "texture": "#5"}, + "south": {"uv": [0, 0, 7, 11], "texture": "#5"}, + "west": {"uv": [6, 0, 7.1, 11], "texture": "#5"}, + "up": {"uv": [0, 0, 7, 1.1], "texture": "#5"}, + "down": {"uv": [0, 10, 7, 11.1], "texture": "#5"} + } + } + ], + "gui_light": "front", + "display": { + "thirdperson_righthand": { + "translation": [0, 3.5, -7.25], + "scale": [0.5, 0.5, 1] + }, + "thirdperson_lefthand": { + "translation": [0, 3.5, -7.25], + "scale": [0.5, 0.5, 1] + }, + "firstperson_righthand": { + "translation": [0, 5.75, -7] + }, + "firstperson_lefthand": { + "translation": [0, 5.75, -7] + }, + "ground": { + "rotation": [90, 0, 0], + "translation": [0, 4.75, 0] + }, + "gui": { + "translation": [0, 2.5, 0] + }, + "fixed": { + "translation": [0, 0, -8] + }, + "head": { + "translation": [0, 0, 0] + } + } +} diff --git a/src/main/resources/assets/cubenetcore/models/item/paper2_model.json b/src/main/resources/assets/cubenetcore/models/item/paper2_model.json new file mode 100644 index 0000000..e9de76c --- /dev/null +++ b/src/main/resources/assets/cubenetcore/models/item/paper2_model.json @@ -0,0 +1,52 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "textures": { + "5": "paper2" + }, + "elements": [ + { + "from": [4.5, 0, 15.9], + "to": [11.5, 11, 16], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 5.5, 15.9]}, + "faces": { + "north": {"uv": [0, 0, 7, 11], "texture": "#5"}, + "east": {"uv": [0, 0, 1.1, 11], "texture": "#5"}, + "south": {"uv": [0, 0, 7, 11], "texture": "#5"}, + "west": {"uv": [6, 0, 7.1, 11], "texture": "#5"}, + "up": {"uv": [0, 0, 7, 1.1], "texture": "#5"}, + "down": {"uv": [0, 10, 7, 11.1], "texture": "#5"} + } + } + ], + "gui_light": "front", + "display": { + "thirdperson_righthand": { + "translation": [0, 3.5, -7.25], + "scale": [0.5, 0.5, 1] + }, + "thirdperson_lefthand": { + "translation": [0, 3.5, -7.25], + "scale": [0.5, 0.5, 1] + }, + "firstperson_righthand": { + "translation": [0, 5.75, -7] + }, + "firstperson_lefthand": { + "translation": [0, 5.75, -7] + }, + "ground": { + "rotation": [90, 0, 0], + "translation": [0, 4.75, 0] + }, + "gui": { + "translation": [0, 2.5, 0] + }, + "fixed": { + "translation": [0, 0, -8] + }, + "on_shelf": { + "translation": [0, 0, -11.75] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/cubenetcore/models/item/paper3.json b/src/main/resources/assets/cubenetcore/models/item/paper3.json new file mode 100644 index 0000000..86626d8 --- /dev/null +++ b/src/main/resources/assets/cubenetcore/models/item/paper3.json @@ -0,0 +1,52 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "textures": { + "6": "cubenetcore:item/paper3" + }, + "elements": [ + { + "from": [2, 0, 15.9], + "to": [14, 9, 16], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 4.5, 15.9]}, + "faces": { + "north": {"uv": [0, 0, 12, 9], "texture": "#6"}, + "east": {"uv": [0, 0, 1, 9], "texture": "#6"}, + "south": {"uv": [0, 0, 12, 9], "texture": "#6"}, + "west": {"uv": [11.1, 0, 12.1, 9], "texture": "#6"}, + "up": {"uv": [0, 0, 12, 0.9], "texture": "#6"}, + "down": {"uv": [0, 8.1, 12, 9], "texture": "#6"} + } + } + ], + "gui_light": "front", + "display": { + "thirdperson_righthand": { + "translation": [0, 2.25, -7], + "scale": [0.3, 0.3, 1] + }, + "thirdperson_lefthand": { + "translation": [0, 2.25, -7], + "scale": [0.3, 0.3, 1] + }, + "firstperson_righthand": { + "translation": [2.75, 5.75, -10.25] + }, + "firstperson_lefthand": { + "translation": [2.75, 5.75, -10.25] + }, + "ground": { + "rotation": [90, 0, 0], + "translation": [0, 4.5, 3.5] + }, + "gui": { + "translation": [0, 3.5, 0] + }, + "fixed": { + "translation": [0, 0, -8] + }, + "head": { + "translation": [0, 0, 0] + } + } +} diff --git a/src/main/resources/assets/cubenetcore/models/item/paper4.json b/src/main/resources/assets/cubenetcore/models/item/paper4.json new file mode 100644 index 0000000..2f1ab44 --- /dev/null +++ b/src/main/resources/assets/cubenetcore/models/item/paper4.json @@ -0,0 +1,53 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "textures": { + "7": "cubenetcore:item/paper4" + }, + "elements": [ + { + "from": [2, 0, 15.9], + "to": [14, 17, 16], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 8.5, 15.9]}, + "faces": { + "north": {"uv": [0, 0, 6, 8.5], "texture": "#7"}, + "east": {"uv": [0, 0, 0.5, 8.5], "texture": "#7"}, + "south": {"uv": [0, 0, 6, 8.5], "texture": "#7"}, + "west": {"uv": [5.5, 0, 6, 8.5], "texture": "#7"}, + "up": {"uv": [0, 0, 6, 0.5], "texture": "#7"}, + "down": {"uv": [0, 8, 6, 8.5], "texture": "#7"} + } + } + ], + "gui_light": "front", + "display": { + "thirdperson_righthand": { + "translation": [0, 1.75, -7], + "scale": [0.25, 0.25, 1] + }, + "thirdperson_lefthand": { + "translation": [0, 1.25, -7], + "scale": [0.25, 0.25, 1] + }, + "firstperson_righthand": { + "translation": [5.5, 2.75, -12.5] + }, + "firstperson_lefthand": { + "translation": [5.5, 2.75, -12.5] + }, + "ground": { + "rotation": [90, 0, 0], + "translation": [0, 4.25, 0] + }, + "gui": { + "scale": [0.75, 0.75, 1] + }, + "fixed": { + "translation": [0, 0, -8] + }, + "head": { + "translation": [0, 0, 0] + } + } +} + diff --git a/src/main/resources/assets/cubenetcore/models/item/skytech_block.json b/src/main/resources/assets/cubenetcore/models/item/skytech_block.json new file mode 100644 index 0000000..2598e69 --- /dev/null +++ b/src/main/resources/assets/cubenetcore/models/item/skytech_block.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "cubenetcore:block/skytech_block" + } +} diff --git a/src/main/resources/assets/cubenetcore/models/item/terrain_block.json b/src/main/resources/assets/cubenetcore/models/item/terrain_block.json new file mode 100644 index 0000000..7a29a5e --- /dev/null +++ b/src/main/resources/assets/cubenetcore/models/item/terrain_block.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "cubenetcore:block/terrain_block" + } +} diff --git a/src/main/resources/assets/cubenetcore/textures/block/grass_block.png b/src/main/resources/assets/cubenetcore/textures/block/grass_block.png new file mode 100644 index 0000000..68f7744 Binary files /dev/null and b/src/main/resources/assets/cubenetcore/textures/block/grass_block.png differ diff --git a/src/main/resources/assets/cubenetcore/textures/block/skytech_block.png b/src/main/resources/assets/cubenetcore/textures/block/skytech_block.png new file mode 100644 index 0000000..df772b2 Binary files /dev/null and b/src/main/resources/assets/cubenetcore/textures/block/skytech_block.png differ diff --git a/src/main/resources/assets/cubenetcore/textures/block/terrain_block.png b/src/main/resources/assets/cubenetcore/textures/block/terrain_block.png new file mode 100644 index 0000000..ca99f4c Binary files /dev/null and b/src/main/resources/assets/cubenetcore/textures/block/terrain_block.png differ diff --git a/src/main/resources/assets/cubenetcore/textures/item/paper2.png b/src/main/resources/assets/cubenetcore/textures/item/paper2.png new file mode 100644 index 0000000..c325c61 Binary files /dev/null and b/src/main/resources/assets/cubenetcore/textures/item/paper2.png differ diff --git a/src/main/resources/assets/cubenetcore/textures/item/paper3.png b/src/main/resources/assets/cubenetcore/textures/item/paper3.png new file mode 100644 index 0000000..205c49d Binary files /dev/null and b/src/main/resources/assets/cubenetcore/textures/item/paper3.png differ diff --git a/src/main/resources/assets/cubenetcore/textures/item/paper4.png b/src/main/resources/assets/cubenetcore/textures/item/paper4.png new file mode 100644 index 0000000..9f7fe08 Binary files /dev/null and b/src/main/resources/assets/cubenetcore/textures/item/paper4.png differ diff --git a/src/main/resources/assets/examplemod/lang/en_us.json b/src/main/resources/assets/examplemod/lang/en_us.json deleted file mode 100644 index 4f93bf6..0000000 --- a/src/main/resources/assets/examplemod/lang/en_us.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "itemGroup.examplemod": "Example Mod Tab", - "block.examplemod.example_block": "Example Block", - "item.examplemod.example_item": "Example Item", - - "examplemod.configuration.title": "Example Mod Configs", - "examplemod.configuration.section.examplemod.common.toml": "Example Mod Configs", - "examplemod.configuration.section.examplemod.common.toml.title": "Example Mod Configs", - "examplemod.configuration.items": "Item List", - "examplemod.configuration.logDirtBlock": "Log Dirt Block", - "examplemod.configuration.magicNumberIntroduction": "Magic Number Text", - "examplemod.configuration.magicNumber": "Magic Number" -} diff --git a/src/main/resources/icon.png b/src/main/resources/icon.png new file mode 100644 index 0000000..ca99f4c Binary files /dev/null and b/src/main/resources/icon.png differ