├── .gitattributes ├── .gitignore ├── LICENSE ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src └── main ├── java └── io │ └── github │ └── darealturtywurty │ └── tutorialmod │ ├── TutorialMod.java │ ├── client │ ├── ClientAccess.java │ ├── KeyInit.java │ ├── event │ │ ├── ClientForgeEvents.java │ │ └── ClientModEvents.java │ ├── renderer │ │ ├── ExampleEntityRenderer.java │ │ ├── SeatRenderer.java │ │ ├── block │ │ │ └── DisplayHandBER.java │ │ └── model │ │ │ └── ExampleEntityModel.java │ └── screen │ │ ├── EnergyGeneratorScreen.java │ │ ├── EnergyStorageScreen.java │ │ ├── ExampleChestScreen.java │ │ └── PoopStorageScreen.java │ ├── common │ ├── block │ │ ├── BaseCropBlock.java │ │ ├── DisplayHandBlock.java │ │ ├── DrawerBlock.java │ │ ├── EnergyGeneratorBlock.java │ │ ├── EnergyStorageBlock.java │ │ ├── ExampleChestBlock.java │ │ ├── LightningJumperBlock.java │ │ ├── PoopStorageBlock.java │ │ ├── ToiletBlock.java │ │ └── entity │ │ │ ├── DisplayHandBlockEntity.java │ │ │ ├── DrawerBlockEntity.java │ │ │ ├── EnergyGeneratorBlockEntity.java │ │ │ ├── EnergyStorageBlockEntity.java │ │ │ ├── ExampleChestBlockEntity.java │ │ │ ├── PoopStorageBlockEntity.java │ │ │ ├── ToiletBlockEntity.java │ │ │ └── util │ │ │ ├── CustomEnergyStorage.java │ │ │ └── InventoryBlockEntity.java │ ├── container │ │ ├── EnergyGeneratorContainer.java │ │ ├── ExampleChestContainer.java │ │ ├── PoopStorageContainer.java │ │ └── syncdata │ │ │ ├── EnergyGeneratorContainerData.java │ │ │ └── PoopStorageContainerData.java │ ├── entity │ │ ├── ExampleEntity.java │ │ └── SittableEntity.java │ └── item │ │ ├── ClickerItem.java │ │ └── FuelItem.java │ └── core │ ├── event │ ├── CommonForgeEvents.java │ └── CommonModEvents.java │ ├── init │ ├── ArmorMaterialInit.java │ ├── BlockEntityInit.java │ ├── BlockInit.java │ ├── ContainerInit.java │ ├── EntityInit.java │ ├── ItemInit.java │ ├── PacketHandler.java │ ├── SoundInit.java │ └── ToolMaterialInit.java │ ├── network │ ├── ClientboundUpdateEnergyStorageScreenPacket.java │ ├── ClientboundUpdateToiletPacket.java │ ├── ServerboundGetEnergyStoredPacket.java │ └── ServerboundToiletUpdatePacket.java │ ├── util │ ├── BaseArmorMaterial.java │ └── BaseToolMaterial.java │ └── world │ └── OreGeneration.java └── resources ├── META-INF ├── accesstransformer.cfg └── mods.toml ├── assets └── tutorialmod │ ├── blockstates │ ├── cropium.json │ ├── display_hand.json │ ├── drawer.json │ ├── example_block.json │ ├── example_chest.json │ ├── lightning_jumper.json │ ├── poop_storage.json │ └── toilet.json │ ├── lang │ └── en_us.json │ ├── models │ ├── block │ │ ├── cropium_stage0.json │ │ ├── cropium_stage1.json │ │ ├── cropium_stage2.json │ │ ├── cropium_stage3.json │ │ ├── cropium_stage4.json │ │ ├── cropium_stage5.json │ │ ├── cropium_stage6.json │ │ ├── cropium_stage7.json │ │ ├── drawer.json │ │ ├── example_block.json │ │ ├── example_chest.json │ │ ├── lightning_jumper.json │ │ ├── poop_storage.json │ │ └── toilet.json │ └── item │ │ ├── bean_axe.json │ │ ├── bean_boots.json │ │ ├── bean_chestplate.json │ │ ├── bean_helmet.json │ │ ├── bean_hoe.json │ │ ├── bean_leggings.json │ │ ├── bean_pickaxe.json │ │ ├── bean_shovel.json │ │ ├── bean_sword.json │ │ ├── beans.json │ │ ├── clicker.json │ │ ├── cropium.json │ │ ├── cropium_seeds.json │ │ ├── display_hand.json │ │ ├── drawer.json │ │ ├── example_block.json │ │ ├── example_chest.json │ │ ├── example_entity_spawn_egg.json │ │ ├── example_item.json │ │ ├── lightning_jumper.json │ │ ├── poop.json │ │ ├── poop_storage.json │ │ └── toilet.json │ ├── sounds.json │ ├── sounds │ ├── example_entity_ambient.ogg │ ├── example_entity_death.ogg │ ├── example_entity_hurt.ogg │ └── fart.ogg │ └── textures │ ├── blocks │ ├── cropium_stage0.png │ ├── cropium_stage1.png │ ├── cropium_stage2.png │ ├── cropium_stage3.png │ ├── cropium_stage4.png │ ├── cropium_stage5.png │ ├── cropium_stage6.png │ ├── cropium_stage7.png │ ├── drawer_front.png │ ├── drawer_side.png │ ├── example_block.png │ ├── example_chest_front.png │ ├── example_chest_side.png │ ├── example_chest_top.png │ ├── poop_storage_side.png │ └── poop_storage_top.png │ ├── entities │ └── example_entity.png │ ├── gui │ ├── energy_generator.png │ ├── energy_storage.png │ ├── example_chest.png │ └── poop_storage.png │ ├── items │ ├── bean_axe.png │ ├── bean_boots.png │ ├── bean_chestplate.png │ ├── bean_helmet.png │ ├── bean_hoe.png │ ├── bean_leggings.png │ ├── bean_pickaxe.png │ ├── bean_shovel.png │ ├── bean_sword.png │ ├── beans.png │ ├── clicker.png │ ├── cropium.png │ ├── cropium_seeds.png │ ├── example_item.png │ └── poop.png │ └── models │ └── armor │ ├── bean_layer_1.png │ └── bean_layer_2.png ├── data ├── minecraft │ └── tags │ │ └── blocks │ │ ├── mineable │ │ └── pickaxe.json │ │ └── needs_iron_tool.json └── tutorialmod │ ├── loot_tables │ ├── blocks │ │ ├── cropium.json │ │ └── example_block.json │ └── entities │ │ └── example_entity.json │ └── recipes │ └── bean_leggings.json └── pack.mcmeta /.gitattributes: -------------------------------------------------------------------------------- 1 | # Disable autocrlf on generated files, they always generate with LF 2 | # Add any extra files or paths here to make git stop saying they 3 | # are changed when only line endings change. 4 | src/generated/**/.cache/cache text eol=lf 5 | src/generated/**/*.json text eol=lf 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse 2 | bin 3 | *.launch 4 | .settings 5 | .metadata 6 | .classpath 7 | .project 8 | 9 | # idea 10 | out 11 | *.ipr 12 | *.iws 13 | *.iml 14 | .idea 15 | 16 | # gradle 17 | build 18 | .gradle 19 | 20 | # other 21 | eclipse 22 | run 23 | 24 | # Files from Forge MDK 25 | forge*changelog.txt 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 TurtysProductions 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url = 'https://maven.minecraftforge.net' } 4 | mavenCentral() 5 | } 6 | 7 | dependencies { 8 | classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true 9 | } 10 | } 11 | 12 | apply plugin: 'net.minecraftforge.gradle' 13 | apply plugin: 'eclipse' 14 | apply plugin: 'maven-publish' 15 | 16 | version = '1.0' 17 | group = 'io.github.darealturtywurty.tutorialmod' 18 | archivesBaseName = 'tutorialmod' 19 | 20 | java.toolchain.languageVersion = JavaLanguageVersion.of(17) 21 | 22 | println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) 23 | minecraft { 24 | mappings channel: 'official', version: '1.18.1' 25 | 26 | accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') 27 | 28 | runs { 29 | client { 30 | workingDirectory project.file('run') 31 | 32 | mods { 33 | tutorialmod { 34 | source sourceSets.main 35 | } 36 | } 37 | } 38 | 39 | server { 40 | workingDirectory project.file('run') 41 | 42 | mods { 43 | tutorialmod { 44 | source sourceSets.main 45 | } 46 | } 47 | } 48 | 49 | data { 50 | workingDirectory project.file('run') 51 | 52 | args '--mod', archivesBaseName, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') 53 | 54 | mods { 55 | tutorialmod { 56 | source sourceSets.main 57 | } 58 | } 59 | } 60 | } 61 | } 62 | 63 | sourceSets.main.resources { srcDir 'src/generated/resources' } 64 | 65 | repositories { 66 | } 67 | 68 | dependencies { 69 | minecraft 'net.minecraftforge:forge:1.18.1-39.0.5' 70 | } 71 | 72 | jar { 73 | manifest { 74 | attributes([ 75 | "Specification-Title" : "tutorialmod", 76 | "Specification-Vendor" : "TurtyWurty", 77 | "Specification-Version" : "1", 78 | "Implementation-Title" : project.name, 79 | "Implementation-Version" : project.jar.archiveVersion, 80 | "Implementation-Vendor" : "TurtyWurty", 81 | "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") 82 | ]) 83 | } 84 | } 85 | 86 | jar.finalizedBy('reobfJar') 87 | 88 | publishing { 89 | publications { 90 | mavenJava(MavenPublication) { 91 | artifact jar 92 | } 93 | } 94 | repositories { 95 | maven { 96 | url "file://${project.projectDir}/mcmodsrepo" 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx3G 4 | org.gradle.daemon=false -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/gradlew -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/TutorialMod.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod; 2 | 3 | import java.util.Map.Entry; 4 | import java.util.Optional; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | import org.apache.logging.log4j.LogManager; 9 | import org.apache.logging.log4j.Logger; 10 | 11 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 12 | import io.github.darealturtywurty.tutorialmod.core.init.BlockInit; 13 | import io.github.darealturtywurty.tutorialmod.core.init.ContainerInit; 14 | import io.github.darealturtywurty.tutorialmod.core.init.EntityInit; 15 | import io.github.darealturtywurty.tutorialmod.core.init.ItemInit; 16 | import io.github.darealturtywurty.tutorialmod.core.init.SoundInit; 17 | import net.minecraft.core.Direction; 18 | import net.minecraft.resources.ResourceLocation; 19 | import net.minecraft.world.item.CreativeModeTab; 20 | import net.minecraft.world.item.ItemStack; 21 | import net.minecraft.world.level.block.Block; 22 | import net.minecraft.world.level.block.Blocks; 23 | import net.minecraft.world.phys.shapes.Shapes; 24 | import net.minecraft.world.phys.shapes.VoxelShape; 25 | import net.minecraftforge.fml.common.Mod; 26 | import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 27 | import net.minecraftforge.registries.ForgeRegistries; 28 | 29 | @Mod(TutorialMod.MODID) 30 | public class TutorialMod { 31 | public static final String MODID = "tutorialmod"; 32 | public static final Logger LOGGER = LogManager.getLogger(MODID); 33 | 34 | public static final CreativeModeTab TUTORIAL_TAB = new CreativeModeTab(MODID) { // tutorialmod.itemGroup 35 | @Override 36 | public ItemStack makeIcon() { 37 | return ItemInit.EXAMPLE_ENTITY_SPAWN_EGG.get().getDefaultInstance(); 38 | } 39 | }; 40 | 41 | public TutorialMod() { 42 | final var bus = FMLJavaModLoadingContext.get().getModEventBus(); 43 | 44 | SoundInit.SOUNDS.register(bus); 45 | BlockInit.BLOCKS.register(bus); 46 | BlockEntityInit.BLOCK_ENTITIES.register(bus); 47 | ContainerInit.CONTAINERS.register(bus); 48 | ItemInit.ITEMS.register(bus); 49 | EntityInit.ENTITIES.register(bus); 50 | } 51 | 52 | @Nonnull 53 | public Block retreiveBlock(ResourceLocation name) { 54 | final Optional block = ForgeRegistries.BLOCKS.getEntries().stream() 55 | .filter(entry -> entry.getKey().getRegistryName().equals(name)).map(Entry::getValue).findFirst(); 56 | return block.orElse(Blocks.AIR); 57 | } 58 | 59 | public static VoxelShape calculateShapes(Direction to, VoxelShape shape) { 60 | final VoxelShape[] buffer = { shape, Shapes.empty() }; 61 | 62 | final int times = (to.get2DDataValue() - Direction.NORTH.get2DDataValue() + 4) % 4; 63 | for (int i = 0; i < times; i++) { 64 | buffer[0].forAllBoxes((minX, minY, minZ, maxX, maxY, 65 | maxZ) -> buffer[1] = Shapes.or(buffer[1], Shapes.create(1 - maxZ, minY, minX, 1 - minZ, maxY, maxX))); 66 | buffer[0] = buffer[1]; 67 | buffer[1] = Shapes.empty(); 68 | } 69 | 70 | return buffer[0]; 71 | } 72 | } -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/ClientAccess.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client; 2 | 3 | import io.github.darealturtywurty.tutorialmod.client.screen.EnergyStorageScreen; 4 | import io.github.darealturtywurty.tutorialmod.common.block.entity.EnergyStorageBlockEntity; 5 | import io.github.darealturtywurty.tutorialmod.common.block.entity.ToiletBlockEntity; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.screens.Screen; 8 | import net.minecraft.core.BlockPos; 9 | import net.minecraft.world.level.block.entity.BlockEntity; 10 | 11 | @SuppressWarnings("resource") 12 | public class ClientAccess { 13 | public static Runnable openEnergyStorage(EnergyStorageBlockEntity be) { 14 | return () -> Minecraft.getInstance().setScreen(new EnergyStorageScreen(be)); 15 | } 16 | 17 | public static void updateEnergyStorage(int energy) { 18 | final Screen screen = Minecraft.getInstance().screen; 19 | if (screen instanceof final EnergyStorageScreen energyStorage) { 20 | energyStorage.setEnergy(energy); 21 | } 22 | } 23 | 24 | public static void updateToilet(BlockPos pos) { 25 | final BlockEntity blockEntity = Minecraft.getInstance().level.getBlockEntity(pos); 26 | if (blockEntity instanceof final ToiletBlockEntity toilet) { 27 | toilet.isShitting = false; 28 | toilet.fartTicker = 0; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/KeyInit.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client; 2 | 3 | import com.mojang.blaze3d.platform.InputConstants; 4 | 5 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 6 | import net.minecraft.client.KeyMapping; 7 | import net.minecraftforge.client.ClientRegistry; 8 | 9 | public final class KeyInit { 10 | public static KeyMapping exampleKeyMapping; 11 | 12 | private KeyInit() { 13 | } 14 | 15 | public static void init() { 16 | exampleKeyMapping = registerKey("example_key", KeyMapping.CATEGORY_GAMEPLAY, InputConstants.KEY_S); 17 | } 18 | 19 | private static KeyMapping registerKey(String name, String category, int keycode) { 20 | final var key = new KeyMapping("key." + TutorialMod.MODID + "." + name, keycode, category); 21 | ClientRegistry.registerKeyBinding(key); 22 | return key; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/event/ClientForgeEvents.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client.event; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.client.KeyInit; 5 | import io.github.darealturtywurty.tutorialmod.common.block.entity.ToiletBlockEntity; 6 | import io.github.darealturtywurty.tutorialmod.common.entity.SittableEntity; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraftforge.api.distmarker.Dist; 9 | import net.minecraftforge.event.TickEvent.ClientTickEvent; 10 | import net.minecraftforge.eventbus.api.SubscribeEvent; 11 | import net.minecraftforge.fml.common.Mod; 12 | import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; 13 | 14 | @Mod.EventBusSubscriber(modid = TutorialMod.MODID, bus = Bus.FORGE, value = Dist.CLIENT) 15 | public final class ClientForgeEvents { 16 | private ClientForgeEvents() { 17 | } 18 | 19 | @SuppressWarnings("resource") 20 | @SubscribeEvent 21 | public static void clientTick(ClientTickEvent event) { 22 | final var player = Minecraft.getInstance().player; 23 | if ((KeyInit.exampleKeyMapping.isDown() && player.isPassenger() 24 | && player.getVehicle() instanceof SittableEntity) 25 | && (player.level.getBlockEntity( 26 | player.getVehicle().blockPosition())instanceof final ToiletBlockEntity toilet)) { 27 | toilet.setShitting(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/event/ClientModEvents.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client.event; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.client.KeyInit; 5 | import io.github.darealturtywurty.tutorialmod.client.renderer.ExampleEntityRenderer; 6 | import io.github.darealturtywurty.tutorialmod.client.renderer.SeatRenderer; 7 | import io.github.darealturtywurty.tutorialmod.client.renderer.block.DisplayHandBER; 8 | import io.github.darealturtywurty.tutorialmod.client.renderer.model.ExampleEntityModel; 9 | import io.github.darealturtywurty.tutorialmod.client.screen.EnergyGeneratorScreen; 10 | import io.github.darealturtywurty.tutorialmod.client.screen.ExampleChestScreen; 11 | import io.github.darealturtywurty.tutorialmod.client.screen.PoopStorageScreen; 12 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 13 | import io.github.darealturtywurty.tutorialmod.core.init.BlockInit; 14 | import io.github.darealturtywurty.tutorialmod.core.init.ContainerInit; 15 | import io.github.darealturtywurty.tutorialmod.core.init.EntityInit; 16 | import net.minecraft.client.gui.screens.MenuScreens; 17 | import net.minecraft.client.renderer.ItemBlockRenderTypes; 18 | import net.minecraft.client.renderer.RenderType; 19 | import net.minecraftforge.api.distmarker.Dist; 20 | import net.minecraftforge.client.event.EntityRenderersEvent; 21 | import net.minecraftforge.eventbus.api.SubscribeEvent; 22 | import net.minecraftforge.fml.common.Mod; 23 | import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; 24 | import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; 25 | 26 | @Mod.EventBusSubscriber(modid = TutorialMod.MODID, bus = Bus.MOD, value = Dist.CLIENT) 27 | public final class ClientModEvents { 28 | 29 | private ClientModEvents() { 30 | } 31 | 32 | @SubscribeEvent 33 | public static void clientSetup(FMLClientSetupEvent event) { 34 | ItemBlockRenderTypes.setRenderLayer(BlockInit.LIGHTNING_JUMPER.get(), RenderType.cutout()); 35 | ItemBlockRenderTypes.setRenderLayer(BlockInit.DISPLAY_HAND.get(), RenderType.cutout()); 36 | ItemBlockRenderTypes.setRenderLayer(BlockInit.CROPIUM.get(), RenderType.cutout()); 37 | KeyInit.init(); 38 | MenuScreens.register(ContainerInit.EXAMPLE_CHEST.get(), ExampleChestScreen::new); 39 | MenuScreens.register(ContainerInit.POOP_STORAGE.get(), PoopStorageScreen::new); 40 | MenuScreens.register(ContainerInit.ENERGY_GENERATOR.get(), EnergyGeneratorScreen::new); 41 | } 42 | 43 | @SubscribeEvent 44 | public static void registerLayers(EntityRenderersEvent.RegisterLayerDefinitions event) { 45 | event.registerLayerDefinition(ExampleEntityModel.LAYER_LOCATION, ExampleEntityModel::createBodyLayer); 46 | } 47 | 48 | @SubscribeEvent 49 | public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) { 50 | event.registerEntityRenderer(EntityInit.EXAMPLE_ENTITY.get(), ExampleEntityRenderer::new); 51 | event.registerEntityRenderer(EntityInit.SEAT.get(), SeatRenderer::new); 52 | 53 | event.registerBlockEntityRenderer(BlockEntityInit.DISPLAY_HAND.get(), DisplayHandBER::new); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/renderer/ExampleEntityRenderer.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client.renderer; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.client.renderer.model.ExampleEntityModel; 5 | import io.github.darealturtywurty.tutorialmod.common.entity.ExampleEntity; 6 | import net.minecraft.client.renderer.entity.EntityRendererProvider.Context; 7 | import net.minecraft.client.renderer.entity.MobRenderer; 8 | import net.minecraft.resources.ResourceLocation; 9 | 10 | public class ExampleEntityRenderer extends MobRenderer> { 11 | 12 | private static final ResourceLocation TEXTURE = new ResourceLocation(TutorialMod.MODID, 13 | "textures/entities/example_entity.png"); 14 | 15 | public ExampleEntityRenderer(Context context) { 16 | super(context, new ExampleEntityModel<>(context.bakeLayer(ExampleEntityModel.LAYER_LOCATION)), 0.5f); 17 | } 18 | 19 | @Override 20 | public ResourceLocation getTextureLocation(Type entity) { 21 | return TEXTURE; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/renderer/SeatRenderer.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client.renderer; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.entity.SittableEntity; 5 | import net.minecraft.client.renderer.entity.EntityRenderer; 6 | import net.minecraft.client.renderer.entity.EntityRendererProvider.Context; 7 | import net.minecraft.resources.ResourceLocation; 8 | 9 | public class SeatRenderer extends EntityRenderer { 10 | 11 | private static final ResourceLocation TEXTURE = new ResourceLocation(TutorialMod.MODID, ""); 12 | 13 | public SeatRenderer(Context context) { 14 | super(context); 15 | } 16 | 17 | @Override 18 | public ResourceLocation getTextureLocation(SittableEntity entity) { 19 | return TEXTURE; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/renderer/block/DisplayHandBER.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client.renderer.block; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | 5 | import io.github.darealturtywurty.tutorialmod.common.block.entity.DisplayHandBlockEntity; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.player.LocalPlayer; 8 | import net.minecraft.client.renderer.MultiBufferSource; 9 | import net.minecraft.client.renderer.block.BlockRenderDispatcher; 10 | import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType; 11 | import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; 12 | import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; 13 | import net.minecraft.client.renderer.entity.ItemRenderer; 14 | import net.minecraft.world.item.ItemStack; 15 | import net.minecraft.world.level.block.Blocks; 16 | import net.minecraftforge.client.model.data.EmptyModelData; 17 | 18 | public class DisplayHandBER implements BlockEntityRenderer { 19 | private final BlockEntityRendererProvider.Context context; 20 | 21 | public DisplayHandBER(BlockEntityRendererProvider.Context context) { 22 | this.context = context; 23 | } 24 | 25 | @SuppressWarnings("resource") 26 | @Override 27 | public void render(DisplayHandBlockEntity be, float partialTicks, PoseStack stack, MultiBufferSource buffer, 28 | int combinedOverlay, int packedLight) { 29 | final BlockRenderDispatcher dispatcher = this.context.getBlockRenderDispatcher(); 30 | final ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); 31 | dispatcher.renderSingleBlock(Blocks.GLASS.defaultBlockState(), stack, buffer, combinedOverlay, packedLight, 32 | EmptyModelData.INSTANCE); 33 | 34 | final LocalPlayer player = Minecraft.getInstance().player; 35 | final ItemStack heldItem = player.getMainHandItem().isEmpty() ? player.getOffhandItem() 36 | : player.getMainHandItem(); 37 | stack.pushPose(); 38 | stack.translate(0.5f, 0.5f, 0.5f); 39 | stack.scale(0.75f, 0.75f, 0.75f); 40 | itemRenderer.renderStatic(player, heldItem, TransformType.FIXED, false, stack, buffer, 41 | Minecraft.getInstance().level, combinedOverlay, packedLight, 0); 42 | stack.popPose(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/renderer/model/ExampleEntityModel.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client.renderer.model; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import com.mojang.blaze3d.vertex.VertexConsumer; 5 | 6 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 7 | import io.github.darealturtywurty.tutorialmod.common.entity.ExampleEntity; 8 | import net.minecraft.client.model.EntityModel; 9 | import net.minecraft.client.model.geom.ModelLayerLocation; 10 | import net.minecraft.client.model.geom.ModelPart; 11 | import net.minecraft.client.model.geom.PartPose; 12 | import net.minecraft.client.model.geom.builders.CubeDeformation; 13 | import net.minecraft.client.model.geom.builders.CubeListBuilder; 14 | import net.minecraft.client.model.geom.builders.LayerDefinition; 15 | import net.minecraft.client.model.geom.builders.MeshDefinition; 16 | import net.minecraft.client.model.geom.builders.PartDefinition; 17 | import net.minecraft.resources.ResourceLocation; 18 | 19 | public class ExampleEntityModel extends EntityModel { 20 | public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation( 21 | new ResourceLocation(TutorialMod.MODID, "example_entity"), "main"); 22 | 23 | private final ModelPart body; 24 | 25 | public ExampleEntityModel(ModelPart root) { 26 | this.body = root.getChild("body"); 27 | } 28 | 29 | public static LayerDefinition createBodyLayer() { 30 | MeshDefinition meshdefinition = new MeshDefinition(); 31 | PartDefinition partdefinition = meshdefinition.getRoot(); 32 | 33 | PartDefinition body = partdefinition.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 0) 34 | .addBox(-5.0F, -8.0F, -7.0F, 10.0F, 7.0F, 14.0F, new CubeDeformation(0.0F)), 35 | PartPose.offset(0.0F, 24.0F, 0.0F)); 36 | 37 | body.addOrReplaceChild("legs", 38 | CubeListBuilder.create().texOffs(26, 27) 39 | .addBox(5.0F, -3.0F, -6.0F, 2.0F, 3.0F, 2.0F, new CubeDeformation(0.0F)).texOffs(17, 27) 40 | .addBox(-7.0F, -3.0F, -6.0F, 2.0F, 3.0F, 2.0F, new CubeDeformation(0.0F)).texOffs(0, 0) 41 | .addBox(-7.0F, -3.0F, 4.0F, 2.0F, 3.0F, 2.0F, new CubeDeformation(0.0F)).texOffs(0, 6) 42 | .addBox(5.0F, -3.0F, 4.0F, 2.0F, 3.0F, 2.0F, new CubeDeformation(0.0F)), 43 | PartPose.offset(0.0F, 0.0F, 0.0F)); 44 | 45 | body.addOrReplaceChild("head", 46 | CubeListBuilder.create().texOffs(0, 22) 47 | .addBox(-2.0F, -10.0F, -11.0F, 4.0F, 3.0F, 4.0F, new CubeDeformation(0.0F)).texOffs(17, 22) 48 | .addBox(-2.0F, -11.0F, -11.0F, 4.0F, 1.0F, 3.0F, new CubeDeformation(0.0F)).texOffs(13, 22) 49 | .addBox(-1.0F, -11.0F, -8.0F, 2.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)).texOffs(7, 30) 50 | .addBox(1.0F, -12.0F, -8.0F, 2.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)).texOffs(0, 30) 51 | .addBox(-3.0F, -12.0F, -8.0F, 2.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), 52 | PartPose.offset(0.0F, 0.0F, 0.0F)); 53 | 54 | return LayerDefinition.create(meshdefinition, 64, 64); 55 | } 56 | 57 | @Override 58 | public void setupAnim(Type entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, 59 | float headPitch) {} 60 | 61 | @Override 62 | public void renderToBuffer(PoseStack poseStack, VertexConsumer buffer, int packedLight, int packedOverlay, 63 | float red, float green, float blue, float alpha) { 64 | this.body.render(poseStack, buffer, packedLight, packedOverlay); 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/screen/EnergyGeneratorScreen.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client.screen; 2 | 3 | import com.mojang.blaze3d.systems.RenderSystem; 4 | import com.mojang.blaze3d.vertex.PoseStack; 5 | 6 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 7 | import io.github.darealturtywurty.tutorialmod.common.container.EnergyGeneratorContainer; 8 | import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; 9 | import net.minecraft.client.renderer.GameRenderer; 10 | import net.minecraft.network.chat.Component; 11 | import net.minecraft.resources.ResourceLocation; 12 | import net.minecraft.world.entity.player.Inventory; 13 | 14 | public class EnergyGeneratorScreen extends AbstractContainerScreen { 15 | private static final ResourceLocation TEXTURE = new ResourceLocation(TutorialMod.MODID, 16 | "textures/gui/energy_generator.png"); 17 | 18 | public EnergyGeneratorScreen(EnergyGeneratorContainer container, Inventory playerInv, Component title) { 19 | super(container, playerInv, title); 20 | this.leftPos = 0; 21 | this.topPos = 0; 22 | } 23 | 24 | @Override 25 | public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) { 26 | super.render(stack, mouseX, mouseY, partialTicks); 27 | 28 | final int energyStored = this.menu.data.get(2); 29 | final int maxEnergy = this.menu.data.get(3); 30 | final int scaledHeight = (int) mapNumber(energyStored, 0, maxEnergy, 0, 62); 31 | bindTexture(); 32 | blit(stack, this.leftPos + 118, this.topPos + 75 - scaledHeight, 176, 62 - scaledHeight, 30, scaledHeight); 33 | 34 | final int progress = this.menu.data.get(0); 35 | final int maxProgress = this.menu.data.get(1); 36 | final int scaledProgress = (int) mapNumber(progress, 0, maxProgress, 0, 22); 37 | bindTexture(); 38 | blit(stack, this.leftPos + 76, this.topPos + 36, 206, 0, scaledProgress, 15); 39 | 40 | this.font.draw(stack, this.title, this.leftPos + 7, this.topPos + 5, 0x404040); 41 | this.font.draw(stack, this.playerInventoryTitle, this.leftPos + 8, this.topPos + 75, 0x404040); 42 | drawCenteredString(stack, this.font, energyStored + "", this.leftPos + 133, this.topPos + 4, 0xFFFFFF); 43 | } 44 | 45 | @Override 46 | protected void renderBg(PoseStack stack, float mouseX, int mouseY, int partialTicks) { 47 | renderBackground(stack); 48 | bindTexture(); 49 | blit(stack, this.leftPos, this.topPos, 0, 0, this.imageWidth, this.imageHeight); 50 | } 51 | 52 | @Override 53 | protected void renderLabels(PoseStack stack, int mouseX, int mouseY) { 54 | } 55 | 56 | public static void bindTexture() { 57 | RenderSystem.setShader(GameRenderer::getPositionTexShader); 58 | RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); 59 | RenderSystem.setShaderTexture(0, TEXTURE); 60 | } 61 | 62 | public static double mapNumber(double value, double rangeMin, double rangeMax, double resultMin, double resultMax) { 63 | return (value - rangeMin) / (rangeMax - rangeMin) * (resultMax - resultMin) + resultMin; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/screen/EnergyStorageScreen.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client.screen; 2 | 3 | import com.mojang.blaze3d.systems.RenderSystem; 4 | import com.mojang.blaze3d.vertex.PoseStack; 5 | 6 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 7 | import io.github.darealturtywurty.tutorialmod.common.block.entity.EnergyStorageBlockEntity; 8 | import io.github.darealturtywurty.tutorialmod.core.init.PacketHandler; 9 | import io.github.darealturtywurty.tutorialmod.core.network.ServerboundGetEnergyStoredPacket; 10 | import net.minecraft.client.gui.screens.Screen; 11 | import net.minecraft.client.renderer.GameRenderer; 12 | import net.minecraft.network.chat.TextComponent; 13 | import net.minecraft.resources.ResourceLocation; 14 | 15 | public class EnergyStorageScreen extends Screen { 16 | private static final ResourceLocation TEXTURE = new ResourceLocation(TutorialMod.MODID, 17 | "textures/gui/energy_storage.png"); 18 | private static final int IMAGE_WIDTH = 176, IMAGE_HEIGHT = 166; 19 | private int leftPos = 0, topPos = 0; 20 | private final EnergyStorageBlockEntity be; 21 | private int energy; 22 | 23 | public EnergyStorageScreen(EnergyStorageBlockEntity be) { 24 | super(TextComponent.EMPTY); 25 | this.be = be; 26 | PacketHandler.INSTANCE.sendToServer(new ServerboundGetEnergyStoredPacket(be.getBlockPos())); 27 | } 28 | 29 | public int getEnergy() { 30 | return this.energy; 31 | } 32 | 33 | @Override 34 | public boolean isPauseScreen() { 35 | return false; 36 | } 37 | 38 | @Override 39 | public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) { 40 | bindTexture(); 41 | blit(stack, this.leftPos, this.topPos, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT); 42 | 43 | final int energyStored = this.energy; 44 | final int maxEnergy = this.be.energyStorage.getMaxEnergyStored(); 45 | final int scaledEnergy = (int) mapNumber(energyStored, 0, maxEnergy, 0, 122); 46 | bindTexture(); 47 | blit(stack, this.leftPos + 59, this.topPos + 145 - scaledEnergy, 176, 122 - scaledEnergy, 58, scaledEnergy); 48 | 49 | this.font.draw(stack, this.title, this.leftPos + 7, this.topPos + 5, 0x404040); 50 | this.font.draw(stack, this.energy + "RF", this.leftPos + 10, this.topPos + 10, 0x404040); 51 | } 52 | 53 | public void setEnergy(int energy) { 54 | this.energy = energy; 55 | } 56 | 57 | @Override 58 | protected void init() { 59 | super.init(); 60 | this.leftPos = (this.width - IMAGE_WIDTH) / 2; 61 | this.topPos = (this.height - IMAGE_HEIGHT) / 2; 62 | } 63 | 64 | public static void bindTexture() { 65 | RenderSystem.setShader(GameRenderer::getPositionTexShader); 66 | RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); 67 | RenderSystem.setShaderTexture(0, TEXTURE); 68 | } 69 | 70 | public static double mapNumber(double value, double rangeMin, double rangeMax, double resultMin, double resultMax) { 71 | return (value - rangeMin) / (rangeMax - rangeMin) * (resultMax - resultMin) + resultMin; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/screen/ExampleChestScreen.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client.screen; 2 | 3 | import com.mojang.blaze3d.systems.RenderSystem; 4 | import com.mojang.blaze3d.vertex.PoseStack; 5 | 6 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 7 | import io.github.darealturtywurty.tutorialmod.common.container.ExampleChestContainer; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; 10 | import net.minecraft.client.renderer.GameRenderer; 11 | import net.minecraft.network.chat.Component; 12 | import net.minecraft.network.chat.TextComponent; 13 | import net.minecraft.resources.ResourceLocation; 14 | import net.minecraft.world.entity.player.Inventory; 15 | import net.minecraftforge.client.gui.widget.ExtendedButton; 16 | 17 | public class ExampleChestScreen extends AbstractContainerScreen { 18 | private static final ResourceLocation TEXTURE = new ResourceLocation(TutorialMod.MODID, 19 | "textures/gui/example_chest.png"); 20 | 21 | private ExtendedButton beanButton; 22 | 23 | public ExampleChestScreen(ExampleChestContainer container, Inventory playerInv, Component title) { 24 | super(container, playerInv, title); 25 | this.leftPos = 0; 26 | this.topPos = 0; 27 | } 28 | 29 | @Override 30 | public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) { 31 | super.render(stack, mouseX, mouseY, partialTicks); 32 | this.font.draw(stack, this.title, this.leftPos + 20, this.topPos + 5, 0x404040); 33 | this.font.draw(stack, this.playerInventoryTitle, this.leftPos + 8, this.topPos + 75, 0x404040); 34 | } 35 | 36 | @Override 37 | protected void init() { 38 | super.init(); 39 | this.beanButton = addRenderableWidget( 40 | new ExtendedButton(this.leftPos, this.topPos, 16, 16, new TextComponent("beans"), 41 | btn -> Minecraft.getInstance().player.displayClientMessage(new TextComponent("beans"), false))); 42 | } 43 | 44 | @Override 45 | protected void renderBg(PoseStack stack, float mouseX, int mouseY, int partialTicks) { 46 | renderBackground(stack); 47 | RenderSystem.setShader(GameRenderer::getPositionTexShader); 48 | RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); 49 | RenderSystem.setShaderTexture(0, TEXTURE); 50 | blit(stack, this.leftPos, this.topPos, 0, 0, this.imageWidth, this.imageHeight); 51 | } 52 | 53 | @Override 54 | protected void renderLabels(PoseStack stack, int mouseX, int mouseY) { 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/client/screen/PoopStorageScreen.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.client.screen; 2 | 3 | import com.mojang.blaze3d.systems.RenderSystem; 4 | import com.mojang.blaze3d.vertex.PoseStack; 5 | 6 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 7 | import io.github.darealturtywurty.tutorialmod.common.container.PoopStorageContainer; 8 | import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; 9 | import net.minecraft.client.renderer.GameRenderer; 10 | import net.minecraft.network.chat.Component; 11 | import net.minecraft.resources.ResourceLocation; 12 | import net.minecraft.world.entity.player.Inventory; 13 | 14 | public class PoopStorageScreen extends AbstractContainerScreen { 15 | private static final ResourceLocation TEXTURE = new ResourceLocation(TutorialMod.MODID, 16 | "textures/gui/poop_storage.png"); 17 | 18 | public PoopStorageScreen(PoopStorageContainer container, Inventory playerInv, Component title) { 19 | super(container, playerInv, title); 20 | this.leftPos = 0; 21 | this.topPos = 0; 22 | } 23 | 24 | @Override 25 | public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) { 26 | super.render(stack, mouseX, mouseY, partialTicks); 27 | 28 | final int count = this.menu.data.get(0); 29 | final int scaledHeight = (int) mapNumber(count, 0, 64, 0, 62); 30 | bindTexture(); 31 | blit(stack, this.leftPos + 118, this.topPos + 75 - scaledHeight, 176, 62 - scaledHeight, 30, scaledHeight); 32 | 33 | this.font.draw(stack, this.title, this.leftPos + 20, this.topPos + 5, 0x404040); 34 | this.font.draw(stack, this.playerInventoryTitle, this.leftPos + 8, this.topPos + 75, 0x404040); 35 | this.font.draw(stack, count + "", this.leftPos + 105, this.topPos + 12, 0x404040); 36 | } 37 | 38 | @Override 39 | protected void renderBg(PoseStack stack, float mouseX, int mouseY, int partialTicks) { 40 | renderBackground(stack); 41 | bindTexture(); 42 | blit(stack, this.leftPos, this.topPos, 0, 0, this.imageWidth, this.imageHeight); 43 | } 44 | 45 | @Override 46 | protected void renderLabels(PoseStack stack, int mouseX, int mouseY) { 47 | } 48 | 49 | public static void bindTexture() { 50 | RenderSystem.setShader(GameRenderer::getPositionTexShader); 51 | RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); 52 | RenderSystem.setShaderTexture(0, TEXTURE); 53 | } 54 | 55 | public static double mapNumber(double value, double rangeMin, double rangeMax, double resultMin, double resultMax) { 56 | return (value - rangeMin) / (rangeMax - rangeMin) * (resultMax - resultMin) + resultMin; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/BaseCropBlock.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import net.minecraft.world.item.Item; 6 | import net.minecraft.world.level.ItemLike; 7 | import net.minecraft.world.level.block.CropBlock; 8 | 9 | public class BaseCropBlock extends CropBlock { 10 | private final Supplier seeds; 11 | 12 | public BaseCropBlock(Supplier seedsItem, Properties properties) { 13 | super(properties); 14 | this.seeds = seedsItem; 15 | } 16 | 17 | @Override 18 | protected ItemLike getBaseSeedId() { 19 | return this.seeds.get(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/DisplayHandBlock.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.DisplayHandBlockEntity; 4 | import net.minecraft.core.BlockPos; 5 | import net.minecraft.world.level.block.AbstractGlassBlock; 6 | import net.minecraft.world.level.block.EntityBlock; 7 | import net.minecraft.world.level.block.RenderShape; 8 | import net.minecraft.world.level.block.entity.BlockEntity; 9 | import net.minecraft.world.level.block.state.BlockState; 10 | 11 | public class DisplayHandBlock extends AbstractGlassBlock implements EntityBlock { 12 | public DisplayHandBlock(Properties properties) { 13 | super(properties); 14 | } 15 | 16 | @Override 17 | public RenderShape getRenderShape(BlockState state) { 18 | return RenderShape.ENTITYBLOCK_ANIMATED; 19 | } 20 | 21 | @Override 22 | public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { 23 | return new DisplayHandBlockEntity(pos, state); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/DrawerBlock.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.DrawerBlockEntity; 4 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.core.Direction; 7 | import net.minecraft.network.chat.TextComponent; 8 | import net.minecraft.world.InteractionHand; 9 | import net.minecraft.world.InteractionResult; 10 | import net.minecraft.world.entity.player.Player; 11 | import net.minecraft.world.item.context.BlockPlaceContext; 12 | import net.minecraft.world.level.Level; 13 | import net.minecraft.world.level.block.Block; 14 | import net.minecraft.world.level.block.EntityBlock; 15 | import net.minecraft.world.level.block.HorizontalDirectionalBlock; 16 | import net.minecraft.world.level.block.entity.BlockEntity; 17 | import net.minecraft.world.level.block.entity.BlockEntityTicker; 18 | import net.minecraft.world.level.block.entity.BlockEntityType; 19 | import net.minecraft.world.level.block.state.BlockState; 20 | import net.minecraft.world.level.block.state.StateDefinition.Builder; 21 | import net.minecraft.world.phys.BlockHitResult; 22 | 23 | public class DrawerBlock extends HorizontalDirectionalBlock implements EntityBlock { 24 | public DrawerBlock(Properties properties) { 25 | super(properties); 26 | registerDefaultState(defaultBlockState().setValue(FACING, Direction.NORTH)); 27 | } 28 | 29 | @Override 30 | public void attack(BlockState state, Level level, BlockPos pos, Player player) { 31 | if (!level.isClientSide && level.getBlockEntity(pos) instanceof final DrawerBlockEntity drawer) { 32 | if (player.isCrouching()) { 33 | drawer.prependStack(player); 34 | } else { 35 | drawer.prependItem(player); 36 | } 37 | } 38 | } 39 | 40 | @Override 41 | public BlockState getStateForPlacement(BlockPlaceContext context) { 42 | return defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); 43 | } 44 | 45 | @Override 46 | public BlockEntityTicker getTicker(Level level, BlockState state, 47 | BlockEntityType beType) { 48 | return level.isClientSide ? null 49 | : (level0, pos, state0, blockEntity) -> ((DrawerBlockEntity) blockEntity).tick(); 50 | } 51 | 52 | @Override 53 | public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { 54 | return BlockEntityInit.DRAWER.get().create(pos, state); 55 | } 56 | 57 | @Override 58 | public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, 59 | BlockHitResult result) { 60 | if (!level.isClientSide && level.getBlockEntity(pos) instanceof final DrawerBlockEntity drawer) { 61 | if (!player.isCrouching()) { 62 | drawer.appendItem(player.getItemInHand(hand)); 63 | } else { 64 | player.displayClientMessage( 65 | new TextComponent("Current count is " + drawer.getItemInSlot(0).getCount() + "!"), false); 66 | } 67 | } 68 | 69 | return InteractionResult.SUCCESS; 70 | } 71 | 72 | @Override 73 | protected void createBlockStateDefinition(Builder builder) { 74 | super.createBlockStateDefinition(builder); 75 | builder.add(FACING); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/EnergyGeneratorBlock.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.EnergyGeneratorBlockEntity; 4 | import io.github.darealturtywurty.tutorialmod.common.container.EnergyGeneratorContainer; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.server.level.ServerPlayer; 7 | import net.minecraft.world.InteractionHand; 8 | import net.minecraft.world.InteractionResult; 9 | import net.minecraft.world.MenuProvider; 10 | import net.minecraft.world.SimpleMenuProvider; 11 | import net.minecraft.world.entity.item.ItemEntity; 12 | import net.minecraft.world.entity.player.Player; 13 | import net.minecraft.world.level.Level; 14 | import net.minecraft.world.level.block.Block; 15 | import net.minecraft.world.level.block.EntityBlock; 16 | import net.minecraft.world.level.block.entity.BlockEntity; 17 | import net.minecraft.world.level.block.entity.BlockEntityTicker; 18 | import net.minecraft.world.level.block.entity.BlockEntityType; 19 | import net.minecraft.world.level.block.state.BlockState; 20 | import net.minecraft.world.phys.BlockHitResult; 21 | import net.minecraftforge.network.NetworkHooks; 22 | 23 | public class EnergyGeneratorBlock extends Block implements EntityBlock { 24 | public EnergyGeneratorBlock(Properties properties) { 25 | super(properties); 26 | } 27 | 28 | @Override 29 | public BlockEntityTicker getTicker(Level level, BlockState state, 30 | BlockEntityType type) { 31 | return level.isClientSide ? null 32 | : (level0, pos, state0, blockEntity) -> ((EnergyGeneratorBlockEntity) blockEntity).tick(); 33 | } 34 | 35 | @Override 36 | public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { 37 | return new EnergyGeneratorBlockEntity(pos, state); 38 | } 39 | 40 | @SuppressWarnings("deprecation") 41 | @Override 42 | public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean moving) { 43 | final BlockEntity be = level.getBlockEntity(pos); 44 | //@formatter:off 45 | if (!((be instanceof final EnergyGeneratorBlockEntity generator))) 46 | return; 47 | //@formatter:on 48 | 49 | for (int slot = 0; slot < generator.inventory.getSlots(); slot++) { 50 | if (generator.inventory.getStackInSlot(slot).isEmpty()) 51 | return; 52 | 53 | level.addFreshEntity(new ItemEntity(level, pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, 54 | generator.inventory.getStackInSlot(slot))); 55 | } 56 | 57 | super.onRemove(state, level, pos, newState, moving); 58 | } 59 | 60 | @Override 61 | public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, 62 | BlockHitResult result) { 63 | if (!level.isClientSide && level.getBlockEntity(pos) instanceof final EnergyGeneratorBlockEntity generator) { 64 | final MenuProvider container = new SimpleMenuProvider( 65 | EnergyGeneratorContainer.getServerContainer(generator, pos), EnergyGeneratorBlockEntity.TITLE); 66 | NetworkHooks.openGui((ServerPlayer) player, container, pos); 67 | } 68 | 69 | return InteractionResult.SUCCESS; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/EnergyStorageBlock.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block; 2 | 3 | import io.github.darealturtywurty.tutorialmod.client.ClientAccess; 4 | import io.github.darealturtywurty.tutorialmod.common.block.entity.EnergyStorageBlockEntity; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.world.InteractionHand; 7 | import net.minecraft.world.InteractionResult; 8 | import net.minecraft.world.entity.player.Player; 9 | import net.minecraft.world.level.Level; 10 | import net.minecraft.world.level.block.Block; 11 | import net.minecraft.world.level.block.EntityBlock; 12 | import net.minecraft.world.level.block.entity.BlockEntity; 13 | import net.minecraft.world.level.block.entity.BlockEntityTicker; 14 | import net.minecraft.world.level.block.entity.BlockEntityType; 15 | import net.minecraft.world.level.block.state.BlockState; 16 | import net.minecraft.world.phys.BlockHitResult; 17 | import net.minecraftforge.api.distmarker.Dist; 18 | import net.minecraftforge.fml.DistExecutor; 19 | 20 | public class EnergyStorageBlock extends Block implements EntityBlock { 21 | public EnergyStorageBlock(Properties properties) { 22 | super(properties); 23 | } 24 | 25 | @Override 26 | public BlockEntityTicker getTicker(Level level, BlockState state, 27 | BlockEntityType type) { 28 | return level.isClientSide ? null 29 | : (level0, pos, state0, blockEntity) -> ((EnergyStorageBlockEntity) blockEntity).tick(); 30 | } 31 | 32 | @Override 33 | public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { 34 | return new EnergyStorageBlockEntity(pos, state); 35 | } 36 | 37 | @Override 38 | public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, 39 | BlockHitResult result) { 40 | if (level.isClientSide && level.getBlockEntity(pos) instanceof final EnergyStorageBlockEntity energyStorage) { 41 | DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientAccess.openEnergyStorage(energyStorage)); 42 | } 43 | 44 | return InteractionResult.sidedSuccess(level.isClientSide); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/ExampleChestBlock.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.ExampleChestBlockEntity; 4 | import io.github.darealturtywurty.tutorialmod.common.container.ExampleChestContainer; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.core.Direction; 7 | import net.minecraft.server.level.ServerPlayer; 8 | import net.minecraft.world.InteractionHand; 9 | import net.minecraft.world.InteractionResult; 10 | import net.minecraft.world.MenuProvider; 11 | import net.minecraft.world.SimpleMenuProvider; 12 | import net.minecraft.world.entity.player.Player; 13 | import net.minecraft.world.item.context.BlockPlaceContext; 14 | import net.minecraft.world.level.Level; 15 | import net.minecraft.world.level.block.Block; 16 | import net.minecraft.world.level.block.EntityBlock; 17 | import net.minecraft.world.level.block.HorizontalDirectionalBlock; 18 | import net.minecraft.world.level.block.entity.BlockEntity; 19 | import net.minecraft.world.level.block.entity.BlockEntityTicker; 20 | import net.minecraft.world.level.block.entity.BlockEntityType; 21 | import net.minecraft.world.level.block.state.BlockState; 22 | import net.minecraft.world.level.block.state.StateDefinition.Builder; 23 | import net.minecraft.world.phys.BlockHitResult; 24 | import net.minecraftforge.network.NetworkHooks; 25 | 26 | public class ExampleChestBlock extends HorizontalDirectionalBlock implements EntityBlock { 27 | public ExampleChestBlock(Properties properties) { 28 | super(properties); 29 | registerDefaultState(defaultBlockState().setValue(FACING, Direction.NORTH)); 30 | } 31 | 32 | @Override 33 | public BlockState getStateForPlacement(BlockPlaceContext context) { 34 | return defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); 35 | } 36 | 37 | @Override 38 | public BlockEntityTicker getTicker(Level level, BlockState state, 39 | BlockEntityType beType) { 40 | return level.isClientSide ? null 41 | : (level0, pos, state0, blockEntity) -> ((ExampleChestBlockEntity) blockEntity).tick(); 42 | } 43 | 44 | @Override 45 | public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { 46 | return new ExampleChestBlockEntity(pos, state); 47 | } 48 | 49 | @Override 50 | public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, 51 | BlockHitResult result) { 52 | if (!level.isClientSide && level.getBlockEntity(pos) instanceof final ExampleChestBlockEntity chest) { 53 | final MenuProvider container = new SimpleMenuProvider(ExampleChestContainer.getServerContainer(chest, pos), 54 | ExampleChestBlockEntity.TITLE); 55 | NetworkHooks.openGui((ServerPlayer) player, container, pos); 56 | } 57 | 58 | return InteractionResult.SUCCESS; 59 | } 60 | 61 | @Override 62 | protected void createBlockStateDefinition(Builder builder) { 63 | super.createBlockStateDefinition(builder); 64 | builder.add(FACING); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/LightningJumperBlock.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block; 2 | 3 | import java.util.EnumMap; 4 | import java.util.Map; 5 | import java.util.Optional; 6 | import java.util.stream.Stream; 7 | 8 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 9 | import net.minecraft.core.BlockPos; 10 | import net.minecraft.core.Direction; 11 | import net.minecraft.sounds.SoundEvents; 12 | import net.minecraft.sounds.SoundSource; 13 | import net.minecraft.world.InteractionHand; 14 | import net.minecraft.world.InteractionResult; 15 | import net.minecraft.world.entity.EntityType; 16 | import net.minecraft.world.entity.LightningBolt; 17 | import net.minecraft.world.entity.animal.Pig; 18 | import net.minecraft.world.entity.player.Player; 19 | import net.minecraft.world.item.context.BlockPlaceContext; 20 | import net.minecraft.world.level.BlockGetter; 21 | import net.minecraft.world.level.Level; 22 | import net.minecraft.world.level.block.Block; 23 | import net.minecraft.world.level.block.HorizontalDirectionalBlock; 24 | import net.minecraft.world.level.block.state.BlockState; 25 | import net.minecraft.world.level.block.state.StateDefinition.Builder; 26 | import net.minecraft.world.phys.BlockHitResult; 27 | import net.minecraft.world.phys.shapes.BooleanOp; 28 | import net.minecraft.world.phys.shapes.CollisionContext; 29 | import net.minecraft.world.phys.shapes.Shapes; 30 | import net.minecraft.world.phys.shapes.VoxelShape; 31 | import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; 32 | import net.minecraftforge.eventbus.api.SubscribeEvent; 33 | import net.minecraftforge.fml.common.Mod; 34 | import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; 35 | 36 | public class LightningJumperBlock extends HorizontalDirectionalBlock { 37 | 38 | @Mod.EventBusSubscriber(modid = TutorialMod.MODID, bus = Bus.FORGE) 39 | public static class Events { 40 | @SubscribeEvent 41 | public static void livingTick(LivingUpdateEvent event) { 42 | var entity = event.getEntityLiving(); 43 | var foundTag = new StringBuilder(); 44 | entity.getTags().forEach(tag -> { 45 | if (tag.startsWith("LightningJumper-") && foundTag.isEmpty()) 46 | foundTag.append(tag); 47 | }); 48 | 49 | if (!foundTag.isEmpty()) { 50 | int ticks = Integer.parseInt(foundTag.toString().split("-")[1]); 51 | if (ticks < 120) { 52 | entity.removeTag(foundTag.toString()); 53 | entity.addTag("LightningJumper-" + (ticks + 1)); 54 | } else { 55 | entity.removeTag(foundTag.toString()); 56 | LightningBolt lightning = EntityType.LIGHTNING_BOLT.create(entity.level); 57 | lightning.setPos(entity.position()); 58 | entity.level.addFreshEntity(lightning); 59 | } 60 | } 61 | } 62 | } 63 | 64 | private static final Map SHAPES = new EnumMap<>(Direction.class); 65 | 66 | private static final Optional SHAPE = Stream 67 | .of(Block.box(7, 1, 3, 9, 7, 7), Block.box(3, 1, 7, 13, 7, 13), Block.box(6, 0, 2, 10, 1, 4), 68 | Block.box(2, 0, 7, 14, 1, 14), Block.box(3, 0, 6, 13, 1, 7), Block.box(4, 0, 5, 12, 1, 6), 69 | Block.box(5, 0, 4, 11, 1, 5), Block.box(9, 7, 6, 10, 16, 7), Block.box(6, 7, 6, 7, 16, 7), 70 | Block.box(7, 7, 3, 9, 9, 13), Block.box(7, 1, 13, 9, 10, 15), Block.box(7, 1, 1, 9, 7, 3), 71 | Block.box(7, 1, 0, 9, 6, 1), Block.box(7, 7, 2, 9, 8, 3), Block.box(7, 0, 14, 9, 1, 15), 72 | Block.box(7, 0, 1, 9, 1, 2), Block.box(9, 1, 13, 10, 6, 14), Block.box(6, 1, 13, 7, 6, 14), 73 | Block.box(11, 5, 6, 12, 6, 7), Block.box(9, 2, 5, 10, 3, 6), Block.box(9, 6, 6, 11, 7, 7), 74 | Block.box(9, 6, 5, 10, 7, 6), Block.box(10, 4, 6, 11, 5, 7), Block.box(9, 4, 5, 10, 5, 7), 75 | Block.box(9, 5, 5, 11, 6, 7), Block.box(9, 5, 4, 10, 6, 5), Block.box(9, 2, 6, 11, 3, 7), 76 | Block.box(11, 1, 6, 12, 2, 7), Block.box(9, 1, 4, 10, 2, 5), Block.box(9, 1, 5, 11, 2, 7), 77 | Block.box(9, 3, 6, 10, 6, 7), Block.box(4, 5, 6, 5, 6, 7), Block.box(5, 4, 6, 7, 5, 7), 78 | Block.box(6, 4, 5, 7, 5, 6), Block.box(5, 5, 5, 7, 6, 7), Block.box(6, 5, 4, 7, 6, 5), 79 | Block.box(6, 6, 5, 7, 7, 7), Block.box(6, 3, 6, 7, 6, 7), Block.box(5, 6, 6, 6, 7, 7), 80 | Block.box(5, 1, 5, 7, 2, 7), Block.box(4, 1, 6, 5, 2, 7), Block.box(6, 1, 4, 7, 2, 5), 81 | Block.box(6, 2, 5, 7, 3, 7), Block.box(5, 2, 6, 6, 3, 7)) 82 | .reduce((v1, v2) -> Shapes.join(v1, v2, BooleanOp.OR)); 83 | 84 | public LightningJumperBlock(Properties properties) { 85 | super(properties); 86 | registerDefaultState(defaultBlockState().setValue(FACING, Direction.NORTH)); 87 | runCalculation(SHAPE.orElse(Shapes.block())); 88 | } 89 | 90 | @Override 91 | protected void createBlockStateDefinition(Builder builder) { 92 | super.createBlockStateDefinition(builder); 93 | builder.add(FACING); 94 | } 95 | 96 | @Override 97 | public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { 98 | return SHAPES.get(state.getValue(FACING)); 99 | } 100 | 101 | @Override 102 | public BlockState getStateForPlacement(BlockPlaceContext context) { 103 | return defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); 104 | } 105 | 106 | protected void runCalculation(VoxelShape shape) { 107 | for (Direction direction : Direction.values()) 108 | SHAPES.put(direction, TutorialMod.calculateShapes(direction, shape)); 109 | } 110 | 111 | @Override 112 | public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, 113 | BlockHitResult result) { 114 | if (!level.isClientSide) { 115 | if (player.experienceLevel <= 10 && !player.isCreative()) { 116 | level.playSound(player, pos, SoundEvents.ANVIL_BREAK, SoundSource.PLAYERS, 1.0f, 1.0f); 117 | return InteractionResult.FAIL; 118 | } 119 | 120 | if (!player.isCreative()) 121 | player.giveExperienceLevels(-5); 122 | 123 | level.playSound(player, pos, SoundEvents.AMBIENT_UNDERWATER_LOOP, SoundSource.BLOCKS, 1.0f, 1.0f); 124 | for (int index = 0; index < this.RANDOM.nextInt(10) + 7; index++) { 125 | Pig pig = EntityType.PIG.create(level); 126 | pig.setPos(pos.getX() + this.RANDOM.nextInt(10) - 5, pos.getY(), 127 | pos.getZ() + this.RANDOM.nextInt(10) - 5); 128 | pig.addTag("LightningJumper-0"); 129 | level.addFreshEntity(pig); 130 | } 131 | return InteractionResult.SUCCESS; 132 | } 133 | return InteractionResult.FAIL; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/PoopStorageBlock.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.PoopStorageBlockEntity; 4 | import io.github.darealturtywurty.tutorialmod.common.container.PoopStorageContainer; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.server.level.ServerPlayer; 7 | import net.minecraft.world.InteractionHand; 8 | import net.minecraft.world.InteractionResult; 9 | import net.minecraft.world.MenuProvider; 10 | import net.minecraft.world.SimpleMenuProvider; 11 | import net.minecraft.world.entity.player.Player; 12 | import net.minecraft.world.level.Level; 13 | import net.minecraft.world.level.block.Block; 14 | import net.minecraft.world.level.block.EntityBlock; 15 | import net.minecraft.world.level.block.entity.BlockEntity; 16 | import net.minecraft.world.level.block.entity.BlockEntityTicker; 17 | import net.minecraft.world.level.block.entity.BlockEntityType; 18 | import net.minecraft.world.level.block.state.BlockState; 19 | import net.minecraft.world.phys.BlockHitResult; 20 | import net.minecraftforge.network.NetworkHooks; 21 | 22 | public class PoopStorageBlock extends Block implements EntityBlock { 23 | public PoopStorageBlock(Properties properties) { 24 | super(properties); 25 | } 26 | 27 | @Override 28 | public BlockEntityTicker getTicker(Level level, BlockState state, 29 | BlockEntityType type) { 30 | return level.isClientSide ? null 31 | : (level0, pos, state0, blockEntity) -> ((PoopStorageBlockEntity) blockEntity).tick(); 32 | } 33 | 34 | @Override 35 | public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { 36 | return new PoopStorageBlockEntity(pos, state); 37 | } 38 | 39 | @Override 40 | public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, 41 | BlockHitResult result) { 42 | if (!level.isClientSide && level.getBlockEntity(pos) instanceof final PoopStorageBlockEntity be) { 43 | final MenuProvider container = new SimpleMenuProvider(PoopStorageContainer.getServerContainer(be, pos), 44 | PoopStorageBlockEntity.TITLE); 45 | NetworkHooks.openGui((ServerPlayer) player, container, pos); 46 | } 47 | 48 | return InteractionResult.SUCCESS; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/ToiletBlock.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block; 2 | 3 | import java.util.EnumMap; 4 | import java.util.Map; 5 | 6 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 7 | import io.github.darealturtywurty.tutorialmod.common.block.entity.ToiletBlockEntity; 8 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 9 | import net.minecraft.core.BlockPos; 10 | import net.minecraft.core.Direction; 11 | import net.minecraft.network.chat.TextComponent; 12 | import net.minecraft.world.InteractionHand; 13 | import net.minecraft.world.InteractionResult; 14 | import net.minecraft.world.entity.player.Player; 15 | import net.minecraft.world.item.context.BlockPlaceContext; 16 | import net.minecraft.world.level.BlockGetter; 17 | import net.minecraft.world.level.Level; 18 | import net.minecraft.world.level.block.Block; 19 | import net.minecraft.world.level.block.EntityBlock; 20 | import net.minecraft.world.level.block.HorizontalDirectionalBlock; 21 | import net.minecraft.world.level.block.entity.BlockEntity; 22 | import net.minecraft.world.level.block.entity.BlockEntityTicker; 23 | import net.minecraft.world.level.block.entity.BlockEntityType; 24 | import net.minecraft.world.level.block.state.BlockState; 25 | import net.minecraft.world.level.block.state.StateDefinition.Builder; 26 | import net.minecraft.world.level.block.state.properties.BooleanProperty; 27 | import net.minecraft.world.phys.BlockHitResult; 28 | import net.minecraft.world.phys.shapes.BooleanOp; 29 | import net.minecraft.world.phys.shapes.CollisionContext; 30 | import net.minecraft.world.phys.shapes.Shapes; 31 | import net.minecraft.world.phys.shapes.VoxelShape; 32 | 33 | public class ToiletBlock extends HorizontalDirectionalBlock implements EntityBlock { 34 | 35 | public static final BooleanProperty IS_USED = BooleanProperty.create("is_used"); 36 | private static final Map SHAPES = new EnumMap<>(Direction.class); 37 | 38 | private static final VoxelShape SHAPE = Shapes.join(Block.box(3, 6, 1, 13, 13, 13), 39 | Block.box(5, 0, 5, 11, 6, 11), BooleanOp.OR); 40 | 41 | public ToiletBlock(Properties properties) { 42 | super(properties); 43 | registerDefaultState(defaultBlockState().setValue(FACING, Direction.NORTH).setValue(IS_USED, false)); 44 | runCalculation(SHAPE); 45 | } 46 | 47 | @Override 48 | public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { 49 | return SHAPES.get(state.getValue(FACING)); 50 | } 51 | 52 | @Override 53 | public BlockState getStateForPlacement(BlockPlaceContext context) { 54 | return defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); 55 | } 56 | 57 | @Override 58 | public BlockEntityTicker getTicker(Level level, BlockState state, 59 | BlockEntityType type) { 60 | return level.isClientSide ? null 61 | : (level0, pos, state0, blockEntity) -> ((ToiletBlockEntity) blockEntity).tick(); 62 | } 63 | 64 | @Override 65 | public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { 66 | return BlockEntityInit.TOILET.get().create(pos, state); 67 | } 68 | 69 | @Override 70 | public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, 71 | InteractionHand hand, BlockHitResult result) { 72 | final var toilet = (ToiletBlockEntity) level.getBlockEntity(pos); 73 | if (!level.isClientSide() && !player.isShiftKeyDown()) { 74 | final boolean success = player.startRiding(toilet.seat); 75 | if (success) { 76 | toilet.playerUses.put(player.getUUID(), 77 | toilet.playerUses.containsKey(player.getUUID()) 78 | ? toilet.playerUses.get(player.getUUID()) + 1 79 | : 1); 80 | level.blockUpdated(pos, this); 81 | toilet.setChanged(); 82 | } 83 | return success ? InteractionResult.SUCCESS : InteractionResult.PASS; 84 | } 85 | 86 | if (player.isShiftKeyDown() && !level.isClientSide() && hand == InteractionHand.MAIN_HAND) { 87 | player.displayClientMessage( 88 | new TextComponent( 89 | "Player has shitted " + toilet.playerUses.get(player.getUUID()) + " times!"), 90 | false); 91 | } 92 | return InteractionResult.PASS; 93 | } 94 | 95 | @Override 96 | protected void createBlockStateDefinition(Builder builder) { 97 | super.createBlockStateDefinition(builder); 98 | builder.add(FACING, IS_USED); 99 | } 100 | 101 | protected void runCalculation(VoxelShape shape) { 102 | for (final Direction direction : Direction.values()) { 103 | SHAPES.put(direction, TutorialMod.calculateShapes(direction, shape)); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/entity/DisplayHandBlockEntity.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block.entity; 2 | 3 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 4 | import net.minecraft.core.BlockPos; 5 | import net.minecraft.world.level.block.entity.BlockEntity; 6 | import net.minecraft.world.level.block.state.BlockState; 7 | 8 | public class DisplayHandBlockEntity extends BlockEntity { 9 | public DisplayHandBlockEntity(BlockPos pos, BlockState state) { 10 | super(BlockEntityInit.DISPLAY_HAND.get(), pos, state); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/entity/DrawerBlockEntity.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block.entity; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.util.InventoryBlockEntity; 4 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.nbt.CompoundTag; 7 | import net.minecraft.nbt.ListTag; 8 | import net.minecraft.nbt.Tag; 9 | import net.minecraft.world.entity.item.ItemEntity; 10 | import net.minecraft.world.entity.player.Player; 11 | import net.minecraft.world.item.ItemStack; 12 | import net.minecraft.world.level.block.state.BlockState; 13 | 14 | public class DrawerBlockEntity extends InventoryBlockEntity { 15 | private static final int LIMIT = (int) Math.pow(2, 15); 16 | 17 | public DrawerBlockEntity(BlockPos pos, BlockState state) { 18 | super(BlockEntityInit.DRAWER.get(), pos, state, 1); 19 | } 20 | 21 | public boolean appendItem(ItemStack stack) { 22 | final ItemStack current = getItemInSlot(0); 23 | final int currentCount = current.getCount(); 24 | if (current.getCount() < 0 || current.isEmpty()) { 25 | current.setCount(0); 26 | } 27 | 28 | if (!current.isEmpty() && !ItemStack.isSame(stack, current)) 29 | return false; 30 | 31 | if (stack.getCount() < 0) { 32 | stack.setCount(0); 33 | return false; 34 | } 35 | 36 | if (current.getCount() >= LIMIT) 37 | return false; 38 | 39 | boolean increment = false; 40 | if (current.isEmpty() || current.getCount() == 0) { 41 | insertItem(0, new ItemStack(stack.getItem(), 1)); 42 | increment = true; 43 | } 44 | 45 | final var copy = new ItemStack(stack.getItem(), getItemInSlot(0).getCount()); 46 | if (current.getCount() + stack.getCount() > LIMIT) { 47 | final int available = LIMIT - copy.getCount(); 48 | stack.shrink(available); 49 | copy.setCount(LIMIT); 50 | } else { 51 | copy.grow(stack.getCount()); 52 | stack.shrink(stack.getCount()); 53 | } 54 | 55 | if (increment || copy.getCount() == 1) { 56 | copy.shrink(1); 57 | } 58 | 59 | if (currentCount != copy.getCount()) { 60 | this.inventory.setStackInSlot(0, copy); 61 | update(); 62 | return true; 63 | } 64 | 65 | return false; 66 | } 67 | 68 | @Override 69 | public void load(CompoundTag compound) { 70 | final CompoundTag inventory = compound.getCompound("Inventory"); 71 | this.inventory.setSize( 72 | inventory.contains("Size", Tag.TAG_INT) ? inventory.getInt("Size") : this.inventory.getSlots()); 73 | 74 | final ListTag items = inventory.getList("Items", Tag.TAG_COMPOUND); 75 | for (int index = 0; index < items.size(); index++) { 76 | final CompoundTag itemTags = items.getCompound(index); 77 | final int slot = itemTags.getInt("Slot"); 78 | 79 | if (slot >= 0 && slot < this.inventory.getSlots()) { 80 | final var stack = ItemStack.of(itemTags); 81 | stack.setCount(itemTags.getInt("RealCount")); 82 | this.inventory.setStackInSlot(slot, stack); 83 | } 84 | } 85 | 86 | this.setChanged(); 87 | } 88 | 89 | public boolean prependItem(Player player) { 90 | final ItemStack current = getItemInSlot(0); 91 | final ItemStack copy = current.copy(); 92 | 93 | final int currentCount = current.getCount(); 94 | if (current.getCount() <= 0) 95 | return false; 96 | 97 | getItemInSlot(0).shrink(1); 98 | 99 | if (currentCount != current.getCount()) { 100 | copy.setCount(1); 101 | final var item = new ItemEntity(this.level, player.getX(), player.getY() + 0.5D, player.getZ(), copy); 102 | this.level.addFreshEntity(item); 103 | update(); 104 | return true; 105 | } 106 | 107 | return false; 108 | } 109 | 110 | public boolean prependStack(Player player) { 111 | final ItemStack current = getItemInSlot(0); 112 | final ItemStack copy = current.copy(); 113 | 114 | final int currentCount = current.getCount(); 115 | if (current.getCount() <= 0) 116 | return false; 117 | 118 | int count = 0; 119 | if (currentCount >= 64) { 120 | count = 64; 121 | current.shrink(64); 122 | } else { 123 | count = currentCount; 124 | this.inventory.setStackInSlot(0, ItemStack.EMPTY); 125 | } 126 | 127 | if (currentCount != current.getCount() && count != 0) { 128 | copy.setCount(count); 129 | final var item = new ItemEntity(this.level, player.getX(), player.getY() + 0.5D, player.getZ(), copy); 130 | this.level.addFreshEntity(item); 131 | update(); 132 | return true; 133 | } 134 | 135 | return false; 136 | } 137 | 138 | @Override 139 | public void saveAdditional(CompoundTag compound) { 140 | final var items = new ListTag(); 141 | for (int slot = 0; slot < this.inventory.getSlots(); slot++) { 142 | if (!this.inventory.getStackInSlot(slot).isEmpty()) { 143 | final var item = new CompoundTag(); 144 | item.putInt("Slot", slot); 145 | this.inventory.getStackInSlot(slot).save(item); 146 | item.putInt("RealCount", this.inventory.getStackInSlot(slot).getCount()); 147 | items.add(item); 148 | } 149 | } 150 | 151 | final var inventory = new CompoundTag(); 152 | inventory.put("Items", items); 153 | inventory.putInt("Size", this.inventory.getSlots()); 154 | compound.put("Inventory", inventory); 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/entity/EnergyGeneratorBlockEntity.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block.entity; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.block.entity.util.CustomEnergyStorage; 5 | import io.github.darealturtywurty.tutorialmod.common.block.entity.util.InventoryBlockEntity; 6 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 7 | import net.minecraft.core.BlockPos; 8 | import net.minecraft.core.Direction; 9 | import net.minecraft.nbt.CompoundTag; 10 | import net.minecraft.network.chat.Component; 11 | import net.minecraft.network.chat.TranslatableComponent; 12 | import net.minecraft.world.item.ItemStack; 13 | import net.minecraft.world.item.crafting.RecipeType; 14 | import net.minecraft.world.level.Level; 15 | import net.minecraft.world.level.block.entity.BlockEntity; 16 | import net.minecraft.world.level.block.entity.BlockEntityTicker; 17 | import net.minecraft.world.level.block.state.BlockState; 18 | import net.minecraftforge.common.ForgeHooks; 19 | import net.minecraftforge.common.capabilities.Capability; 20 | import net.minecraftforge.common.util.LazyOptional; 21 | import net.minecraftforge.energy.CapabilityEnergy; 22 | 23 | public class EnergyGeneratorBlockEntity extends InventoryBlockEntity 24 | implements BlockEntityTicker { 25 | public static final Component TITLE = new TranslatableComponent( 26 | "container." + TutorialMod.MODID + ".energy_generator"); 27 | 28 | public final CustomEnergyStorage energyStorage; 29 | 30 | private int capacity = 2000, maxExtract = 100; 31 | private int progress, maxProgress = 0; 32 | private LazyOptional energy; 33 | 34 | public EnergyGeneratorBlockEntity(BlockPos pos, BlockState state) { 35 | super(BlockEntityInit.ENERGY_GENERATOR.get(), pos, state, 1); 36 | this.energyStorage = createEnergyStorage(); 37 | this.energy = LazyOptional.of(() -> this.energyStorage); 38 | } 39 | 40 | @Override 41 | public LazyOptional getCapability(Capability cap, Direction side) { 42 | return cap == CapabilityEnergy.ENERGY ? this.energy.cast() : super.getCapability(cap, side); 43 | } 44 | 45 | public int getEnergy() { 46 | return this.energyStorage.getEnergyStored(); 47 | } 48 | 49 | public int getEnergyForStack(ItemStack stack) { 50 | return ForgeHooks.getBurnTime(stack, RecipeType.SMELTING); 51 | } 52 | 53 | public int getMaxProgress() { 54 | return this.maxProgress; 55 | } 56 | 57 | public int getProgress() { 58 | return this.progress; 59 | } 60 | 61 | @Override 62 | public void invalidateCaps() { 63 | super.invalidateCaps(); 64 | this.energy.invalidate(); 65 | } 66 | 67 | @Override 68 | public void load(CompoundTag tag) { 69 | super.load(tag); 70 | this.progress = tag.getInt("Progress"); 71 | this.energyStorage.setEnergy(tag.getInt("Energy")); 72 | } 73 | 74 | public void outputEnergy() { 75 | if (this.energyStorage.getEnergyStored() >= this.maxExtract && this.energyStorage.canExtract()) { 76 | for (final var direction : Direction.values()) { 77 | final BlockEntity be = this.level.getBlockEntity(this.worldPosition.relative(direction)); 78 | if (be == null) { 79 | continue; 80 | } 81 | 82 | be.getCapability(CapabilityEnergy.ENERGY, direction.getOpposite()).ifPresent(storage -> { 83 | if (be != this && storage.getEnergyStored() < storage.getMaxEnergyStored()) { 84 | final int toSend = EnergyGeneratorBlockEntity.this.energyStorage.extractEnergy(this.maxExtract, 85 | false); 86 | TutorialMod.LOGGER.info("Send: {}", toSend); 87 | final int received = storage.receiveEnergy(toSend, false); 88 | TutorialMod.LOGGER.info("Final Received: {}", received); 89 | 90 | EnergyGeneratorBlockEntity.this.energyStorage.setEnergy( 91 | EnergyGeneratorBlockEntity.this.energyStorage.getEnergyStored() + toSend - received); 92 | } 93 | }); 94 | } 95 | } 96 | } 97 | 98 | @Override 99 | public void tick() { 100 | if (this.energyStorage.getEnergyStored() <= this.energyStorage.getMaxEnergyStored() - 100) { 101 | if (!getItemInSlot(0).isEmpty() && (this.progress <= 0 || this.progress > this.maxProgress)) { 102 | this.maxProgress = getEnergyForStack(getItemInSlot(0)); 103 | this.inventory.extractItem(0, 1, false); 104 | this.progress++; 105 | } else if (this.progress > 0) { 106 | this.progress++; 107 | if (this.progress >= this.maxProgress) { 108 | this.progress = 0; 109 | this.energyStorage.setEnergy(this.energyStorage.getEnergyStored() + this.maxProgress); 110 | } 111 | } else { 112 | this.progress = 0; 113 | this.maxProgress = 0; 114 | } 115 | } 116 | 117 | outputEnergy(); 118 | 119 | super.tick(); 120 | } 121 | 122 | @Override 123 | public void tick(Level level, BlockPos pos, BlockState state, EnergyGeneratorBlockEntity be) { 124 | be.tick(); 125 | } 126 | 127 | @Override 128 | protected void saveAdditional(CompoundTag tag) { 129 | super.saveAdditional(tag); 130 | tag.putInt("Progress", this.progress); 131 | tag.putInt("Energy", getEnergy()); 132 | } 133 | 134 | private CustomEnergyStorage createEnergyStorage() { 135 | return new CustomEnergyStorage(this, this.capacity, 0, this.maxExtract, 0); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/entity/EnergyStorageBlockEntity.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block.entity; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.block.entity.util.CustomEnergyStorage; 5 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 6 | import io.github.darealturtywurty.tutorialmod.core.init.PacketHandler; 7 | import io.github.darealturtywurty.tutorialmod.core.network.ClientboundUpdateEnergyStorageScreenPacket; 8 | import net.minecraft.core.BlockPos; 9 | import net.minecraft.core.Direction; 10 | import net.minecraft.nbt.CompoundTag; 11 | import net.minecraft.network.Connection; 12 | import net.minecraft.network.protocol.Packet; 13 | import net.minecraft.network.protocol.game.ClientGamePacketListener; 14 | import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; 15 | import net.minecraft.world.level.Level; 16 | import net.minecraft.world.level.block.entity.BlockEntity; 17 | import net.minecraft.world.level.block.entity.BlockEntityTicker; 18 | import net.minecraft.world.level.block.state.BlockState; 19 | import net.minecraftforge.common.capabilities.Capability; 20 | import net.minecraftforge.common.util.LazyOptional; 21 | import net.minecraftforge.energy.CapabilityEnergy; 22 | import net.minecraftforge.network.PacketDistributor; 23 | 24 | public class EnergyStorageBlockEntity extends BlockEntity implements BlockEntityTicker { 25 | public final CustomEnergyStorage energyStorage; 26 | private LazyOptional energy; 27 | 28 | private int capacity = 10000, maxExtract = 100, maxReceive = 500; 29 | 30 | public EnergyStorageBlockEntity(BlockPos pos, BlockState state) { 31 | super(BlockEntityInit.ENERGY_STORAGE.get(), pos, state); 32 | this.energyStorage = createEnergyStorage(); 33 | this.energy = LazyOptional.of(() -> this.energyStorage); 34 | } 35 | 36 | @Override 37 | public LazyOptional getCapability(Capability cap, Direction side) { 38 | return cap == CapabilityEnergy.ENERGY ? this.energy.cast() : super.getCapability(cap, side); 39 | } 40 | 41 | @Override 42 | public Packet getUpdatePacket() { 43 | return ClientboundBlockEntityDataPacket.create(this); 44 | } 45 | 46 | @Override 47 | public CompoundTag getUpdateTag() { 48 | return serializeNBT(); 49 | } 50 | 51 | @Override 52 | public void handleUpdateTag(CompoundTag tag) { 53 | super.handleUpdateTag(tag); 54 | load(tag); 55 | } 56 | 57 | @Override 58 | public void invalidateCaps() { 59 | super.invalidateCaps(); 60 | this.energy.invalidate(); 61 | } 62 | 63 | @Override 64 | public void load(CompoundTag tag) { 65 | super.load(tag); 66 | this.energyStorage.setEnergy(tag.getInt("Energy")); 67 | this.setChanged(); 68 | } 69 | 70 | @Override 71 | public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { 72 | super.onDataPacket(net, pkt); 73 | handleUpdateTag(pkt.getTag()); 74 | } 75 | 76 | public void tick() { 77 | // TODO: Extract to all sides 78 | } 79 | 80 | @Override 81 | public void tick(Level level, BlockPos pos, BlockState state, EnergyStorageBlockEntity blockEntity) { 82 | blockEntity.tick(); 83 | } 84 | 85 | public void update() { 86 | requestModelDataUpdate(); 87 | setChanged(); 88 | if (this.level != null) { 89 | this.level.setBlockAndUpdate(this.worldPosition, getBlockState()); 90 | } 91 | } 92 | 93 | @Override 94 | protected void saveAdditional(CompoundTag tag) { 95 | super.saveAdditional(tag); 96 | tag.putInt("Energy", this.energyStorage.getEnergyStored()); 97 | } 98 | 99 | private CustomEnergyStorage createEnergyStorage() { 100 | return new CustomEnergyStorage(this, this.capacity, this.maxReceive, this.maxExtract, 0) { 101 | @Override 102 | public int extractEnergy(int maxExtract, boolean simulate) { 103 | final int e = super.extractEnergy(maxExtract, simulate); 104 | PacketHandler.INSTANCE.send(PacketDistributor.ALL.noArg(), 105 | new ClientboundUpdateEnergyStorageScreenPacket(this.energy)); 106 | return e; 107 | } 108 | 109 | @Override 110 | public int receiveEnergy(int maxReceive, boolean simulate) { 111 | final int e = super.receiveEnergy(maxReceive, simulate); 112 | PacketHandler.INSTANCE.send(PacketDistributor.ALL.noArg(), 113 | new ClientboundUpdateEnergyStorageScreenPacket(this.energy)); 114 | TutorialMod.LOGGER.info("Received: {}", e); 115 | TutorialMod.LOGGER.info("Current: {}", this.energy); 116 | return e; 117 | } 118 | }; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/entity/ExampleChestBlockEntity.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block.entity; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.block.entity.util.InventoryBlockEntity; 5 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.network.chat.Component; 8 | import net.minecraft.network.chat.TranslatableComponent; 9 | import net.minecraft.world.level.block.state.BlockState; 10 | 11 | public class ExampleChestBlockEntity extends InventoryBlockEntity { 12 | public static final Component TITLE = new TranslatableComponent( 13 | "container." + TutorialMod.MODID + ".example_chest"); 14 | 15 | public ExampleChestBlockEntity(BlockPos pos, BlockState state) { 16 | super(BlockEntityInit.EXAMPLE_CHEST.get(), pos, state, 27); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/entity/PoopStorageBlockEntity.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block.entity; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.block.entity.util.InventoryBlockEntity; 5 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.network.chat.Component; 8 | import net.minecraft.network.chat.TranslatableComponent; 9 | import net.minecraft.world.level.block.state.BlockState; 10 | 11 | public class PoopStorageBlockEntity extends InventoryBlockEntity { 12 | public static final Component TITLE = new TranslatableComponent("container." + TutorialMod.MODID + ".poop_storage"); 13 | 14 | public PoopStorageBlockEntity(BlockPos pos, BlockState state) { 15 | super(BlockEntityInit.POOP_STORAGE.get(), pos, state, 1); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/entity/ToiletBlockEntity.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block.entity; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.UUID; 6 | 7 | import io.github.darealturtywurty.tutorialmod.common.entity.SittableEntity; 8 | import io.github.darealturtywurty.tutorialmod.core.init.BlockEntityInit; 9 | import io.github.darealturtywurty.tutorialmod.core.init.PacketHandler; 10 | import io.github.darealturtywurty.tutorialmod.core.init.SoundInit; 11 | import io.github.darealturtywurty.tutorialmod.core.network.ClientboundUpdateToiletPacket; 12 | import io.github.darealturtywurty.tutorialmod.core.network.ServerboundToiletUpdatePacket; 13 | import net.minecraft.core.BlockPos; 14 | import net.minecraft.nbt.CompoundTag; 15 | import net.minecraft.nbt.ListTag; 16 | import net.minecraft.nbt.Tag; 17 | import net.minecraft.network.Connection; 18 | import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; 19 | import net.minecraft.sounds.SoundSource; 20 | import net.minecraft.world.entity.player.Player; 21 | import net.minecraft.world.level.block.HorizontalDirectionalBlock; 22 | import net.minecraft.world.level.block.entity.BlockEntity; 23 | import net.minecraft.world.level.block.state.BlockState; 24 | import net.minecraftforge.network.PacketDistributor; 25 | 26 | public class ToiletBlockEntity extends BlockEntity { 27 | public static final int FART_TIME = 40; 28 | public SittableEntity seat; 29 | public int ticks = 0, fartTicker = 0; 30 | public final Map playerUses = new HashMap<>(); 31 | public boolean isShitting; 32 | 33 | public ToiletBlockEntity(BlockPos pos, BlockState state) { 34 | super(BlockEntityInit.TOILET.get(), pos, state); 35 | } 36 | 37 | public SittableEntity getOrCreateSeat() { 38 | if (this.seat == null) { 39 | final var seat = new SittableEntity(this.level); 40 | seat.absMoveTo(this.worldPosition.getX() + 0.5D, this.worldPosition.getY(), 41 | this.worldPosition.getZ() + 0.5D, 42 | getBlockState().getValue(HorizontalDirectionalBlock.FACING).toYRot(), 0.0f); 43 | this.level.addFreshEntity(seat); 44 | this.seat = seat; 45 | } 46 | 47 | return this.seat; 48 | } 49 | 50 | @Override 51 | public ClientboundBlockEntityDataPacket getUpdatePacket() { 52 | return ClientboundBlockEntityDataPacket.create(this); 53 | } 54 | 55 | @Override 56 | public CompoundTag getUpdateTag() { 57 | return serializeNBT(); 58 | } 59 | 60 | @Override 61 | public void handleUpdateTag(CompoundTag tag) { 62 | load(tag); 63 | } 64 | 65 | @Override 66 | public void load(CompoundTag nbt) { 67 | super.load(nbt); 68 | 69 | final ListTag playerUses = nbt.getList("PlayerUseMap", Tag.TAG_COMPOUND); 70 | playerUses.forEach(player -> { 71 | if (player instanceof final CompoundTag tag) { 72 | final UUID uuid = tag.getUUID("UUID"); 73 | final int uses = tag.getInt("Uses"); 74 | this.playerUses.put(uuid, uses); 75 | } 76 | }); 77 | } 78 | 79 | @Override 80 | public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { 81 | load(pkt.getTag()); 82 | } 83 | 84 | @Override 85 | public void onLoad() { 86 | super.onLoad(); 87 | getOrCreateSeat(); 88 | } 89 | 90 | @Override 91 | public void saveAdditional(CompoundTag nbt) { 92 | super.saveAdditional(nbt); 93 | 94 | final var playerUses = new ListTag(); 95 | this.playerUses.forEach((uuid, uses) -> { 96 | final var playerTag = new CompoundTag(); 97 | playerTag.putUUID("UUID", uuid); 98 | playerTag.putInt("Uses", uses); 99 | playerUses.add(playerTag); 100 | }); 101 | 102 | nbt.put("PlayerUseMap", playerUses); 103 | } 104 | 105 | @Override 106 | public void setRemoved() { 107 | super.setRemoved(); 108 | if (this.seat != null) { 109 | this.seat.kill(); 110 | } 111 | } 112 | 113 | public void setShitting() { 114 | if (!this.isShitting) { 115 | this.isShitting = true; 116 | this.fartTicker = 0; 117 | PacketHandler.INSTANCE.sendToServer(new ServerboundToiletUpdatePacket(this.worldPosition)); 118 | } 119 | } 120 | 121 | public void tick() { 122 | if (this.isShitting) { 123 | if (this.fartTicker <= 0) { 124 | this.level.playSound((Player) null, this.worldPosition, SoundInit.FART.get(), SoundSource.BLOCKS, 1.0f, 125 | 1.0f); 126 | } 127 | 128 | if (++this.fartTicker >= FART_TIME) { 129 | this.isShitting = false; 130 | this.fartTicker = 0; 131 | this.seat.ejectPassengers(); 132 | PacketHandler.INSTANCE.send( 133 | PacketDistributor.TRACKING_CHUNK.with(() -> this.level.getChunkAt(this.worldPosition)), 134 | new ClientboundUpdateToiletPacket(this.worldPosition)); 135 | } 136 | } 137 | 138 | if (this.ticks % 5 == 0 && (this.seat == null || this.seat.isRemoved())) { 139 | if (this.seat != null) { 140 | this.seat.kill(); 141 | this.seat = null; 142 | } 143 | getOrCreateSeat(); 144 | } 145 | this.ticks++; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/entity/util/CustomEnergyStorage.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block.entity.util; 2 | 3 | import net.minecraft.world.level.block.entity.BlockEntity; 4 | import net.minecraftforge.energy.EnergyStorage; 5 | 6 | public class CustomEnergyStorage extends EnergyStorage { 7 | private final BlockEntity blockEntity; 8 | 9 | public CustomEnergyStorage(BlockEntity blockEntity, int capacity) { 10 | super(capacity); 11 | this.blockEntity = blockEntity; 12 | } 13 | 14 | public CustomEnergyStorage(BlockEntity blockEntity, int capacity, int maxTransfer) { 15 | super(capacity, maxTransfer); 16 | this.blockEntity = blockEntity; 17 | } 18 | 19 | public CustomEnergyStorage(BlockEntity blockEntity, int capacity, int maxReceive, int maxExtract) { 20 | super(capacity, maxReceive, maxExtract); 21 | this.blockEntity = blockEntity; 22 | } 23 | 24 | public CustomEnergyStorage(BlockEntity blockEntity, int capacity, int maxReceive, int maxExtract, int energy) { 25 | super(capacity, maxReceive, maxExtract, energy); 26 | this.blockEntity = blockEntity; 27 | } 28 | 29 | @Override 30 | public int extractEnergy(int maxExtract, boolean simulate) { 31 | this.blockEntity.setChanged(); 32 | return super.extractEnergy(maxExtract, simulate); 33 | } 34 | 35 | @Override 36 | public int receiveEnergy(int maxReceive, boolean simulate) { 37 | this.blockEntity.setChanged(); 38 | return super.receiveEnergy(maxReceive, simulate); 39 | } 40 | 41 | public void setEnergy(int energy) { 42 | this.energy = Math.max(0, Math.min(energy, this.capacity)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/block/entity/util/InventoryBlockEntity.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.block.entity.util; 2 | 3 | import net.minecraft.core.BlockPos; 4 | import net.minecraft.core.Direction; 5 | import net.minecraft.nbt.CompoundTag; 6 | import net.minecraft.network.Connection; 7 | import net.minecraft.network.protocol.Packet; 8 | import net.minecraft.network.protocol.game.ClientGamePacketListener; 9 | import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; 10 | import net.minecraft.world.item.ItemStack; 11 | import net.minecraft.world.level.block.entity.BlockEntity; 12 | import net.minecraft.world.level.block.entity.BlockEntityType; 13 | import net.minecraft.world.level.block.state.BlockState; 14 | import net.minecraftforge.common.capabilities.Capability; 15 | import net.minecraftforge.common.util.LazyOptional; 16 | import net.minecraftforge.items.CapabilityItemHandler; 17 | import net.minecraftforge.items.ItemStackHandler; 18 | 19 | public class InventoryBlockEntity extends BlockEntity { 20 | public final int size; 21 | protected int timer; 22 | protected boolean requiresUpdate; 23 | 24 | public final ItemStackHandler inventory; 25 | protected LazyOptional handler; 26 | 27 | public InventoryBlockEntity(BlockEntityType type, BlockPos pos, BlockState state, int size) { 28 | super(type, pos, state); 29 | if (size <= 0) { 30 | size = 1; 31 | } 32 | 33 | this.size = size; 34 | this.inventory = createInventory(); 35 | this.handler = LazyOptional.of(() -> this.inventory); 36 | } 37 | 38 | public ItemStack extractItem(int slot) { 39 | final int count = getItemInSlot(slot).getCount(); 40 | this.requiresUpdate = true; 41 | return this.handler.map(inv -> inv.extractItem(slot, count, false)).orElse(ItemStack.EMPTY); 42 | } 43 | 44 | @Override 45 | public LazyOptional getCapability(Capability cap, Direction side) { 46 | return cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY ? this.handler.cast() 47 | : super.getCapability(cap, side); 48 | } 49 | 50 | public LazyOptional getHandler() { 51 | return this.handler; 52 | } 53 | 54 | public ItemStack getItemInSlot(int slot) { 55 | return this.handler.map(inv -> inv.getStackInSlot(slot)).orElse(ItemStack.EMPTY); 56 | } 57 | 58 | @Override 59 | public Packet getUpdatePacket() { 60 | return ClientboundBlockEntityDataPacket.create(this); 61 | } 62 | 63 | @Override 64 | public CompoundTag getUpdateTag() { 65 | return serializeNBT(); 66 | } 67 | 68 | @Override 69 | public void handleUpdateTag(CompoundTag tag) { 70 | super.handleUpdateTag(tag); 71 | load(tag); 72 | } 73 | 74 | public ItemStack insertItem(int slot, ItemStack stack) { 75 | final ItemStack copy = stack.copy(); 76 | stack.shrink(copy.getCount()); 77 | this.requiresUpdate = true; 78 | return this.handler.map(inv -> inv.insertItem(slot, copy, false)).orElse(ItemStack.EMPTY); 79 | } 80 | 81 | @Override 82 | public void invalidateCaps() { 83 | super.invalidateCaps(); 84 | this.handler.invalidate(); 85 | } 86 | 87 | @Override 88 | public void load(CompoundTag tag) { 89 | super.load(tag); 90 | this.inventory.deserializeNBT(tag.getCompound("Inventory")); 91 | } 92 | 93 | @Override 94 | public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { 95 | super.onDataPacket(net, pkt); 96 | handleUpdateTag(pkt.getTag()); 97 | } 98 | 99 | public void tick() { 100 | this.timer++; 101 | if (this.requiresUpdate && this.level != null) { 102 | update(); 103 | this.requiresUpdate = false; 104 | } 105 | } 106 | 107 | public void update() { 108 | requestModelDataUpdate(); 109 | setChanged(); 110 | if (this.level != null) { 111 | this.level.setBlockAndUpdate(this.worldPosition, getBlockState()); 112 | } 113 | } 114 | 115 | @Override 116 | protected void saveAdditional(CompoundTag tag) { 117 | super.saveAdditional(tag); 118 | tag.put("Inventory", this.inventory.serializeNBT()); 119 | } 120 | 121 | private ItemStackHandler createInventory() { 122 | return new ItemStackHandler(this.size) { 123 | @Override 124 | public ItemStack extractItem(int slot, int amount, boolean simulate) { 125 | InventoryBlockEntity.this.update(); 126 | return super.extractItem(slot, amount, simulate); 127 | } 128 | 129 | @Override 130 | public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { 131 | InventoryBlockEntity.this.update(); 132 | return super.insertItem(slot, stack, simulate); 133 | } 134 | }; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/container/EnergyGeneratorContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.container; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.EnergyGeneratorBlockEntity; 4 | import io.github.darealturtywurty.tutorialmod.common.container.syncdata.EnergyGeneratorContainerData; 5 | import io.github.darealturtywurty.tutorialmod.core.init.BlockInit; 6 | import io.github.darealturtywurty.tutorialmod.core.init.ContainerInit; 7 | import net.minecraft.core.BlockPos; 8 | import net.minecraft.world.entity.player.Inventory; 9 | import net.minecraft.world.entity.player.Player; 10 | import net.minecraft.world.inventory.AbstractContainerMenu; 11 | import net.minecraft.world.inventory.ContainerData; 12 | import net.minecraft.world.inventory.ContainerLevelAccess; 13 | import net.minecraft.world.inventory.MenuConstructor; 14 | import net.minecraft.world.inventory.SimpleContainerData; 15 | import net.minecraft.world.inventory.Slot; 16 | import net.minecraft.world.item.ItemStack; 17 | import net.minecraftforge.items.IItemHandler; 18 | import net.minecraftforge.items.ItemStackHandler; 19 | import net.minecraftforge.items.SlotItemHandler; 20 | 21 | public class EnergyGeneratorContainer extends AbstractContainerMenu { 22 | private final ContainerLevelAccess containerAccess; 23 | public final ContainerData data; 24 | 25 | // Client Constructor 26 | public EnergyGeneratorContainer(int id, Inventory playerInv) { 27 | this(id, playerInv, new ItemStackHandler(1), BlockPos.ZERO, new SimpleContainerData(4)); 28 | } 29 | 30 | // Server constructor 31 | public EnergyGeneratorContainer(int id, Inventory playerInv, IItemHandler slots, BlockPos pos, ContainerData data) { 32 | super(ContainerInit.ENERGY_GENERATOR.get(), id); 33 | this.containerAccess = ContainerLevelAccess.create(playerInv.player.level, pos); 34 | this.data = data; 35 | 36 | final int slotSizePlus2 = 18, startX = 8, startY = 86, hotbarY = 144; 37 | 38 | addSlot(new SlotItemHandler(slots, 0, 44, 36)); 39 | 40 | for (int row = 0; row < 3; row++) { 41 | for (int column = 0; column < 9; column++) { 42 | addSlot(new Slot(playerInv, 9 + row * 9 + column, startX + column * slotSizePlus2, 43 | startY + row * slotSizePlus2)); 44 | } 45 | } 46 | 47 | for (int column = 0; column < 9; column++) { 48 | addSlot(new Slot(playerInv, column, startX + column * slotSizePlus2, hotbarY)); 49 | } 50 | 51 | addDataSlots(data); 52 | } 53 | 54 | @Override 55 | public ItemStack quickMoveStack(Player player, int index) { 56 | var retStack = ItemStack.EMPTY; 57 | final Slot slot = getSlot(index); 58 | if (slot.hasItem()) { 59 | final ItemStack item = slot.getItem(); 60 | retStack = item.copy(); 61 | if (index < 1) { 62 | if (!moveItemStackTo(item, 1, this.slots.size(), true)) 63 | return ItemStack.EMPTY; 64 | } else if (!moveItemStackTo(item, 0, 1, false)) 65 | return ItemStack.EMPTY; 66 | 67 | if (item.isEmpty()) { 68 | slot.set(ItemStack.EMPTY); 69 | } else { 70 | slot.setChanged(); 71 | } 72 | } 73 | 74 | return retStack; 75 | } 76 | 77 | @Override 78 | public boolean stillValid(Player player) { 79 | return stillValid(this.containerAccess, player, BlockInit.ENERGY_GENERATOR.get()); 80 | } 81 | 82 | public static MenuConstructor getServerContainer(EnergyGeneratorBlockEntity be, BlockPos pos) { 83 | return (id, playerInv, player) -> new EnergyGeneratorContainer(id, playerInv, be.inventory, pos, 84 | new EnergyGeneratorContainerData(be, 4)); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/container/ExampleChestContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.container; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.ExampleChestBlockEntity; 4 | import io.github.darealturtywurty.tutorialmod.core.init.BlockInit; 5 | import io.github.darealturtywurty.tutorialmod.core.init.ContainerInit; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.world.entity.player.Inventory; 8 | import net.minecraft.world.entity.player.Player; 9 | import net.minecraft.world.inventory.AbstractContainerMenu; 10 | import net.minecraft.world.inventory.ContainerLevelAccess; 11 | import net.minecraft.world.inventory.MenuConstructor; 12 | import net.minecraft.world.inventory.Slot; 13 | import net.minecraft.world.item.ItemStack; 14 | import net.minecraftforge.items.IItemHandler; 15 | import net.minecraftforge.items.ItemStackHandler; 16 | import net.minecraftforge.items.SlotItemHandler; 17 | 18 | public class ExampleChestContainer extends AbstractContainerMenu { 19 | private final ContainerLevelAccess containerAccess; 20 | 21 | // Client Constructor 22 | public ExampleChestContainer(int id, Inventory playerInv) { 23 | this(id, playerInv, new ItemStackHandler(27), BlockPos.ZERO); 24 | } 25 | 26 | // Server constructor 27 | public ExampleChestContainer(int id, Inventory playerInv, IItemHandler slots, BlockPos pos) { 28 | super(ContainerInit.EXAMPLE_CHEST.get(), id); 29 | this.containerAccess = ContainerLevelAccess.create(playerInv.player.level, pos); 30 | 31 | final int slotSizePlus2 = 18, startX = 8, startY = 86, hotbarY = 144, inventoryY = 18; 32 | 33 | for (int row = 0; row < 3; row++) { 34 | for (int column = 0; column < 9; column++) { 35 | addSlot(new SlotItemHandler(slots, row * 9 + column, startX + column * slotSizePlus2, 36 | inventoryY + row * slotSizePlus2)); 37 | } 38 | } 39 | 40 | for (int row = 0; row < 3; row++) { 41 | for (int column = 0; column < 9; column++) { 42 | addSlot(new Slot(playerInv, 9 + row * 9 + column, startX + column * slotSizePlus2, 43 | startY + row * slotSizePlus2)); 44 | } 45 | } 46 | 47 | for (int column = 0; column < 9; column++) { 48 | addSlot(new Slot(playerInv, column, startX + column * slotSizePlus2, hotbarY)); 49 | } 50 | } 51 | 52 | @Override 53 | public ItemStack quickMoveStack(Player player, int index) { 54 | var retStack = ItemStack.EMPTY; 55 | final Slot slot = getSlot(index); 56 | if (slot.hasItem()) { 57 | final ItemStack item = slot.getItem(); 58 | retStack = item.copy(); 59 | if (index < 27) { 60 | if (!moveItemStackTo(item, 27, this.slots.size(), true)) 61 | return ItemStack.EMPTY; 62 | } else if (!moveItemStackTo(item, 0, 27, false)) 63 | return ItemStack.EMPTY; 64 | 65 | if (item.isEmpty()) { 66 | slot.set(ItemStack.EMPTY); 67 | } else { 68 | slot.setChanged(); 69 | } 70 | } 71 | 72 | return retStack; 73 | } 74 | 75 | @Override 76 | public boolean stillValid(Player player) { 77 | return stillValid(this.containerAccess, player, BlockInit.EXAMPLE_CHEST.get()); 78 | } 79 | 80 | public static MenuConstructor getServerContainer(ExampleChestBlockEntity chest, BlockPos pos) { 81 | return (id, playerInv, player) -> new ExampleChestContainer(id, playerInv, chest.inventory, pos); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/container/PoopStorageContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.container; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.PoopStorageBlockEntity; 4 | import io.github.darealturtywurty.tutorialmod.common.container.syncdata.PoopStorageContainerData; 5 | import io.github.darealturtywurty.tutorialmod.core.init.BlockInit; 6 | import io.github.darealturtywurty.tutorialmod.core.init.ContainerInit; 7 | import net.minecraft.core.BlockPos; 8 | import net.minecraft.world.entity.player.Inventory; 9 | import net.minecraft.world.entity.player.Player; 10 | import net.minecraft.world.inventory.AbstractContainerMenu; 11 | import net.minecraft.world.inventory.ContainerData; 12 | import net.minecraft.world.inventory.ContainerLevelAccess; 13 | import net.minecraft.world.inventory.MenuConstructor; 14 | import net.minecraft.world.inventory.SimpleContainerData; 15 | import net.minecraft.world.inventory.Slot; 16 | import net.minecraft.world.item.ItemStack; 17 | import net.minecraftforge.items.IItemHandler; 18 | import net.minecraftforge.items.ItemStackHandler; 19 | import net.minecraftforge.items.SlotItemHandler; 20 | 21 | public class PoopStorageContainer extends AbstractContainerMenu { 22 | private final ContainerLevelAccess containerAccess; 23 | public final ContainerData data; 24 | 25 | // Client Constructor 26 | public PoopStorageContainer(int id, Inventory playerInv) { 27 | this(id, playerInv, new ItemStackHandler(1), BlockPos.ZERO, new SimpleContainerData(1)); 28 | } 29 | 30 | // Server constructor 31 | public PoopStorageContainer(int id, Inventory playerInv, IItemHandler slots, BlockPos pos, ContainerData data) { 32 | super(ContainerInit.POOP_STORAGE.get(), id); 33 | this.containerAccess = ContainerLevelAccess.create(playerInv.player.level, pos); 34 | this.data = data; 35 | 36 | final int slotSizePlus2 = 18, startX = 8, startY = 86, hotbarY = 144; 37 | 38 | addSlot(new SlotItemHandler(slots, 0, 44, 36)); 39 | 40 | for (int row = 0; row < 3; row++) { 41 | for (int column = 0; column < 9; column++) { 42 | addSlot(new Slot(playerInv, 9 + row * 9 + column, startX + column * slotSizePlus2, 43 | startY + row * slotSizePlus2)); 44 | } 45 | } 46 | 47 | for (int column = 0; column < 9; column++) { 48 | addSlot(new Slot(playerInv, column, startX + column * slotSizePlus2, hotbarY)); 49 | } 50 | 51 | addDataSlots(data); 52 | } 53 | 54 | @Override 55 | public ItemStack quickMoveStack(Player player, int index) { 56 | var retStack = ItemStack.EMPTY; 57 | final Slot slot = getSlot(index); 58 | if (slot.hasItem()) { 59 | final ItemStack item = slot.getItem(); 60 | retStack = item.copy(); 61 | if (index < 1) { 62 | if (!moveItemStackTo(item, 1, this.slots.size(), true)) 63 | return ItemStack.EMPTY; 64 | } else if (!moveItemStackTo(item, 0, 1, false)) 65 | return ItemStack.EMPTY; 66 | 67 | if (item.isEmpty()) { 68 | slot.set(ItemStack.EMPTY); 69 | } else { 70 | slot.setChanged(); 71 | } 72 | } 73 | 74 | return retStack; 75 | } 76 | 77 | @Override 78 | public boolean stillValid(Player player) { 79 | return stillValid(this.containerAccess, player, BlockInit.POOP_STORAGE.get()); 80 | } 81 | 82 | public static MenuConstructor getServerContainer(PoopStorageBlockEntity be, BlockPos pos) { 83 | return (id, playerInv, player) -> new PoopStorageContainer(id, playerInv, be.inventory, pos, 84 | new PoopStorageContainerData(be, 1)); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/container/syncdata/EnergyGeneratorContainerData.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.container.syncdata; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.EnergyGeneratorBlockEntity; 4 | import net.minecraft.world.inventory.SimpleContainerData; 5 | 6 | public class EnergyGeneratorContainerData extends SimpleContainerData { 7 | private final EnergyGeneratorBlockEntity blockEntity; 8 | 9 | public EnergyGeneratorContainerData(EnergyGeneratorBlockEntity be, int amount) { 10 | super(amount); 11 | this.blockEntity = be; 12 | } 13 | 14 | @Override 15 | public int get(int key) { 16 | return switch (key) { 17 | case 0 -> this.blockEntity.getProgress(); 18 | case 1 -> this.blockEntity.getMaxProgress(); 19 | case 2 -> this.blockEntity.getEnergy(); 20 | case 3 -> this.blockEntity.energyStorage.getMaxEnergyStored(); 21 | default -> throw new UnsupportedOperationException("Unable to get key: '" + key + "' for block entity: '" 22 | + this.blockEntity + "' at pos: '" + this.blockEntity.getBlockPos() + "'"); 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/container/syncdata/PoopStorageContainerData.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.container.syncdata; 2 | 3 | import io.github.darealturtywurty.tutorialmod.common.block.entity.PoopStorageBlockEntity; 4 | import net.minecraft.world.inventory.SimpleContainerData; 5 | import net.minecraft.world.item.ItemStack; 6 | 7 | public class PoopStorageContainerData extends SimpleContainerData { 8 | private final PoopStorageBlockEntity blockEntity; 9 | 10 | public PoopStorageContainerData(PoopStorageBlockEntity be, int amount) { 11 | super(amount); 12 | this.blockEntity = be; 13 | } 14 | 15 | @Override 16 | public int get(int key) { 17 | return switch (key) { 18 | case 0 -> this.blockEntity.getItemInSlot(0).getCount(); 19 | default -> throw new UnsupportedOperationException( 20 | "There is no value corresponding to key: '" + key + "' in: '" + this.blockEntity + "'"); 21 | }; 22 | } 23 | 24 | @Override 25 | public void set(int key, int value) { 26 | switch (key) { 27 | case 0: 28 | ItemStack stack = this.blockEntity.getItemInSlot(0); 29 | if (value > 0 && value < stack.getMaxStackSize()) { 30 | stack.setCount(value); 31 | } else if (value <= 0) { 32 | stack = ItemStack.EMPTY; 33 | } else if (value > stack.getMaxStackSize()) { 34 | stack.setCount(stack.getMaxStackSize()); 35 | } 36 | 37 | this.blockEntity.inventory.setStackInSlot(0, stack); 38 | break; 39 | default: 40 | throw new UnsupportedOperationException( 41 | "There is no value corresponding to key: '" + key + "' in: '" + this.blockEntity + "'"); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/entity/ExampleEntity.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.entity; 2 | 3 | import java.util.Random; 4 | 5 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 6 | import io.github.darealturtywurty.tutorialmod.core.init.EntityInit; 7 | import io.github.darealturtywurty.tutorialmod.core.init.ItemInit; 8 | import io.github.darealturtywurty.tutorialmod.core.init.SoundInit; 9 | import net.minecraft.core.BlockPos; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.server.level.ServerLevel; 12 | import net.minecraft.sounds.SoundEvent; 13 | import net.minecraft.world.damagesource.DamageSource; 14 | import net.minecraft.world.entity.AgeableMob; 15 | import net.minecraft.world.entity.EntityType; 16 | import net.minecraft.world.entity.Mob; 17 | import net.minecraft.world.entity.MobSpawnType; 18 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 19 | import net.minecraft.world.entity.ai.attributes.Attributes; 20 | import net.minecraft.world.entity.ai.goal.BreedGoal; 21 | import net.minecraft.world.entity.ai.goal.FloatGoal; 22 | import net.minecraft.world.entity.ai.goal.FollowParentGoal; 23 | import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; 24 | import net.minecraft.world.entity.ai.goal.PanicGoal; 25 | import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal; 26 | import net.minecraft.world.entity.ai.goal.TemptGoal; 27 | import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal; 28 | import net.minecraft.world.entity.animal.Animal; 29 | import net.minecraft.world.entity.player.Player; 30 | import net.minecraft.world.item.crafting.Ingredient; 31 | import net.minecraft.world.level.Level; 32 | import net.minecraft.world.level.LevelAccessor; 33 | 34 | public class ExampleEntity extends Animal { 35 | private static final ResourceLocation LOOT_TABLE = new ResourceLocation(TutorialMod.MODID, 36 | "entities/example_entity"); 37 | 38 | public ExampleEntity(EntityType entityType, Level level) { 39 | super(entityType, level); 40 | } 41 | 42 | @Override 43 | public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob parent) { 44 | return EntityInit.EXAMPLE_ENTITY.get().create(level); 45 | } 46 | 47 | @Override 48 | protected SoundEvent getAmbientSound() { 49 | return SoundInit.EXAMPLE_ENTITY_AMBIENT.get(); 50 | } 51 | 52 | @Override 53 | protected SoundEvent getDeathSound() { 54 | return SoundInit.EXAMPLE_ENTITY_DEATH.get(); 55 | } 56 | 57 | @Override 58 | protected ResourceLocation getDefaultLootTable() { 59 | return LOOT_TABLE; 60 | } 61 | 62 | @Override 63 | protected SoundEvent getHurtSound(DamageSource source) { 64 | return SoundInit.EXAMPLE_ENTITY_HURT.get(); 65 | } 66 | 67 | @Override 68 | protected void registerGoals() { 69 | this.goalSelector.addGoal(0, new FloatGoal(this)); 70 | this.goalSelector.addGoal(1, new PanicGoal(this, 1.25D)); 71 | this.goalSelector.addGoal(3, new BreedGoal(this, 1.0D)); 72 | this.goalSelector.addGoal(4, new TemptGoal(this, 1.2D, Ingredient.of(ItemInit.EXAMPLE_ITEM.get()), false)); 73 | this.goalSelector.addGoal(5, new FollowParentGoal(this, 1.1D)); 74 | this.goalSelector.addGoal(6, new WaterAvoidingRandomStrollGoal(this, 1.0D)); 75 | this.goalSelector.addGoal(7, new LookAtPlayerGoal(this, Player.class, 6.0F)); 76 | this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); 77 | } 78 | 79 | public static boolean canSpawn(EntityType entity, LevelAccessor levelAccess, MobSpawnType spawnType, 80 | BlockPos pos, Random random) { 81 | return checkAnimalSpawnRules(entity, levelAccess, spawnType, pos, random) && pos.getY() > 70; 82 | } 83 | 84 | public static AttributeSupplier.Builder createAttributes() { 85 | return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 50.0D).add(Attributes.MOVEMENT_SPEED, 0.24D); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/entity/SittableEntity.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.entity; 2 | 3 | import io.github.darealturtywurty.tutorialmod.core.init.EntityInit; 4 | import net.minecraft.nbt.CompoundTag; 5 | import net.minecraft.network.protocol.Packet; 6 | import net.minecraft.util.Mth; 7 | import net.minecraft.world.entity.Entity; 8 | import net.minecraft.world.entity.EntityType; 9 | import net.minecraft.world.entity.MoverType; 10 | import net.minecraft.world.entity.player.Player; 11 | import net.minecraft.world.level.Level; 12 | import net.minecraft.world.level.block.state.BlockState; 13 | import net.minecraft.world.level.block.state.properties.BlockStateProperties; 14 | import net.minecraft.world.phys.Vec3; 15 | import net.minecraftforge.network.NetworkHooks; 16 | 17 | public class SittableEntity extends Entity { 18 | 19 | private BlockState seat; 20 | 21 | public SittableEntity(EntityType entityTypeIn, Level worldIn) { 22 | super(entityTypeIn, worldIn); 23 | } 24 | 25 | public SittableEntity(Level worldIn) { 26 | super(EntityInit.SEAT.get(), worldIn); 27 | } 28 | 29 | @Override 30 | public boolean canCollideWith(Entity entity) { 31 | return false; 32 | } 33 | 34 | @Override 35 | public boolean equals(Object object) { 36 | if (!(object instanceof SittableEntity)) 37 | return false; 38 | return super.equals(object) && this.seat.equals(((SittableEntity) object).seat); 39 | } 40 | 41 | @Override 42 | public Packet getAddEntityPacket() { 43 | return NetworkHooks.getEntitySpawningPacket(this); 44 | } 45 | 46 | @Override 47 | public double getPassengersRidingOffset() { 48 | return 0.25D; 49 | } 50 | 51 | @Override 52 | public float getPickRadius() { 53 | return 0.0f; 54 | } 55 | 56 | @Override 57 | public int hashCode() { 58 | return super.hashCode() + this.seat.hashCode(); 59 | } 60 | 61 | @Override 62 | public boolean isPickable() { 63 | return false; 64 | } 65 | 66 | @Override 67 | public void move(MoverType typeIn, Vec3 pos) { 68 | 69 | } 70 | 71 | @Override 72 | public void playerTouch(Player entityIn) { 73 | 74 | } 75 | 76 | @Override 77 | public void positionRider(Entity passenger) { 78 | super.positionRider(passenger); 79 | final float blockRotation = this.seat.hasProperty(BlockStateProperties.HORIZONTAL_FACING) 80 | ? this.seat.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot() 81 | : 0.0f; 82 | if (this.hasPassenger(passenger)) { 83 | float xOffset = 0.0F; 84 | final float yOffset = (float) ((isRemoved() ? (double) 0.01F : getPassengersRidingOffset()) 85 | + passenger.getMyRidingOffset()); 86 | if (getPassengers().size() > 1) { 87 | final int passengerIndex = getPassengers().indexOf(passenger); 88 | if (passengerIndex == 0) { 89 | xOffset = 0.2F; 90 | } else { 91 | xOffset = -0.6F; 92 | } 93 | } 94 | 95 | final var offset = new Vec3(xOffset, 0.0D, 0.0D) 96 | .yRot(-this.yRotO * ((float) Math.PI / 180F) - (float) Math.PI / 2F); 97 | passenger.setPos(this.getX() + offset.x, this.getY() + yOffset, this.getZ() + offset.z); 98 | passenger.setYHeadRot(passenger.getYHeadRot() + blockRotation); 99 | applyYawToEntity(passenger); 100 | } 101 | } 102 | 103 | @Override 104 | public void push(Entity entityIn) { 105 | 106 | } 107 | 108 | @Override 109 | public void tick() { 110 | super.tick(); 111 | if (this.seat == null) { 112 | this.seat = getCommandSenderWorld().getBlockState(blockPosition()); 113 | if (this.seat == null || this.seat.isAir()) { 114 | kill(); 115 | } 116 | } 117 | } 118 | 119 | @Override 120 | protected void addAdditionalSaveData(CompoundTag compound) { 121 | 122 | } 123 | 124 | protected void applyYawToEntity(Entity entityToUpdate) { 125 | entityToUpdate.setYBodyRot(this.yRotO); 126 | final float rotation = Mth.wrapDegrees(entityToUpdate.yRotO - this.yRotO); 127 | final float clampedRotation = Mth.clamp(rotation, -75.0F, 75.0F); 128 | entityToUpdate.yRotO += clampedRotation - rotation; 129 | entityToUpdate.setYHeadRot(entityToUpdate.yRotO); 130 | } 131 | 132 | @Override 133 | protected boolean canRide(Entity entityIn) { 134 | return entityIn instanceof Player; 135 | } 136 | 137 | @Override 138 | protected void checkInsideBlocks() { 139 | 140 | } 141 | 142 | @Override 143 | protected void defineSynchedData() { 144 | 145 | } 146 | 147 | @Override 148 | protected void readAdditionalSaveData(CompoundTag compound) { 149 | 150 | } 151 | } -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/item/ClickerItem.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.item; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import net.minecraft.core.BlockPos; 5 | import net.minecraft.nbt.CompoundTag; 6 | import net.minecraft.nbt.NbtUtils; 7 | import net.minecraft.nbt.Tag; 8 | import net.minecraft.world.InteractionHand; 9 | import net.minecraft.world.InteractionResult; 10 | import net.minecraft.world.InteractionResultHolder; 11 | import net.minecraft.world.entity.player.Player; 12 | import net.minecraft.world.item.Item; 13 | import net.minecraft.world.item.ItemStack; 14 | import net.minecraft.world.item.context.BlockPlaceContext; 15 | import net.minecraft.world.item.context.UseOnContext; 16 | import net.minecraft.world.level.ClipContext; 17 | import net.minecraft.world.level.Level; 18 | import net.minecraft.world.level.block.Blocks; 19 | import net.minecraft.world.level.block.state.BlockState; 20 | import net.minecraft.world.phys.BlockHitResult; 21 | 22 | public class ClickerItem extends Item { 23 | 24 | public ClickerItem(Properties properties) { 25 | super(properties); 26 | } 27 | 28 | public static boolean canInteract(Player player, BlockPos pos) { 29 | final float speed = player.getDigSpeed(player.level.getBlockState(pos), pos); 30 | return player.isCreative() || player.mayBuild() && speed > 0 && speed < Float.MAX_VALUE; 31 | } 32 | 33 | @Override 34 | public boolean isFoil(ItemStack stack) { 35 | final CompoundTag nbt = stack.getOrCreateTag(); 36 | return nbt.contains(TutorialMod.MODID, Tag.TAG_COMPOUND) 37 | && nbt.getCompound(TutorialMod.MODID).contains("ContainedBlock", Tag.TAG_COMPOUND); 38 | } 39 | 40 | @Override 41 | public InteractionResultHolder use(Level level, Player player, InteractionHand hand) { 42 | final ItemStack stack = player.getItemInHand(hand); 43 | final BlockHitResult result = Item.getPlayerPOVHitResult(level, player, ClipContext.Fluid.ANY); 44 | final BlockState state = level.getBlockState(result.getBlockPos()); 45 | if (!canInteract(player, result.getBlockPos()) || !state.isAir() 46 | || !state.canBeReplaced(new BlockPlaceContext(player, hand, stack, result))) 47 | return InteractionResultHolder.fail(stack); 48 | 49 | if (!stack.getOrCreateTag().contains(TutorialMod.MODID, Tag.TAG_COMPOUND)) { 50 | stack.getOrCreateTag().put(TutorialMod.MODID, new CompoundTag()); 51 | return InteractionResultHolder.fail(stack); 52 | } 53 | 54 | final CompoundTag nbt = stack.getOrCreateTag().getCompound(TutorialMod.MODID); 55 | if (!nbt.contains("ContainedBlock", Tag.TAG_COMPOUND)) 56 | return InteractionResultHolder.fail(stack); 57 | 58 | final BlockState toPlace = NbtUtils.readBlockState(nbt.getCompound("ContainedBlock")); 59 | level.setBlockAndUpdate(result.getBlockPos(), toPlace); 60 | nbt.remove("ContainedBlock"); 61 | return InteractionResultHolder.success(stack); 62 | } 63 | 64 | @Override 65 | public InteractionResult useOn(UseOnContext context) { 66 | final ItemStack stack = context.getItemInHand(); 67 | final var player = context.getPlayer(); 68 | final var level = player.level; 69 | final BlockPos pos = context.getClickedPos(); 70 | final BlockState state = level.getBlockState(pos); 71 | if (!canInteract(player, pos)) 72 | return InteractionResult.FAIL; 73 | 74 | if (!stack.getOrCreateTag().contains(TutorialMod.MODID, Tag.TAG_COMPOUND)) { 75 | stack.getOrCreateTag().put(TutorialMod.MODID, new CompoundTag()); 76 | } 77 | 78 | final CompoundTag nbt = stack.getOrCreateTag().getCompound(TutorialMod.MODID); 79 | if (!nbt.contains("ContainedBlock", Tag.TAG_COMPOUND)) { 80 | if (!state.isAir()) { 81 | level.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState()); 82 | nbt.put("ContainedBlock", NbtUtils.writeBlockState(state)); 83 | return InteractionResult.SUCCESS; 84 | } 85 | } else if (state.canBeReplaced(new BlockPlaceContext(context))) { 86 | level.setBlockAndUpdate(pos, NbtUtils.readBlockState(nbt.getCompound("ContainedBlock"))); 87 | nbt.remove("ContainedBlock"); 88 | return InteractionResult.SUCCESS; 89 | } 90 | 91 | return InteractionResult.FAIL; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/common/item/FuelItem.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.common.item; 2 | 3 | import java.util.function.BiFunction; 4 | 5 | import net.minecraft.world.item.Item; 6 | import net.minecraft.world.item.ItemStack; 7 | import net.minecraft.world.item.crafting.RecipeType; 8 | 9 | public class FuelItem extends Item { 10 | private final BiFunction, Integer> burnTime; 11 | 12 | public FuelItem(Properties properties, BiFunction, Integer> burnTime) { 13 | super(properties); 14 | this.burnTime = burnTime; 15 | } 16 | 17 | @Override 18 | public int getBurnTime(ItemStack itemStack, RecipeType recipeType) { 19 | return this.burnTime.apply(itemStack, recipeType); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/event/CommonForgeEvents.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.event; 2 | 3 | import java.util.List; 4 | import java.util.function.Supplier; 5 | 6 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 7 | import io.github.darealturtywurty.tutorialmod.core.init.EntityInit; 8 | import io.github.darealturtywurty.tutorialmod.core.world.OreGeneration; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.entity.MobCategory; 11 | import net.minecraft.world.item.Items; 12 | import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData; 13 | import net.minecraft.world.level.levelgen.GenerationStep.Decoration; 14 | import net.minecraft.world.level.levelgen.placement.PlacedFeature; 15 | import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; 16 | import net.minecraftforge.event.world.BiomeLoadingEvent; 17 | import net.minecraftforge.eventbus.api.EventPriority; 18 | import net.minecraftforge.eventbus.api.SubscribeEvent; 19 | import net.minecraftforge.fml.common.Mod; 20 | import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; 21 | 22 | @Mod.EventBusSubscriber(modid = TutorialMod.MODID, bus = Bus.FORGE) 23 | public class CommonForgeEvents { 24 | @SubscribeEvent(priority = EventPriority.HIGHEST) 25 | public static void biomeLoading(BiomeLoadingEvent event) { 26 | final List> features = event.getGeneration() 27 | .getFeatures(Decoration.UNDERGROUND_ORES); 28 | 29 | switch (event.getCategory()) { 30 | case NETHER -> OreGeneration.NETHER_ORES.forEach(ore -> features.add(() -> ore)); 31 | case THEEND -> OreGeneration.END_ORES.forEach(ore -> features.add(() -> ore)); 32 | default -> OreGeneration.OVERWORLD_ORES.forEach(ore -> features.add(() -> ore)); 33 | } 34 | 35 | if (event.getName().equals(new ResourceLocation("minecraft:plains"))) { 36 | event.getSpawns().addSpawn(MobCategory.CREATURE, 37 | new SpawnerData(EntityInit.EXAMPLE_ENTITY.get(), 5, 1, 7)); 38 | } 39 | } 40 | 41 | @SubscribeEvent 42 | public static void burnTime(FurnaceFuelBurnTimeEvent event) { 43 | if (event.getItemStack().getItem() == Items.BREAD) { 44 | event.setBurnTime(500); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/event/CommonModEvents.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.event; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.entity.ExampleEntity; 5 | import io.github.darealturtywurty.tutorialmod.core.init.EntityInit; 6 | import io.github.darealturtywurty.tutorialmod.core.init.PacketHandler; 7 | import io.github.darealturtywurty.tutorialmod.core.world.OreGeneration; 8 | import net.minecraft.world.entity.SpawnPlacements; 9 | import net.minecraft.world.level.levelgen.Heightmap; 10 | import net.minecraftforge.event.entity.EntityAttributeCreationEvent; 11 | import net.minecraftforge.eventbus.api.SubscribeEvent; 12 | import net.minecraftforge.fml.common.Mod; 13 | import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; 14 | import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; 15 | 16 | @Mod.EventBusSubscriber(modid = TutorialMod.MODID, bus = Bus.MOD) 17 | public class CommonModEvents { 18 | 19 | @SubscribeEvent 20 | public static void commonSetup(FMLCommonSetupEvent event) { 21 | event.enqueueWork(() -> { 22 | OreGeneration.registerOres(); 23 | PacketHandler.init(); 24 | SpawnPlacements.register(EntityInit.EXAMPLE_ENTITY.get(), SpawnPlacements.Type.ON_GROUND, 25 | Heightmap.Types.WORLD_SURFACE, ExampleEntity::canSpawn); 26 | }); 27 | } 28 | 29 | @SubscribeEvent 30 | public static void registerAttributes(EntityAttributeCreationEvent event) { 31 | event.put(EntityInit.EXAMPLE_ENTITY.get(), ExampleEntity.createAttributes().build()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/init/ArmorMaterialInit.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.init; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.core.util.BaseArmorMaterial; 5 | import net.minecraft.sounds.SoundEvents; 6 | import net.minecraft.world.item.ArmorMaterial; 7 | import net.minecraft.world.item.crafting.Ingredient; 8 | 9 | public final class ArmorMaterialInit { 10 | public static final ArmorMaterial BEANS = new BaseArmorMaterial(100, new int[] { 950, 1400, 1800, 1000 }, 11 | new int[] { 20, 35, 50, 27 }, 3.2f, 1.85f, TutorialMod.MODID + ":bean", 12 | SoundEvents.BOAT_PADDLE_WATER, () -> Ingredient.of(ItemInit.BEANS.get())); 13 | 14 | private ArmorMaterialInit() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/init/BlockEntityInit.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.init; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.block.entity.DisplayHandBlockEntity; 5 | import io.github.darealturtywurty.tutorialmod.common.block.entity.DrawerBlockEntity; 6 | import io.github.darealturtywurty.tutorialmod.common.block.entity.EnergyGeneratorBlockEntity; 7 | import io.github.darealturtywurty.tutorialmod.common.block.entity.EnergyStorageBlockEntity; 8 | import io.github.darealturtywurty.tutorialmod.common.block.entity.ExampleChestBlockEntity; 9 | import io.github.darealturtywurty.tutorialmod.common.block.entity.PoopStorageBlockEntity; 10 | import io.github.darealturtywurty.tutorialmod.common.block.entity.ToiletBlockEntity; 11 | import net.minecraft.world.level.block.entity.BlockEntityType; 12 | import net.minecraftforge.registries.DeferredRegister; 13 | import net.minecraftforge.registries.ForgeRegistries; 14 | import net.minecraftforge.registries.RegistryObject; 15 | 16 | public final class BlockEntityInit { 17 | 18 | public static final DeferredRegister> BLOCK_ENTITIES = DeferredRegister 19 | .create(ForgeRegistries.BLOCK_ENTITIES, TutorialMod.MODID); 20 | 21 | public static final RegistryObject> TOILET = BLOCK_ENTITIES.register("toilet", 22 | () -> BlockEntityType.Builder.of(ToiletBlockEntity::new, BlockInit.TOILET.get()).build(null)); 23 | 24 | public static final RegistryObject> DRAWER = BLOCK_ENTITIES.register("drawer", 25 | () -> BlockEntityType.Builder.of(DrawerBlockEntity::new, BlockInit.DRAWER.get()).build(null)); 26 | 27 | public static final RegistryObject> EXAMPLE_CHEST = BLOCK_ENTITIES 28 | .register("example_chest", () -> BlockEntityType.Builder 29 | .of(ExampleChestBlockEntity::new, BlockInit.EXAMPLE_CHEST.get()).build(null)); 30 | 31 | public static final RegistryObject> POOP_STORAGE = BLOCK_ENTITIES.register( 32 | "poop_storage", 33 | () -> BlockEntityType.Builder.of(PoopStorageBlockEntity::new, BlockInit.POOP_STORAGE.get()).build(null)); 34 | 35 | public static final RegistryObject> DISPLAY_HAND = BLOCK_ENTITIES.register( 36 | "display_hand", 37 | () -> BlockEntityType.Builder.of(DisplayHandBlockEntity::new, BlockInit.DISPLAY_HAND.get()).build(null)); 38 | 39 | public static final RegistryObject> ENERGY_STORAGE = BLOCK_ENTITIES 40 | .register("energy_storage", () -> BlockEntityType.Builder 41 | .of(EnergyStorageBlockEntity::new, BlockInit.ENERGY_STORAGE.get()).build(null)); 42 | 43 | public static final RegistryObject> ENERGY_GENERATOR = BLOCK_ENTITIES 44 | .register("energy_generator", () -> BlockEntityType.Builder 45 | .of(EnergyGeneratorBlockEntity::new, BlockInit.ENERGY_GENERATOR.get()).build(null)); 46 | 47 | private BlockEntityInit() { 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/init/BlockInit.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.init; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.block.BaseCropBlock; 5 | import io.github.darealturtywurty.tutorialmod.common.block.DisplayHandBlock; 6 | import io.github.darealturtywurty.tutorialmod.common.block.DrawerBlock; 7 | import io.github.darealturtywurty.tutorialmod.common.block.EnergyGeneratorBlock; 8 | import io.github.darealturtywurty.tutorialmod.common.block.EnergyStorageBlock; 9 | import io.github.darealturtywurty.tutorialmod.common.block.ExampleChestBlock; 10 | import io.github.darealturtywurty.tutorialmod.common.block.LightningJumperBlock; 11 | import io.github.darealturtywurty.tutorialmod.common.block.PoopStorageBlock; 12 | import io.github.darealturtywurty.tutorialmod.common.block.ToiletBlock; 13 | import net.minecraft.world.level.block.Block; 14 | import net.minecraft.world.level.block.Blocks; 15 | import net.minecraft.world.level.block.state.BlockBehaviour; 16 | import net.minecraft.world.level.material.Material; 17 | import net.minecraft.world.level.material.MaterialColor; 18 | import net.minecraftforge.registries.DeferredRegister; 19 | import net.minecraftforge.registries.ForgeRegistries; 20 | import net.minecraftforge.registries.RegistryObject; 21 | 22 | public final class BlockInit { 23 | public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, 24 | TutorialMod.MODID); 25 | 26 | public static final RegistryObject EXAMPLE_BLOCK = BLOCKS.register("example_block", 27 | () -> new Block(BlockBehaviour.Properties.of(Material.STONE, MaterialColor.TERRACOTTA_BLUE).strength(2.0f, 15f) 28 | .requiresCorrectToolForDrops().friction(0.5f))); 29 | 30 | public static final RegistryObject LIGHTNING_JUMPER = BLOCKS.register("lightning_jumper", 31 | () -> new LightningJumperBlock(BlockBehaviour.Properties.of(Material.METAL, MaterialColor.TERRACOTTA_ORANGE) 32 | .strength(8.0f, 30f).requiresCorrectToolForDrops().noOcclusion().dynamicShape())); 33 | 34 | public static final RegistryObject TOILET = BLOCKS.register("toilet", 35 | () -> new ToiletBlock(BlockBehaviour.Properties.copy(Blocks.QUARTZ_BLOCK).noOcclusion().dynamicShape())); 36 | 37 | public static final RegistryObject DRAWER = BLOCKS.register("drawer", 38 | () -> new DrawerBlock(BlockBehaviour.Properties.copy(Blocks.STONE_BRICKS))); 39 | 40 | public static final RegistryObject EXAMPLE_CHEST = BLOCKS.register("example_chest", 41 | () -> new ExampleChestBlock(BlockBehaviour.Properties.copy(BlockInit.EXAMPLE_BLOCK.get()))); 42 | 43 | public static final RegistryObject POOP_STORAGE = BLOCKS.register("poop_storage", 44 | () -> new PoopStorageBlock(BlockBehaviour.Properties.copy(Blocks.QUARTZ_BLOCK))); 45 | 46 | public static final RegistryObject DISPLAY_HAND = BLOCKS.register("display_hand", 47 | () -> new DisplayHandBlock(BlockBehaviour.Properties.copy(Blocks.GLASS))); 48 | 49 | public static final RegistryObject ENERGY_STORAGE = BLOCKS.register("energy_storage", 50 | () -> new EnergyStorageBlock(BlockBehaviour.Properties.copy(Blocks.STONE))); 51 | 52 | public static final RegistryObject ENERGY_GENERATOR = BLOCKS.register("energy_generator", 53 | () -> new EnergyGeneratorBlock(BlockBehaviour.Properties.copy(Blocks.STONE))); 54 | 55 | public static final RegistryObject CROPIUM = BLOCKS.register("cropium", 56 | () -> new BaseCropBlock(ItemInit.CROPIUM, BlockBehaviour.Properties.copy(Blocks.WHEAT))); 57 | 58 | private BlockInit() { 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/init/ContainerInit.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.init; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.container.EnergyGeneratorContainer; 5 | import io.github.darealturtywurty.tutorialmod.common.container.ExampleChestContainer; 6 | import io.github.darealturtywurty.tutorialmod.common.container.PoopStorageContainer; 7 | import net.minecraft.world.inventory.MenuType; 8 | import net.minecraftforge.registries.DeferredRegister; 9 | import net.minecraftforge.registries.ForgeRegistries; 10 | import net.minecraftforge.registries.RegistryObject; 11 | 12 | public final class ContainerInit { 13 | public static final DeferredRegister> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, 14 | TutorialMod.MODID); 15 | 16 | public static final RegistryObject> EXAMPLE_CHEST = CONTAINERS 17 | .register("example_chest", () -> new MenuType<>(ExampleChestContainer::new)); 18 | 19 | public static final RegistryObject> POOP_STORAGE = CONTAINERS 20 | .register("poop_storage", () -> new MenuType<>(PoopStorageContainer::new)); 21 | 22 | public static final RegistryObject> ENERGY_GENERATOR = CONTAINERS 23 | .register("energy_generator", () -> new MenuType<>(EnergyGeneratorContainer::new)); 24 | 25 | private ContainerInit() { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/init/EntityInit.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.init; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.entity.ExampleEntity; 5 | import io.github.darealturtywurty.tutorialmod.common.entity.SittableEntity; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.entity.EntityType; 8 | import net.minecraft.world.entity.MobCategory; 9 | import net.minecraftforge.registries.DeferredRegister; 10 | import net.minecraftforge.registries.ForgeRegistries; 11 | import net.minecraftforge.registries.RegistryObject; 12 | 13 | public final class EntityInit { 14 | 15 | public static final DeferredRegister> ENTITIES = DeferredRegister 16 | .create(ForgeRegistries.ENTITIES, TutorialMod.MODID); 17 | 18 | public static final RegistryObject> EXAMPLE_ENTITY = ENTITIES.register( 19 | "example_entity", 20 | () -> EntityType.Builder.of(ExampleEntity::new, MobCategory.CREATURE).sized(0.8f, 0.6f) 21 | .build(new ResourceLocation(TutorialMod.MODID, "example_entity").toString())); 22 | 23 | public static final RegistryObject> SEAT = ENTITIES.register("seat", 24 | () -> EntityType.Builder.of(SittableEntity::new, MobCategory.MISC).sized(1f, 1f) 25 | .build(new ResourceLocation(TutorialMod.MODID, "seat").toString())); 26 | 27 | private EntityInit() { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/init/ItemInit.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.init; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.common.item.ClickerItem; 5 | import io.github.darealturtywurty.tutorialmod.common.item.FuelItem; 6 | import net.minecraft.world.effect.MobEffectInstance; 7 | import net.minecraft.world.effect.MobEffects; 8 | import net.minecraft.world.entity.EquipmentSlot; 9 | import net.minecraft.world.food.FoodProperties; 10 | import net.minecraft.world.item.ArmorItem; 11 | import net.minecraft.world.item.AxeItem; 12 | import net.minecraft.world.item.BlockItem; 13 | import net.minecraft.world.item.HoeItem; 14 | import net.minecraft.world.item.Item; 15 | import net.minecraft.world.item.ItemNameBlockItem; 16 | import net.minecraft.world.item.PickaxeItem; 17 | import net.minecraft.world.item.ShovelItem; 18 | import net.minecraft.world.item.SwordItem; 19 | import net.minecraftforge.common.ForgeSpawnEggItem; 20 | import net.minecraftforge.registries.DeferredRegister; 21 | import net.minecraftforge.registries.ForgeRegistries; 22 | import net.minecraftforge.registries.RegistryObject; 23 | 24 | public final class ItemInit { 25 | public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, 26 | TutorialMod.MODID); 27 | 28 | public static final RegistryObject EXAMPLE_ITEM = ITEMS.register("example_item", 29 | () -> new FuelItem(new Item.Properties().tab(TutorialMod.TUTORIAL_TAB).fireResistant(), 30 | (stack, recipe) -> 300)); 31 | 32 | public static final RegistryObject CLICKER = ITEMS.register("clicker", 33 | () -> new ClickerItem(new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 34 | 35 | public static final RegistryObject EXAMPLE_ENTITY_SPAWN_EGG = ITEMS 36 | .register("example_entity_spawn_egg", () -> new ForgeSpawnEggItem(EntityInit.EXAMPLE_ENTITY, 0x1E51ED, 0x34BD27, 37 | new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 38 | 39 | public static final RegistryObject BEANS = ITEMS.register("beans", 40 | () -> new Item(new Item.Properties().tab(TutorialMod.TUTORIAL_TAB) 41 | .food(new FoodProperties.Builder().nutrition(5).saturationMod(4.5f) 42 | .effect(() -> new MobEffectInstance(MobEffects.JUMP, 360, 4), 0.7f) 43 | .effect(() -> new MobEffectInstance(MobEffects.DIG_SPEED, 500, 2), 0.2f).build()))); 44 | 45 | public static final RegistryObject POOP = ITEMS.register("poop", 46 | () -> new Item(new Item.Properties().tab(TutorialMod.TUTORIAL_TAB) 47 | .food(new FoodProperties.Builder().nutrition(50).saturationMod(5f) 48 | .effect(() -> new MobEffectInstance(MobEffects.REGENERATION, 200, 5), 1f) 49 | .effect(() -> new MobEffectInstance(MobEffects.ABSORPTION, 500, 64), 1f).build()))); 50 | 51 | // Tools 52 | public static final RegistryObject BEAN_SWORD = ITEMS.register("bean_sword", 53 | () -> new SwordItem(ToolMaterialInit.BEANS, 20, 5f, new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 54 | 55 | public static final RegistryObject BEAN_PICKAXE = ITEMS.register("bean_pickaxe", 56 | () -> new PickaxeItem(ToolMaterialInit.BEANS, 20, 5f, new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 57 | 58 | public static final RegistryObject BEAN_SHOVEL = ITEMS.register("bean_shovel", 59 | () -> new ShovelItem(ToolMaterialInit.BEANS, 20, 5f, new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 60 | 61 | public static final RegistryObject BEAN_AXE = ITEMS.register("bean_axe", 62 | () -> new AxeItem(ToolMaterialInit.BEANS, 20, 5f, new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 63 | 64 | public static final RegistryObject BEAN_HOE = ITEMS.register("bean_hoe", 65 | () -> new HoeItem(ToolMaterialInit.BEANS, 20, 5f, new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 66 | 67 | // Armor 68 | public static final RegistryObject BEAN_HELMET = ITEMS.register("bean_helmet", 69 | () -> new ArmorItem(ArmorMaterialInit.BEANS, EquipmentSlot.HEAD, 70 | new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 71 | 72 | public static final RegistryObject BEAN_CHESTPLATE = ITEMS.register("bean_chestplate", 73 | () -> new ArmorItem(ArmorMaterialInit.BEANS, EquipmentSlot.CHEST, 74 | new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 75 | 76 | public static final RegistryObject BEAN_LEGGINGS = ITEMS.register("bean_leggings", 77 | () -> new ArmorItem(ArmorMaterialInit.BEANS, EquipmentSlot.LEGS, 78 | new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 79 | 80 | public static final RegistryObject BEAN_BOOTS = ITEMS.register("bean_boots", 81 | () -> new ArmorItem(ArmorMaterialInit.BEANS, EquipmentSlot.FEET, 82 | new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 83 | 84 | // Block Items 85 | public static final RegistryObject EXAMPLE_BLOCK_ITEM = ITEMS.register("example_block", 86 | () -> new BlockItem(BlockInit.EXAMPLE_BLOCK.get(), new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 87 | 88 | public static final RegistryObject LIGHTNING_JUMPER_ITEM = ITEMS.register("lightning_jumper", 89 | () -> new BlockItem(BlockInit.LIGHTNING_JUMPER.get(), new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 90 | 91 | public static final RegistryObject TOILET_ITEM = ITEMS.register("toilet", 92 | () -> new BlockItem(BlockInit.TOILET.get(), new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 93 | 94 | public static final RegistryObject DRAWER_ITEM = ITEMS.register("drawer", 95 | () -> new BlockItem(BlockInit.DRAWER.get(), new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 96 | 97 | public static final RegistryObject EXAMPLE_CHEST_ITEM = ITEMS.register("example_chest", 98 | () -> new BlockItem(BlockInit.EXAMPLE_CHEST.get(), new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 99 | 100 | public static final RegistryObject POOP_STORAGE_ITEM = ITEMS.register("poop_storage", 101 | () -> new BlockItem(BlockInit.POOP_STORAGE.get(), new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 102 | 103 | public static final RegistryObject DISPLAY_HAND_ITEM = ITEMS.register("display_hand", 104 | () -> new BlockItem(BlockInit.DISPLAY_HAND.get(), new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 105 | 106 | public static final RegistryObject ENERGY_STORAGE_ITEM = ITEMS.register("energy_storage", 107 | () -> new BlockItem(BlockInit.ENERGY_STORAGE.get(), new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 108 | 109 | public static final RegistryObject ENERGY_GENERATOR_ITEM = ITEMS.register("energy_generator", 110 | () -> new BlockItem(BlockInit.ENERGY_GENERATOR.get(), new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 111 | 112 | public static final RegistryObject CROPIUM = ITEMS.register("cropium", 113 | () -> new Item(new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 114 | 115 | public static final RegistryObject CROPIUM_SEEDS = ITEMS.register("cropium_seeds", 116 | () -> new ItemNameBlockItem(BlockInit.CROPIUM.get(), new Item.Properties().tab(TutorialMod.TUTORIAL_TAB))); 117 | 118 | private ItemInit() { 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/init/PacketHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.init; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import io.github.darealturtywurty.tutorialmod.core.network.ClientboundUpdateEnergyStorageScreenPacket; 5 | import io.github.darealturtywurty.tutorialmod.core.network.ClientboundUpdateToiletPacket; 6 | import io.github.darealturtywurty.tutorialmod.core.network.ServerboundGetEnergyStoredPacket; 7 | import io.github.darealturtywurty.tutorialmod.core.network.ServerboundToiletUpdatePacket; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraftforge.network.NetworkDirection; 10 | import net.minecraftforge.network.NetworkRegistry; 11 | import net.minecraftforge.network.simple.SimpleChannel; 12 | 13 | public final class PacketHandler { 14 | private static final String PROTOCOL_VERSION = "1"; 15 | 16 | public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel( 17 | new ResourceLocation(TutorialMod.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, 18 | PROTOCOL_VERSION::equals); 19 | 20 | private PacketHandler() { 21 | } 22 | 23 | public static void init() { 24 | int index = 0; 25 | INSTANCE.messageBuilder(ServerboundToiletUpdatePacket.class, index++, NetworkDirection.PLAY_TO_SERVER) 26 | .encoder(ServerboundToiletUpdatePacket::encode).decoder(ServerboundToiletUpdatePacket::new) 27 | .consumer(ServerboundToiletUpdatePacket::handle).add(); 28 | INSTANCE.messageBuilder(ClientboundUpdateToiletPacket.class, index++, NetworkDirection.PLAY_TO_CLIENT) 29 | .encoder(ClientboundUpdateToiletPacket::encode).decoder(ClientboundUpdateToiletPacket::new) 30 | .consumer(ClientboundUpdateToiletPacket::handle).add(); 31 | INSTANCE 32 | .messageBuilder(ClientboundUpdateEnergyStorageScreenPacket.class, index++, NetworkDirection.PLAY_TO_CLIENT) 33 | .encoder(ClientboundUpdateEnergyStorageScreenPacket::encode) 34 | .decoder(ClientboundUpdateEnergyStorageScreenPacket::new) 35 | .consumer(ClientboundUpdateEnergyStorageScreenPacket::handle).add(); 36 | INSTANCE.messageBuilder(ServerboundGetEnergyStoredPacket.class, index++, NetworkDirection.PLAY_TO_SERVER) 37 | .encoder(ServerboundGetEnergyStoredPacket::encode).decoder(ServerboundGetEnergyStoredPacket::new) 38 | .consumer(ServerboundGetEnergyStoredPacket::handle).add(); 39 | TutorialMod.LOGGER.info("Registered {} packets for mod '{}'", index, TutorialMod.MODID); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/init/SoundInit.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.init; 2 | 3 | import io.github.darealturtywurty.tutorialmod.TutorialMod; 4 | import net.minecraft.resources.ResourceLocation; 5 | import net.minecraft.sounds.SoundEvent; 6 | import net.minecraftforge.registries.DeferredRegister; 7 | import net.minecraftforge.registries.ForgeRegistries; 8 | import net.minecraftforge.registries.RegistryObject; 9 | 10 | public final class SoundInit { 11 | 12 | public static final DeferredRegister SOUNDS = DeferredRegister 13 | .create(ForgeRegistries.SOUND_EVENTS, TutorialMod.MODID); 14 | 15 | public static final RegistryObject EXAMPLE_ENTITY_AMBIENT = SOUNDS.register( 16 | "entity.example_entity.ambient", 17 | () -> new SoundEvent(new ResourceLocation(TutorialMod.MODID, "entity.example_entity.ambient"))); 18 | 19 | public static final RegistryObject EXAMPLE_ENTITY_HURT = SOUNDS.register( 20 | "entity.example_entity.hurt", 21 | () -> new SoundEvent(new ResourceLocation(TutorialMod.MODID, "entity.example_entity.hurt"))); 22 | 23 | public static final RegistryObject EXAMPLE_ENTITY_DEATH = SOUNDS.register( 24 | "entity.example_entity.death", 25 | () -> new SoundEvent(new ResourceLocation(TutorialMod.MODID, "entity.example_entity.death"))); 26 | 27 | public static final RegistryObject FART = SOUNDS.register("block.toilet.fart", 28 | () -> new SoundEvent(new ResourceLocation(TutorialMod.MODID, "block.toilet.fart"))); 29 | 30 | private SoundInit() { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/init/ToolMaterialInit.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.init; 2 | 3 | import io.github.darealturtywurty.tutorialmod.core.util.BaseToolMaterial; 4 | import net.minecraft.world.item.Tier; 5 | import net.minecraft.world.item.crafting.Ingredient; 6 | 7 | public final class ToolMaterialInit { 8 | protected static final Tier BEANS = new BaseToolMaterial(15.5f, 500, 5, 25f, 2500, 9 | () -> Ingredient.of(ItemInit.BEANS.get())); 10 | 11 | private ToolMaterialInit() { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/network/ClientboundUpdateEnergyStorageScreenPacket.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.network; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import io.github.darealturtywurty.tutorialmod.client.ClientAccess; 6 | import net.minecraft.network.FriendlyByteBuf; 7 | import net.minecraftforge.api.distmarker.Dist; 8 | import net.minecraftforge.fml.DistExecutor; 9 | import net.minecraftforge.network.NetworkEvent; 10 | 11 | public class ClientboundUpdateEnergyStorageScreenPacket { 12 | public final int energy; 13 | 14 | public ClientboundUpdateEnergyStorageScreenPacket(FriendlyByteBuf buffer) { 15 | this(buffer.readInt()); 16 | } 17 | 18 | public ClientboundUpdateEnergyStorageScreenPacket(int energy) { 19 | this.energy = energy; 20 | } 21 | 22 | public void encode(FriendlyByteBuf buffer) { 23 | buffer.writeInt(this.energy); 24 | } 25 | 26 | // This is an example of where we can return true instead of setting the packet 27 | // to be handled. 28 | public boolean handle(Supplier ctx) { 29 | ctx.get().enqueueWork( 30 | () -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientAccess.updateEnergyStorage(this.energy))); 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/network/ClientboundUpdateToiletPacket.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.network; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import io.github.darealturtywurty.tutorialmod.client.ClientAccess; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.network.FriendlyByteBuf; 8 | import net.minecraftforge.api.distmarker.Dist; 9 | import net.minecraftforge.fml.DistExecutor; 10 | import net.minecraftforge.network.NetworkEvent; 11 | 12 | public class ClientboundUpdateToiletPacket { 13 | public final BlockPos toiletPos; 14 | 15 | public ClientboundUpdateToiletPacket(BlockPos pos) { 16 | this.toiletPos = pos; 17 | } 18 | 19 | public ClientboundUpdateToiletPacket(FriendlyByteBuf buffer) { 20 | this(buffer.readBlockPos()); 21 | } 22 | 23 | public void encode(FriendlyByteBuf buffer) { 24 | buffer.writeBlockPos(this.toiletPos); 25 | } 26 | 27 | public void handle(Supplier ctx) { 28 | ctx.get().enqueueWork( 29 | () -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientAccess.updateToilet(this.toiletPos))); 30 | 31 | ctx.get().setPacketHandled(true); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/network/ServerboundGetEnergyStoredPacket.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.network; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import io.github.darealturtywurty.tutorialmod.core.init.PacketHandler; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.network.FriendlyByteBuf; 8 | import net.minecraft.world.level.block.entity.BlockEntity; 9 | import net.minecraftforge.energy.CapabilityEnergy; 10 | import net.minecraftforge.network.NetworkEvent; 11 | import net.minecraftforge.network.PacketDistributor; 12 | 13 | public class ServerboundGetEnergyStoredPacket { 14 | public final BlockPos bePos; 15 | 16 | public ServerboundGetEnergyStoredPacket(BlockPos pos) { 17 | this.bePos = pos; 18 | } 19 | 20 | public ServerboundGetEnergyStoredPacket(FriendlyByteBuf buffer) { 21 | this(buffer.readBlockPos()); 22 | } 23 | 24 | public void encode(FriendlyByteBuf buffer) { 25 | buffer.writeBlockPos(this.bePos); 26 | } 27 | 28 | public void handle(Supplier ctx) { 29 | ctx.get().enqueueWork(() -> { 30 | final BlockEntity blockEntity = ctx.get().getSender().level.getBlockEntity(this.bePos); 31 | blockEntity.getCapability(CapabilityEnergy.ENERGY) 32 | .ifPresent(storage -> PacketHandler.INSTANCE.send(PacketDistributor.ALL.noArg(), 33 | new ClientboundUpdateEnergyStorageScreenPacket(storage.getEnergyStored()))); 34 | }); 35 | 36 | ctx.get().setPacketHandled(true); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/network/ServerboundToiletUpdatePacket.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.network; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import io.github.darealturtywurty.tutorialmod.common.block.entity.ToiletBlockEntity; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.network.FriendlyByteBuf; 8 | import net.minecraft.world.level.block.entity.BlockEntity; 9 | import net.minecraftforge.network.NetworkEvent; 10 | 11 | public class ServerboundToiletUpdatePacket { 12 | public final BlockPos toiletPos; 13 | 14 | public ServerboundToiletUpdatePacket(BlockPos pos) { 15 | this.toiletPos = pos; 16 | } 17 | 18 | public ServerboundToiletUpdatePacket(FriendlyByteBuf buffer) { 19 | this(buffer.readBlockPos()); 20 | } 21 | 22 | public void encode(FriendlyByteBuf buffer) { 23 | buffer.writeBlockPos(this.toiletPos); 24 | } 25 | 26 | public void handle(Supplier ctx) { 27 | ctx.get().enqueueWork(() -> { 28 | final BlockEntity blockEntity = ctx.get().getSender().level.getBlockEntity(this.toiletPos); 29 | if (blockEntity instanceof final ToiletBlockEntity toilet) { 30 | toilet.isShitting = true; 31 | toilet.fartTicker = 0; 32 | } 33 | }); 34 | 35 | ctx.get().setPacketHandled(true); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/util/BaseArmorMaterial.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.util; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import net.minecraft.sounds.SoundEvent; 6 | import net.minecraft.world.entity.EquipmentSlot; 7 | import net.minecraft.world.item.ArmorMaterial; 8 | import net.minecraft.world.item.crafting.Ingredient; 9 | 10 | public class BaseArmorMaterial implements ArmorMaterial { 11 | private final int enchantability; 12 | private final int[] durability, damageReduction; 13 | private final float knockbackResistance, toughness; 14 | private final String name; 15 | private final SoundEvent equipSound; 16 | private final Supplier repairMaterial; 17 | 18 | public BaseArmorMaterial(int enchantability, int[] durability, int[] damageReduction, 19 | float knockbackResistance, float toughness, String name, SoundEvent equipSound, 20 | Supplier repairMaterial) { 21 | this.enchantability = enchantability; 22 | this.durability = durability; 23 | this.damageReduction = damageReduction; 24 | this.knockbackResistance = knockbackResistance; 25 | this.toughness = toughness; 26 | this.name = name; 27 | this.equipSound = equipSound; 28 | this.repairMaterial = repairMaterial; 29 | } 30 | 31 | @Override 32 | public int getDefenseForSlot(EquipmentSlot slot) { 33 | return this.damageReduction[slot.getIndex()]; 34 | } 35 | 36 | @Override 37 | public int getDurabilityForSlot(EquipmentSlot slot) { 38 | return this.durability[slot.getIndex()]; 39 | } 40 | 41 | @Override 42 | public int getEnchantmentValue() { 43 | return this.enchantability; 44 | } 45 | 46 | @Override 47 | public SoundEvent getEquipSound() { 48 | return this.equipSound; 49 | } 50 | 51 | @Override 52 | public float getKnockbackResistance() { 53 | return this.knockbackResistance; 54 | } 55 | 56 | @Override 57 | public String getName() { 58 | return this.name; 59 | } 60 | 61 | @Override 62 | public Ingredient getRepairIngredient() { 63 | return this.repairMaterial.get(); 64 | } 65 | 66 | @Override 67 | public float getToughness() { 68 | return this.toughness; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/util/BaseToolMaterial.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.util; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import net.minecraft.world.item.Tier; 6 | import net.minecraft.world.item.crafting.Ingredient; 7 | 8 | public class BaseToolMaterial implements Tier { 9 | 10 | private final float attackDamageBonus, speed; 11 | private final int enchantability, harvestLevel, durability; 12 | private final Supplier repairMaterial; 13 | 14 | public BaseToolMaterial(float attackDamageBonus, int enchantability, int harvestLevel, float speed, 15 | int durability, Supplier repairMaterial) { 16 | this.attackDamageBonus = attackDamageBonus; 17 | this.enchantability = enchantability; 18 | this.harvestLevel = harvestLevel; 19 | this.speed = speed; 20 | this.durability = durability; 21 | this.repairMaterial = repairMaterial; 22 | } 23 | 24 | @Override 25 | public float getAttackDamageBonus() { 26 | return this.attackDamageBonus; 27 | } 28 | 29 | @Override 30 | public int getEnchantmentValue() { 31 | return this.enchantability; 32 | } 33 | 34 | @Override 35 | public int getLevel() { 36 | return this.harvestLevel; 37 | } 38 | 39 | @Override 40 | public Ingredient getRepairIngredient() { 41 | return this.repairMaterial.get(); 42 | } 43 | 44 | @Override 45 | public float getSpeed() { 46 | return this.speed; 47 | } 48 | 49 | @Override 50 | public int getUses() { 51 | return this.durability; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/io/github/darealturtywurty/tutorialmod/core/world/OreGeneration.java: -------------------------------------------------------------------------------- 1 | package io.github.darealturtywurty.tutorialmod.core.world; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import net.minecraft.data.worldgen.features.FeatureUtils; 7 | import net.minecraft.data.worldgen.features.OreFeatures; 8 | import net.minecraft.data.worldgen.placement.OrePlacements; 9 | import net.minecraft.data.worldgen.placement.PlacementUtils; 10 | import net.minecraft.world.level.block.Blocks; 11 | import net.minecraft.world.level.levelgen.VerticalAnchor; 12 | import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; 13 | import net.minecraft.world.level.levelgen.feature.Feature; 14 | import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration; 15 | import net.minecraft.world.level.levelgen.placement.HeightRangePlacement; 16 | import net.minecraft.world.level.levelgen.placement.PlacedFeature; 17 | import net.minecraft.world.level.levelgen.structure.templatesystem.BlockMatchTest; 18 | import net.minecraft.world.level.levelgen.structure.templatesystem.RuleTest; 19 | 20 | public class OreGeneration { 21 | public static final List OVERWORLD_ORES = new ArrayList<>(); 22 | public static final List END_ORES = new ArrayList<>(); 23 | public static final List NETHER_ORES = new ArrayList<>(); 24 | 25 | public static final RuleTest END_TEST = new BlockMatchTest(Blocks.END_STONE); 26 | 27 | public static void registerOres() { 28 | final ConfiguredFeature glowstoneOre = FeatureUtils.register("glowstone_ore", 29 | Feature.ORE.configured(new OreConfiguration(List.of( 30 | OreConfiguration.target(OreFeatures.STONE_ORE_REPLACEABLES, 31 | Blocks.GLOWSTONE.defaultBlockState()), 32 | OreConfiguration.target(OreFeatures.DEEPSLATE_ORE_REPLACEABLES, 33 | Blocks.ACACIA_WOOD.defaultBlockState())), 34 | 11))); 35 | 36 | final PlacedFeature placedGlowstoneOre = PlacementUtils.register("glowstone_ore", 37 | glowstoneOre.placed(OrePlacements.commonOrePlacement(100, HeightRangePlacement 38 | .uniform(VerticalAnchor.bottom(), VerticalAnchor.aboveBottom(20))))); 39 | OVERWORLD_ORES.add(placedGlowstoneOre); 40 | 41 | final ConfiguredFeature beansOre = FeatureUtils.register("beans_ore", 42 | Feature.ORE.configured(new OreConfiguration(List.of(OreConfiguration 43 | .target(OreFeatures.NETHER_ORE_REPLACEABLES, Blocks.BLUE_WOOL.defaultBlockState())), 44 | 3))); 45 | 46 | final PlacedFeature placedBeansOre = PlacementUtils.register("beans_ore", 47 | beansOre.placed(OrePlacements.commonOrePlacement(100, HeightRangePlacement 48 | .triangle(VerticalAnchor.absolute(50), VerticalAnchor.absolute(120))))); 49 | NETHER_ORES.add(placedBeansOre); 50 | 51 | final ConfiguredFeature eggOre = FeatureUtils.register("egg_ore", 52 | Feature.ORE.configured(new OreConfiguration( 53 | List.of(OreConfiguration.target(END_TEST, Blocks.GOLD_BLOCK.defaultBlockState())), 54 | 15))); 55 | 56 | final PlacedFeature placedEggOre = PlacementUtils.register("egg_ore", 57 | eggOre.placed(OrePlacements.commonOrePlacement(100, HeightRangePlacement 58 | .uniform(VerticalAnchor.absolute(20), VerticalAnchor.absolute(60))))); 59 | END_ORES.add(placedEggOre); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/accesstransformer.cfg: -------------------------------------------------------------------------------- 1 | public net.minecraft.data.worldgen.placement.OrePlacements m_195343_(ILnet/minecraft/world/level/levelgen/placement/PlacementModifier;)Ljava/util/List; # commonOrePlacement 2 | public net.minecraft.data.worldgen.placement.OrePlacements m_195349_(ILnet/minecraft/world/level/levelgen/placement/PlacementModifier;)Ljava/util/List; # rareOrePlacement 3 | public net.minecraft.data.worldgen.placement.OrePlacements m_195346_(Lnet/minecraft/world/level/levelgen/placement/PlacementModifier;Lnet/minecraft/world/level/levelgen/placement/PlacementModifier;)Ljava/util/List; # orePlacement -------------------------------------------------------------------------------- /src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | modLoader="javafml" 2 | loaderVersion="[38,)" 3 | license="MIT" 4 | 5 | [[mods]] 6 | modId="tutorialmod" 7 | version="1.0" 8 | displayName="Tutorial Mod" 9 | logoFile="logo.png" 10 | credits="" 11 | authors="TurtyWurty" 12 | description=''' 13 | A tutorial mod for Minecraft 1.18! 14 | 15 | beans 16 | ''' -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/blockstates/cropium.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "age=0": { 4 | "model": "tutorialmod:block/cropium_stage0" 5 | }, 6 | "age=1": { 7 | "model": "tutorialmod:block/cropium_stage1" 8 | }, 9 | "age=2": { 10 | "model": "tutorialmod:block/cropium_stage2" 11 | }, 12 | "age=3": { 13 | "model": "tutorialmod:block/cropium_stage3" 14 | }, 15 | "age=4": { 16 | "model": "tutorialmod:block/cropium_stage4" 17 | }, 18 | "age=5": { 19 | "model": "tutorialmod:block/cropium_stage5" 20 | }, 21 | "age=6": { 22 | "model": "tutorialmod:block/cropium_stage6" 23 | }, 24 | "age=7": { 25 | "model": "tutorialmod:block/cropium_stage7" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/blockstates/display_hand.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "": { "model": "tutorialmod:block/display_hand" } 4 | } 5 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/blockstates/drawer.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "facing=north": { "model": "tutorialmod:block/drawer" }, 4 | "facing=south": { "model": "tutorialmod:block/drawer", "y": 180 }, 5 | "facing=west": { "model": "tutorialmod:block/drawer", "y": 270 }, 6 | "facing=east": { "model": "tutorialmod:block/drawer", "y": 90 } 7 | } 8 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/blockstates/example_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "": { "model": "tutorialmod:block/example_block" } 4 | } 5 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/blockstates/example_chest.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "facing=north": { "model": "tutorialmod:block/example_chest" }, 4 | "facing=south": { "model": "tutorialmod:block/example_chest", "y": 180 }, 5 | "facing=west": { "model": "tutorialmod:block/example_chest", "y": 270 }, 6 | "facing=east": { "model": "tutorialmod:block/example_chest", "y": 90 } 7 | } 8 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/blockstates/lightning_jumper.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "facing=north": { "model": "tutorialmod:block/lightning_jumper" }, 4 | "facing=south": { "model": "tutorialmod:block/lightning_jumper", "y": 180 }, 5 | "facing=west": { "model": "tutorialmod:block/lightning_jumper", "y": 270 }, 6 | "facing=east": { "model": "tutorialmod:block/lightning_jumper", "y": 90 } 7 | } 8 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/blockstates/poop_storage.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "": { "model": "tutorialmod:block/poop_storage" } 4 | } 5 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/blockstates/toilet.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "facing=north": { "model": "tutorialmod:block/toilet" }, 4 | "facing=south": { "model": "tutorialmod:block/toilet", "y": 180 }, 5 | "facing=west": { "model": "tutorialmod:block/toilet", "y": 270 }, 6 | "facing=east": { "model": "tutorialmod:block/toilet", "y": 90 } 7 | } 8 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "item.tutorialmod.example_item": "Example Item", 3 | "block.tutorialmod.example_block": "Example Block", 4 | "entity.tutorialmod.example_entity": "Example Entity", 5 | "item.tutorialmod.example_entity_spawn_egg": "Spawn Example Entity", 6 | "itemGroup.tutorialmod": "Tutorial Mod", 7 | "item.tutorialmod.clicker": "Clicker", 8 | "block.tutorialmod.lightning_jumper": "Lightning Jumper", 9 | "block.tutorialmod.toilet": "Toilet", 10 | "item.tutorialmod.beans": "Beans", 11 | "item.tutorialmod.bean_sword": "Bean-Infused Sword", 12 | "item.tutorialmod.bean_pickaxe": "Bean-Infused Pickaxe", 13 | "item.tutorialmod.bean_shovel": "Bean-Infused Shovel", 14 | "item.tutorialmod.bean_axe": "Bean-Infused Axe", 15 | "item.tutorialmod.bean_hoe": "Bean-Infused Hoe", 16 | "item.tutorialmod.bean_helmet": "Bean-Infused Helmet", 17 | "item.tutorialmod.bean_chestplate": "Bean-Infused Chestplate", 18 | "item.tutorialmod.bean_leggings": "Bean-Infused Leggings", 19 | "item.tutorialmod.bean_boots": "Bean-Infused Boots", 20 | "key.tutorialmod.example_key": "Example Key", 21 | "block.tutorialmod.drawer": "Drawer", 22 | "container.tutorialmod.example_chest": "Example Chest", 23 | "block.tutorialmod.example_chest": "Example Chest", 24 | "container.tutorialmod.poop_storage": "Poop Storage", 25 | "block.tutorialmod.poop_storage": "Poop Storage", 26 | "item.tutorialmod.poop": "Poop", 27 | "block.tutorialmod.display_hand": "Hand Displayer", 28 | "block.tutorialmod.energy_storage": "Energy Storage", 29 | "block.tutorialmod.energy_generator": "Energy Generator", 30 | "container.tutorialmod.energy_storage": "Energy Storage", 31 | "container.tutorialmod.energy_generator": "Energy Generator", 32 | "item.tutorialmod.cropium": "Cropium", 33 | "item.tutorialmod.cropium_seeds": "Cropium Seeds" 34 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/cropium_stage0.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:block/crop", 3 | "textures": { 4 | "crop": "tutorialmod:blocks/cropium_stage0" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/cropium_stage1.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:block/crop", 3 | "textures": { 4 | "crop": "tutorialmod:blocks/cropium_stage1" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/cropium_stage2.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:block/crop", 3 | "textures": { 4 | "crop": "tutorialmod:blocks/cropium_stage2" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/cropium_stage3.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:block/crop", 3 | "textures": { 4 | "crop": "tutorialmod:blocks/cropium_stage3" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/cropium_stage4.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:block/crop", 3 | "textures": { 4 | "crop": "tutorialmod:blocks/cropium_stage4" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/cropium_stage5.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:block/crop", 3 | "textures": { 4 | "crop": "tutorialmod:blocks/cropium_stage5" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/cropium_stage6.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:block/crop", 3 | "textures": { 4 | "crop": "tutorialmod:blocks/cropium_stage6" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/cropium_stage7.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:block/crop", 3 | "textures": { 4 | "crop": "tutorialmod:blocks/cropium_stage7" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/drawer.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/orientable", 3 | "textures": { 4 | "front": "tutorialmod:blocks/drawer_front", 5 | "side": "tutorialmod:blocks/drawer_side", 6 | "top": "tutorialmod:blocks/drawer_side" 7 | } 8 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/example_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/cube_all", 3 | "textures": { 4 | "all": "tutorialmod:blocks/example_block" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/example_chest.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/orientable", 3 | "textures": { 4 | "front": "tutorialmod:blocks/example_chest_front", 5 | "side": "tutorialmod:blocks/example_chest_side", 6 | "top": "tutorialmod:blocks/example_chest_top" 7 | } 8 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/poop_storage.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/orientable", 3 | "textures": { 4 | "front": "tutorialmod:blocks/poop_storage_side", 5 | "side": "tutorialmod:blocks/poop_storage_side", 6 | "top": "tutorialmod:blocks/poop_storage_top" 7 | } 8 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/block/toilet.json: -------------------------------------------------------------------------------- 1 | { 2 | "textures": { 3 | "0": "block/snow", 4 | "1": "block/quartz_block_bottom", 5 | "2": "block/quartz_block_side", 6 | "3": "block/quartz_block_top", 7 | "4": "block/anvil", 8 | "5": "block/black_concrete", 9 | "6": "block/smooth_basalt", 10 | "particle": "block/snow" 11 | }, 12 | "elements": [ 13 | { 14 | "from": [5, 0, 5], 15 | "to": [11, 1, 11], 16 | "faces": { 17 | "north": {"uv": [5, 15, 11, 16], "texture": "#4"}, 18 | "east": {"uv": [5, 15, 11, 16], "texture": "#4"}, 19 | "south": {"uv": [5, 15, 11, 16], "texture": "#4"}, 20 | "west": {"uv": [5, 15, 11, 16], "texture": "#4"}, 21 | "up": {"uv": [5, 5, 11, 11], "texture": "#4"}, 22 | "down": {"uv": [5, 5, 11, 11], "texture": "#4"} 23 | } 24 | }, 25 | { 26 | "from": [6, 1, 6], 27 | "to": [10, 5, 10], 28 | "faces": { 29 | "north": {"uv": [6, 11, 10, 15], "texture": "#2"}, 30 | "east": {"uv": [6, 11, 10, 15], "texture": "#2"}, 31 | "south": {"uv": [6, 11, 10, 15], "texture": "#2"}, 32 | "west": {"uv": [6, 11, 10, 15], "texture": "#2"}, 33 | "up": {"uv": [6, 6, 10, 10], "texture": "#5"}, 34 | "down": {"uv": [0, 0, 4, 4], "texture": "#missing"} 35 | } 36 | }, 37 | { 38 | "from": [10, 5, 6], 39 | "to": [11, 6, 10], 40 | "faces": { 41 | "north": {"uv": [5, 10, 6, 11], "texture": "#2"}, 42 | "east": {"uv": [6, 10, 10, 11], "texture": "#2"}, 43 | "south": {"uv": [10, 10, 11, 11], "texture": "#2"}, 44 | "west": {"uv": [6, 10, 10, 11], "texture": "#2"}, 45 | "up": {"uv": [10, 6, 11, 10], "texture": "#3"}, 46 | "down": {"uv": [10, 6, 11, 10], "texture": "#1"} 47 | } 48 | }, 49 | { 50 | "from": [5, 5, 6], 51 | "to": [6, 6, 10], 52 | "faces": { 53 | "north": {"uv": [10, 10, 11, 11], "texture": "#2"}, 54 | "east": {"uv": [6, 10, 10, 11], "texture": "#2"}, 55 | "south": {"uv": [5, 10, 6, 11], "texture": "#2"}, 56 | "west": {"uv": [6, 10, 10, 11], "texture": "#2"}, 57 | "up": {"uv": [5, 6, 6, 10], "texture": "#3"}, 58 | "down": {"uv": [5, 6, 6, 10], "texture": "#1"} 59 | } 60 | }, 61 | { 62 | "from": [4, 6, 5], 63 | "to": [5, 7, 11], 64 | "faces": { 65 | "north": {"uv": [11, 9, 12, 10], "texture": "#2"}, 66 | "east": {"uv": [5, 9, 11, 10], "texture": "#2"}, 67 | "south": {"uv": [4, 9, 5, 10], "texture": "#2"}, 68 | "west": {"uv": [5, 9, 11, 10], "texture": "#2"}, 69 | "up": {"uv": [4, 5, 5, 11], "texture": "#3"}, 70 | "down": {"uv": [4, 5, 5, 11], "texture": "#1"} 71 | } 72 | }, 73 | { 74 | "from": [11, 6, 5], 75 | "to": [12, 7, 11], 76 | "faces": { 77 | "north": {"uv": [4, 9, 5, 10], "texture": "#2"}, 78 | "east": {"uv": [5, 9, 11, 10], "texture": "#2"}, 79 | "south": {"uv": [11, 9, 12, 10], "texture": "#2"}, 80 | "west": {"uv": [5, 9, 11, 10], "texture": "#2"}, 81 | "up": {"uv": [11, 5, 12, 11], "texture": "#3"}, 82 | "down": {"uv": [11, 5, 12, 11], "texture": "#1"} 83 | } 84 | }, 85 | { 86 | "from": [10, 6, 10], 87 | "to": [11, 7, 11], 88 | "faces": { 89 | "north": {"uv": [5, 9, 6, 10], "texture": "#2"}, 90 | "east": {"uv": [5, 9, 6, 10], "texture": "#2"}, 91 | "south": {"uv": [10, 9, 11, 10], "texture": "#2"}, 92 | "west": {"uv": [10, 9, 11, 10], "texture": "#2"}, 93 | "up": {"uv": [10, 10, 11, 11], "texture": "#3"}, 94 | "down": {"uv": [10, 5, 11, 6], "texture": "#1"} 95 | } 96 | }, 97 | { 98 | "from": [11, 7, 11], 99 | "to": [12, 8, 12], 100 | "faces": { 101 | "north": {"uv": [4, 8, 5, 9], "texture": "#2"}, 102 | "east": {"uv": [4, 8, 5, 9], "texture": "#2"}, 103 | "south": {"uv": [11, 8, 12, 9], "texture": "#2"}, 104 | "west": {"uv": [11, 8, 12, 9], "texture": "#2"}, 105 | "up": {"uv": [11, 11, 12, 12], "texture": "#3"}, 106 | "down": {"uv": [11, 4, 12, 5], "texture": "#1"} 107 | } 108 | }, 109 | { 110 | "from": [4, 7, 11], 111 | "to": [5, 8, 12], 112 | "faces": { 113 | "north": {"uv": [11, 8, 12, 9], "texture": "#2"}, 114 | "east": {"uv": [4, 8, 5, 9], "texture": "#2"}, 115 | "south": {"uv": [4, 8, 5, 9], "texture": "#2"}, 116 | "west": {"uv": [11, 8, 12, 9], "texture": "#2"}, 117 | "up": {"uv": [4, 11, 5, 12], "texture": "#3"}, 118 | "down": {"uv": [4, 4, 5, 5], "texture": "#1"} 119 | } 120 | }, 121 | { 122 | "from": [4, 7, 2], 123 | "to": [5, 8, 5], 124 | "faces": { 125 | "north": {"uv": [11, 8, 12, 9], "texture": "#2"}, 126 | "east": {"uv": [11, 8, 14, 9], "texture": "#2"}, 127 | "south": {"uv": [4, 8, 5, 9], "texture": "#2"}, 128 | "west": {"uv": [2, 8, 5, 9], "texture": "#2"}, 129 | "up": {"uv": [4, 2, 5, 5], "texture": "#3"}, 130 | "down": {"uv": [4, 11, 5, 14], "texture": "#1"} 131 | } 132 | }, 133 | { 134 | "from": [11, 7, 2], 135 | "to": [12, 8, 5], 136 | "faces": { 137 | "north": {"uv": [4, 8, 5, 9], "texture": "#2"}, 138 | "east": {"uv": [11, 8, 14, 9], "texture": "#2"}, 139 | "south": {"uv": [11, 8, 12, 9], "texture": "#2"}, 140 | "west": {"uv": [2, 8, 5, 9], "texture": "#2"}, 141 | "up": {"uv": [11, 2, 12, 5], "texture": "#3"}, 142 | "down": {"uv": [11, 11, 12, 14], "texture": "#1"} 143 | } 144 | }, 145 | { 146 | "from": [5, 6, 10], 147 | "to": [6, 7, 11], 148 | "faces": { 149 | "north": {"uv": [10, 9, 11, 10], "texture": "#2"}, 150 | "east": {"uv": [5, 9, 6, 10], "texture": "#2"}, 151 | "south": {"uv": [5, 9, 6, 10], "texture": "#2"}, 152 | "west": {"uv": [10, 9, 11, 10], "texture": "#2"}, 153 | "up": {"uv": [5, 10, 6, 11], "texture": "#3"}, 154 | "down": {"uv": [5, 5, 6, 6], "texture": "#1"} 155 | } 156 | }, 157 | { 158 | "from": [5, 6, 5], 159 | "to": [6, 7, 6], 160 | "faces": { 161 | "north": {"uv": [10, 9, 11, 10], "texture": "#2"}, 162 | "east": {"uv": [10, 9, 11, 10], "texture": "#2"}, 163 | "south": {"uv": [5, 9, 6, 10], "texture": "#2"}, 164 | "west": {"uv": [5, 9, 6, 10], "texture": "#2"}, 165 | "up": {"uv": [5, 5, 6, 6], "texture": "#3"}, 166 | "down": {"uv": [5, 10, 6, 11], "texture": "#1"} 167 | } 168 | }, 169 | { 170 | "from": [10, 6, 5], 171 | "to": [11, 7, 6], 172 | "faces": { 173 | "north": {"uv": [5, 9, 6, 10], "texture": "#2"}, 174 | "east": {"uv": [10, 9, 11, 10], "texture": "#2"}, 175 | "south": {"uv": [10, 9, 11, 10], "texture": "#2"}, 176 | "west": {"uv": [5, 9, 6, 10], "texture": "#2"}, 177 | "up": {"uv": [10, 5, 11, 6], "texture": "#3"}, 178 | "down": {"uv": [10, 10, 11, 11], "texture": "#1"} 179 | } 180 | }, 181 | { 182 | "from": [6, 5, 10], 183 | "to": [10, 6, 11], 184 | "faces": { 185 | "north": {"uv": [6, 10, 10, 11], "texture": "#2"}, 186 | "east": {"uv": [5, 10, 6, 11], "texture": "#2"}, 187 | "south": {"uv": [6, 10, 10, 11], "texture": "#2"}, 188 | "west": {"uv": [10, 10, 11, 11], "texture": "#2"}, 189 | "up": {"uv": [6, 10, 10, 11], "texture": "#3"}, 190 | "down": {"uv": [6, 5, 10, 6], "texture": "#1"} 191 | } 192 | }, 193 | { 194 | "from": [6, 5, 5], 195 | "to": [10, 6, 6], 196 | "faces": { 197 | "north": {"uv": [6, 10, 10, 11], "texture": "#2"}, 198 | "east": {"uv": [10, 10, 11, 11], "texture": "#2"}, 199 | "south": {"uv": [6, 10, 10, 11], "texture": "#2"}, 200 | "west": {"uv": [5, 10, 6, 11], "texture": "#2"}, 201 | "up": {"uv": [6, 5, 10, 6], "texture": "#3"}, 202 | "down": {"uv": [6, 10, 10, 11], "texture": "#1"} 203 | } 204 | }, 205 | { 206 | "from": [5, 6, 4], 207 | "to": [11, 7, 5], 208 | "faces": { 209 | "north": {"uv": [5, 9, 11, 10], "texture": "#2"}, 210 | "east": {"uv": [11, 9, 12, 10], "texture": "#2"}, 211 | "south": {"uv": [5, 9, 11, 10], "texture": "#2"}, 212 | "west": {"uv": [4, 9, 5, 10], "texture": "#2"}, 213 | "up": {"uv": [5, 4, 11, 5], "texture": "#3"}, 214 | "down": {"uv": [5, 11, 11, 12], "texture": "#1"} 215 | } 216 | }, 217 | { 218 | "from": [5, 7, 2], 219 | "to": [11, 8, 4], 220 | "faces": { 221 | "north": {"uv": [5, 8, 11, 9], "texture": "#2"}, 222 | "east": {"uv": [12, 8, 14, 9], "texture": "#2"}, 223 | "south": {"uv": [5, 8, 11, 9], "texture": "#2"}, 224 | "west": {"uv": [2, 8, 4, 9], "texture": "#2"}, 225 | "up": {"uv": [5, 2, 11, 4], "texture": "#3"}, 226 | "down": {"uv": [5, 12, 11, 14], "texture": "#1"} 227 | } 228 | }, 229 | { 230 | "from": [4, 8, 2], 231 | "to": [12, 9, 3], 232 | "faces": { 233 | "north": {"uv": [4, 7, 12, 8], "texture": "#2"}, 234 | "east": {"uv": [13, 7, 14, 8], "texture": "#2"}, 235 | "south": {"uv": [4, 7, 12, 8], "texture": "#2"}, 236 | "west": {"uv": [2, 7, 3, 8], "texture": "#2"}, 237 | "up": {"uv": [4, 2, 12, 3], "texture": "#3"}, 238 | "down": {"uv": [4, 13, 12, 14], "texture": "#1"} 239 | } 240 | }, 241 | { 242 | "from": [12, 7, 2], 243 | "to": [13, 11, 12], 244 | "faces": { 245 | "north": {"uv": [3, 5, 4, 9], "texture": "#2"}, 246 | "east": {"uv": [4, 5, 14, 9], "texture": "#2"}, 247 | "south": {"uv": [12, 5, 13, 9], "texture": "#2"}, 248 | "west": {"uv": [2, 5, 12, 9], "texture": "#2"}, 249 | "up": {"uv": [12, 2, 13, 12], "texture": "#3"}, 250 | "down": {"uv": [12, 4, 13, 14], "texture": "#1"} 251 | } 252 | }, 253 | { 254 | "from": [4, 7, 1], 255 | "to": [12, 11, 2], 256 | "faces": { 257 | "north": {"uv": [4, 5, 12, 9], "texture": "#2"}, 258 | "east": {"uv": [14, 5, 15, 9], "texture": "#2"}, 259 | "south": {"uv": [4, 5, 12, 9], "texture": "#2"}, 260 | "west": {"uv": [1, 5, 2, 9], "texture": "#2"}, 261 | "up": {"uv": [4, 1, 12, 2], "texture": "#3"}, 262 | "down": {"uv": [4, 14, 12, 15], "texture": "#1"} 263 | } 264 | }, 265 | { 266 | "from": [3, 7, 2], 267 | "to": [4, 11, 12], 268 | "faces": { 269 | "north": {"uv": [12, 5, 13, 9], "texture": "#2"}, 270 | "east": {"uv": [4, 5, 14, 9], "texture": "#2"}, 271 | "south": {"uv": [3, 5, 4, 9], "texture": "#2"}, 272 | "west": {"uv": [2, 5, 12, 9], "texture": "#2"}, 273 | "up": {"uv": [3, 2, 4, 12], "texture": "#3"}, 274 | "down": {"uv": [3, 4, 4, 14], "texture": "#1"} 275 | } 276 | }, 277 | { 278 | "from": [5, 6, 11], 279 | "to": [11, 7, 12], 280 | "faces": { 281 | "north": {"uv": [5, 9, 11, 10], "texture": "#2"}, 282 | "east": {"uv": [4, 9, 5, 10], "texture": "#2"}, 283 | "south": {"uv": [5, 9, 11, 10], "texture": "#2"}, 284 | "west": {"uv": [11, 9, 12, 10], "texture": "#2"}, 285 | "up": {"uv": [5, 11, 11, 12], "texture": "#3"}, 286 | "down": {"uv": [5, 4, 11, 5], "texture": "#1"} 287 | } 288 | }, 289 | { 290 | "from": [4, 7, 12], 291 | "to": [12, 11, 13], 292 | "faces": { 293 | "north": {"uv": [4, 5, 12, 9], "texture": "#2"}, 294 | "east": {"uv": [3, 5, 4, 9], "texture": "#2"}, 295 | "south": {"uv": [4, 5, 12, 9], "texture": "#2"}, 296 | "west": {"uv": [12, 5, 13, 9], "texture": "#2"}, 297 | "up": {"uv": [4, 12, 12, 13], "texture": "#3"}, 298 | "down": {"uv": [4, 3, 12, 4], "texture": "#1"} 299 | } 300 | }, 301 | { 302 | "from": [5, 10, 2], 303 | "to": [11, 11, 3], 304 | "faces": { 305 | "north": {"uv": [5, 5, 11, 6], "texture": "#2"}, 306 | "east": {"uv": [13, 5, 14, 6], "texture": "#2"}, 307 | "south": {"uv": [5, 5, 11, 6], "texture": "#2"}, 308 | "west": {"uv": [2, 5, 3, 6], "texture": "#2"}, 309 | "up": {"uv": [5, 2, 11, 3], "texture": "#3"}, 310 | "down": {"uv": [5, 13, 11, 14], "texture": "#1"} 311 | } 312 | }, 313 | { 314 | "from": [11, 10, 2], 315 | "to": [12, 11, 12], 316 | "faces": { 317 | "north": {"uv": [4, 5, 5, 6], "texture": "#2"}, 318 | "east": {"uv": [4, 5, 14, 6], "texture": "#2"}, 319 | "south": {"uv": [11, 5, 12, 6], "texture": "#2"}, 320 | "west": {"uv": [2, 5, 12, 6], "texture": "#2"}, 321 | "up": {"uv": [11, 2, 12, 12], "texture": "#3"}, 322 | "down": {"uv": [11, 4, 12, 14], "texture": "#1"} 323 | } 324 | }, 325 | { 326 | "from": [4, 10, 2], 327 | "to": [5, 11, 12], 328 | "faces": { 329 | "north": {"uv": [11, 5, 12, 6], "texture": "#2"}, 330 | "east": {"uv": [4, 5, 14, 6], "texture": "#2"}, 331 | "south": {"uv": [4, 5, 5, 6], "texture": "#2"}, 332 | "west": {"uv": [2, 5, 12, 6], "texture": "#2"}, 333 | "up": {"uv": [4, 2, 5, 12], "texture": "#3"}, 334 | "down": {"uv": [4, 4, 5, 14], "texture": "#1"} 335 | } 336 | }, 337 | { 338 | "from": [4, 11, 2], 339 | "to": [5, 12, 12], 340 | "faces": { 341 | "north": {"uv": [11, 4, 12, 5], "texture": "#0"}, 342 | "east": {"uv": [4, 4, 14, 5], "texture": "#0"}, 343 | "south": {"uv": [4, 4, 5, 5], "texture": "#0"}, 344 | "west": {"uv": [2, 4, 12, 5], "texture": "#0"}, 345 | "up": {"uv": [4, 2, 5, 12], "texture": "#0"}, 346 | "down": {"uv": [4, 4, 5, 14], "texture": "#0"} 347 | } 348 | }, 349 | { 350 | "from": [3, 11, 2], 351 | "to": [4, 12, 12], 352 | "faces": { 353 | "north": {"uv": [12, 4, 13, 5], "texture": "#0"}, 354 | "east": {"uv": [4, 4, 14, 5], "texture": "#0"}, 355 | "south": {"uv": [3, 4, 4, 5], "texture": "#0"}, 356 | "west": {"uv": [2, 4, 12, 5], "texture": "#0"}, 357 | "up": {"uv": [3, 2, 4, 12], "texture": "#0"}, 358 | "down": {"uv": [3, 4, 4, 14], "texture": "#0"} 359 | } 360 | }, 361 | { 362 | "from": [4, 11, 12], 363 | "to": [12, 12, 13], 364 | "faces": { 365 | "north": {"uv": [4, 4, 12, 5], "texture": "#0"}, 366 | "east": {"uv": [3, 4, 4, 5], "texture": "#0"}, 367 | "south": {"uv": [4, 4, 12, 5], "texture": "#0"}, 368 | "west": {"uv": [12, 4, 13, 5], "texture": "#0"}, 369 | "up": {"uv": [4, 12, 12, 13], "texture": "#0"}, 370 | "down": {"uv": [4, 3, 12, 4], "texture": "#0"} 371 | } 372 | }, 373 | { 374 | "from": [11, 11, 2], 375 | "to": [12, 12, 12], 376 | "faces": { 377 | "north": {"uv": [4, 4, 5, 5], "texture": "#0"}, 378 | "east": {"uv": [4, 4, 14, 5], "texture": "#0"}, 379 | "south": {"uv": [11, 4, 12, 5], "texture": "#0"}, 380 | "west": {"uv": [2, 4, 12, 5], "texture": "#0"}, 381 | "up": {"uv": [11, 2, 12, 12], "texture": "#0"}, 382 | "down": {"uv": [11, 4, 12, 14], "texture": "#0"} 383 | } 384 | }, 385 | { 386 | "from": [5, 11, 2], 387 | "to": [11, 12, 3], 388 | "faces": { 389 | "north": {"uv": [5, 4, 11, 5], "texture": "#0"}, 390 | "east": {"uv": [13, 4, 14, 5], "texture": "#0"}, 391 | "south": {"uv": [5, 4, 11, 5], "texture": "#0"}, 392 | "west": {"uv": [2, 4, 3, 5], "texture": "#0"}, 393 | "up": {"uv": [5, 2, 11, 3], "texture": "#0"}, 394 | "down": {"uv": [5, 13, 11, 14], "texture": "#0"} 395 | } 396 | }, 397 | { 398 | "from": [4, 11, 1], 399 | "to": [12, 12, 2], 400 | "faces": { 401 | "north": {"uv": [4, 4, 12, 5], "texture": "#0"}, 402 | "east": {"uv": [14, 4, 15, 5], "texture": "#0"}, 403 | "south": {"uv": [4, 4, 12, 5], "texture": "#0"}, 404 | "west": {"uv": [1, 4, 2, 5], "texture": "#0"}, 405 | "up": {"uv": [4, 1, 12, 2], "texture": "#0"}, 406 | "down": {"uv": [4, 14, 12, 15], "texture": "#0"} 407 | } 408 | }, 409 | { 410 | "from": [12, 11, 2], 411 | "to": [13, 12, 12], 412 | "faces": { 413 | "north": {"uv": [3, 4, 4, 5], "texture": "#0"}, 414 | "east": {"uv": [4, 4, 14, 5], "texture": "#0"}, 415 | "south": {"uv": [12, 4, 13, 5], "texture": "#0"}, 416 | "west": {"uv": [2, 4, 12, 5], "texture": "#0"}, 417 | "up": {"uv": [12, 2, 13, 12], "texture": "#0"}, 418 | "down": {"uv": [12, 4, 13, 14], "texture": "#0"} 419 | } 420 | }, 421 | { 422 | "from": [4, 10, 13], 423 | "to": [12, 23, 14], 424 | "faces": { 425 | "north": {"uv": [4, 0, 12, 6], "texture": "#6"}, 426 | "east": {"uv": [2, 0, 3, 6], "texture": "#6"}, 427 | "south": {"uv": [4, 0, 12, 6], "texture": "#6"}, 428 | "west": {"uv": [13, 0, 14, 6], "texture": "#6"}, 429 | "up": {"uv": [4, 13, 12, 14], "texture": "#6"}, 430 | "down": {"uv": [4, 2, 12, 3], "texture": "#6"} 431 | } 432 | } 433 | ], 434 | "display": { 435 | "thirdperson_righthand": { 436 | "rotation": [75, 45, 0], 437 | "translation": [0, 2.5, 0], 438 | "scale": [0.375, 0.375, 0.375] 439 | }, 440 | "thirdperson_lefthand": { 441 | "rotation": [75, 45, 0], 442 | "translation": [0, 2.5, 0], 443 | "scale": [0.375, 0.375, 0.375] 444 | }, 445 | "firstperson_righthand": { 446 | "rotation": [0, 45, 0], 447 | "scale": [0.4, 0.4, 0.4] 448 | }, 449 | "firstperson_lefthand": { 450 | "rotation": [0, 225, 0], 451 | "scale": [0.4, 0.4, 0.4] 452 | }, 453 | "ground": { 454 | "translation": [0, 3, 0], 455 | "scale": [0.25, 0.25, 0.25] 456 | }, 457 | "gui": { 458 | "rotation": [30, 225, 0], 459 | "translation": [0, -2.5, 0], 460 | "scale": [0.625, 0.625, 0.625] 461 | }, 462 | "head": { 463 | "translation": [0, -27.5, 0], 464 | "scale": [4, 4, 4] 465 | }, 466 | "fixed": { 467 | "rotation": [0, 90, 0], 468 | "scale": [0.5, 0.5, 0.5] 469 | } 470 | } 471 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/bean_axe.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "tutorialmod:items/bean_axe" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/bean_boots.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "tutorialmod:items/bean_boots" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/bean_chestplate.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "tutorialmod:items/bean_chestplate" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/bean_helmet.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "tutorialmod:items/bean_helmet" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/bean_hoe.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "tutorialmod:items/bean_hoe" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/bean_leggings.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "tutorialmod:items/bean_leggings" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/bean_pickaxe.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "tutorialmod:items/bean_pickaxe" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/bean_shovel.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "tutorialmod:items/bean_shovel" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/bean_sword.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "tutorialmod:items/bean_sword" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/beans.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "tutorialmod:items/beans" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/clicker.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "tutorialmod:items/clicker" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/cropium.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "tutorialmod:items/cropium" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/cropium_seeds.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "tutorialmod:items/cropium_seeds" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/display_hand.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:block/glass" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/drawer.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "tutorialmod:block/drawer" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/example_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "tutorialmod:block/example_block" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/example_chest.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "tutorialmod:block/example_chest" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/example_entity_spawn_egg.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/template_spawn_egg" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/example_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "tutorialmod:items/example_item" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/lightning_jumper.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "tutorialmod:block/lightning_jumper" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/poop.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "tutorialmod:items/poop" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/poop_storage.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "tutorialmod:block/poop_storage" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/models/item/toilet.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "tutorialmod:block/toilet" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/sounds.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity.example_entity.ambient": { 3 | "sounds": [ 4 | "tutorialmod:example_entity_ambient" 5 | ] 6 | }, 7 | 8 | "entity.example_entity.death": { 9 | "sounds": [ 10 | "tutorialmod:example_entity_death" 11 | ] 12 | }, 13 | 14 | "entity.example_entity.hurt": { 15 | "sounds": [ 16 | "tutorialmod:example_entity_hurt" 17 | ] 18 | }, 19 | 20 | "block.toilet.fart": { 21 | "sounds": [ 22 | "tutorialmod:fart" 23 | ] 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/sounds/example_entity_ambient.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/sounds/example_entity_ambient.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/sounds/example_entity_death.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/sounds/example_entity_death.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/sounds/example_entity_hurt.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/sounds/example_entity_hurt.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/sounds/fart.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/sounds/fart.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage0.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage1.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage2.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage3.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage4.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage5.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage6.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/cropium_stage7.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/drawer_front.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/drawer_front.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/drawer_side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/drawer_side.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/example_block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/example_block.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/example_chest_front.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/example_chest_front.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/example_chest_side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/example_chest_side.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/example_chest_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/example_chest_top.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/poop_storage_side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/poop_storage_side.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/blocks/poop_storage_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/blocks/poop_storage_top.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/entities/example_entity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/entities/example_entity.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/gui/energy_generator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/gui/energy_generator.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/gui/energy_storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/gui/energy_storage.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/gui/example_chest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/gui/example_chest.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/gui/poop_storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/gui/poop_storage.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/bean_axe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/bean_axe.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/bean_boots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/bean_boots.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/bean_chestplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/bean_chestplate.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/bean_helmet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/bean_helmet.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/bean_hoe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/bean_hoe.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/bean_leggings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/bean_leggings.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/bean_pickaxe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/bean_pickaxe.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/bean_shovel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/bean_shovel.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/bean_sword.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/bean_sword.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/beans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/beans.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/clicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/clicker.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/cropium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/cropium.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/cropium_seeds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/cropium_seeds.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/example_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/example_item.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/items/poop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/items/poop.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/models/armor/bean_layer_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/models/armor/bean_layer_1.png -------------------------------------------------------------------------------- /src/main/resources/assets/tutorialmod/textures/models/armor/bean_layer_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaRealTurtyWurty/1.18-Tutorial-Mod/5cb9f9b149bb629deac78f5727f87dc9f09e1d62/src/main/resources/assets/tutorialmod/textures/models/armor/bean_layer_2.png -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | "tutorialmod:example_block" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/tags/blocks/needs_iron_tool.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | "tutorialmod:example_block" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/main/resources/data/tutorialmod/loot_tables/blocks/cropium.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "rolls": 1, 6 | "bonus_rolls": 0, 7 | "entries": [ 8 | { 9 | "type": "minecraft:alternatives", 10 | "children": [ 11 | { 12 | "type": "minecraft:item", 13 | "name": "tutorialmod:cropium", 14 | "conditions": [ 15 | { 16 | "condition": "minecraft:block_state_property", 17 | "block": "tutorialmod:cropium", 18 | "properties": { 19 | "age": "7" 20 | } 21 | } 22 | ] 23 | }, 24 | { 25 | "type": "minecraft:item", 26 | "name": "tutorialmod:cropium_seeds" 27 | } 28 | ] 29 | } 30 | ] 31 | }, 32 | { 33 | "rolls": 1, 34 | "bonus_rolls": 0, 35 | "entries": [ 36 | { 37 | "type": "minecraft:item", 38 | "name": "tutorialmod:cropium_seeds", 39 | "functions": [ 40 | { 41 | "function": "minecraft:apply_bonus", 42 | "enchantment": "minecraft:fortune", 43 | "formula": "minecraft:binomial_with_bonus_count", 44 | "parameters": { 45 | "extra": 3, 46 | "probability": 0.5714286 47 | } 48 | } 49 | ] 50 | } 51 | ], 52 | "conditions": [ 53 | { 54 | "condition": "minecraft:block_state_property", 55 | "block": "tutorialmod:cropium", 56 | "properties": { 57 | "age": "7" 58 | } 59 | } 60 | ] 61 | } 62 | ], 63 | "functions": [ 64 | { 65 | "function": "minecraft:explosion_decay" 66 | } 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /src/main/resources/data/tutorialmod/loot_tables/blocks/example_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "rolls": 1, 6 | "bonus_rolls": 0, 7 | "entries": [ 8 | { 9 | "type": "minecraft:item", 10 | "name": "tutorialmod:example_block" 11 | } 12 | ], 13 | "conditions": [ 14 | { 15 | "condition": "minecraft:survives_explosion" 16 | } 17 | ] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/data/tutorialmod/loot_tables/entities/example_entity.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:entity", 3 | "pools": [ 4 | { 5 | "rolls": 1, 6 | "bonus_rolls": 0, 7 | "entries": [ 8 | { 9 | "type": "minecraft:item", 10 | "name": "minecraft:acacia_boat", 11 | "functions": [ 12 | { 13 | "function": "minecraft:set_count", 14 | "count": { 15 | "type": "minecraft:uniform", 16 | "min": 0, 17 | "max": 1 18 | }, 19 | "add": false 20 | }, 21 | { 22 | "function": "minecraft:looting_enchant", 23 | "count": { 24 | "type": "minecraft:uniform", 25 | "min": 0, 26 | "max": 1 27 | } 28 | } 29 | ] 30 | } 31 | ], 32 | "conditions": [ 33 | { 34 | "condition": "minecraft:killed_by_player" 35 | } 36 | ] 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /src/main/resources/data/tutorialmod/recipes/bean_leggings.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "###", 5 | "# #", 6 | "# #" 7 | ], 8 | "key": { 9 | "#": { 10 | "item": "tutorialmod:beans" 11 | } 12 | }, 13 | "result": { 14 | "item": "tutorialmod:bean_leggings", 15 | "count": 1 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "examplemod resources", 4 | "pack_format": 9 5 | } 6 | } 7 | --------------------------------------------------------------------------------