├── .gitignore ├── Jenkinsfile ├── README.md ├── build.bat ├── build.gradle ├── build.properties ├── clean.bat ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── logs ├── debug.log └── latest.log ├── runClient.launch ├── runServer.launch └── src └── main ├── java └── vazkii │ └── arl │ ├── AutoRegLib.java │ ├── block │ ├── BasicBlock.java │ └── be │ │ ├── ARLBlockEntity.java │ │ └── SimpleInventoryBlockEntity.java │ ├── container │ ├── ContainerBasic.java │ └── slot │ │ ├── SlotFiltered.java │ │ └── SlotType.java │ ├── interf │ ├── IBlockColorProvider.java │ ├── IBlockItemProvider.java │ ├── ICreativeExtras.java │ ├── IItemColorProvider.java │ └── IItemPropertiesFiller.java │ ├── item │ └── BasicItem.java │ ├── network │ ├── BlockEntityMessage.java │ ├── IMessage.java │ ├── MessageSerializer.java │ └── NetworkHandler.java │ └── util │ ├── ARLClientInitializer.java │ ├── ClientTicker.java │ ├── CreativeTabHandler.java │ ├── InventoryIIH.java │ ├── ItemNBTHelper.java │ ├── RegistryHelper.java │ ├── RenderHelper.java │ ├── RotationHandler.java │ ├── TooltipHandler.java │ └── VanillaPacketDispatcher.java └── resources ├── META-INF └── mods.toml ├── assets └── autoreglib │ └── lang │ ├── en_us.json │ ├── es_ar.json │ ├── es_es.json │ ├── es_mx.json │ ├── fr_fr.json │ ├── hr_hr.json │ ├── ko_kr.json │ ├── pl_pl.json │ └── ru_ru.json └── pack.mcmeta /.gitignore: -------------------------------------------------------------------------------- 1 | ## Windows 2 | Thumbs.db 3 | 4 | ## gradle 5 | /.gradle 6 | /build 7 | 8 | ## ForgeGradle 9 | /run 10 | 11 | ## eclipse 12 | /.settings 13 | /.metadata 14 | /.classpath 15 | /.project 16 | /eclipse 17 | /bin 18 | 19 | ## intellij 20 | /out 21 | /.idea 22 | /atlassian-ide-plugin.xml 23 | /*.ipr 24 | /*.iws 25 | /*.iml 26 | 27 | ## Private Stuffs 28 | /private.properties 29 | 30 | ## Jars 31 | *.jar 32 | !/gradle/wrapper/gradle-wrapper.jar 33 | !GardenOfGlass.jar 34 | 35 | ### OSX (adds a lot of garbage)### 36 | .DS_Store 37 | .AppleDouble 38 | .LSOverride 39 | 40 | # Icon must end with two \r 41 | Icon 42 | 43 | 44 | # Thumbnails 45 | ._* 46 | 47 | # Files that might appear in the root of a volume 48 | .DocumentRevisions-V100 49 | .fseventsd 50 | .Spotlight-V100 51 | .TemporaryItems 52 | .Trashes 53 | .VolumeIcon.icns 54 | 55 | # Directories potentially created on remote AFP share 56 | .AppleDB 57 | .AppleDesktop 58 | Network Trash Folder 59 | Temporary Items 60 | .apdisk 61 | 62 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | pipeline { 4 | agent any 5 | tools { 6 | jdk "jdk-17.0.1" 7 | } 8 | stages { 9 | stage('Clean') { 10 | steps { 11 | echo 'Cleaning Project' 12 | sh 'chmod +x gradlew' 13 | sh './gradlew clean' 14 | } 15 | } 16 | stage('Build and Deploy') { 17 | steps { 18 | echo 'Building and Deploying to Maven' 19 | sh './gradlew build publish' 20 | } 21 | } 22 | } 23 | post { 24 | always { 25 | archive 'build/libs/**.jar' 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AutoRegLib 2 | Automatic registry/loading library for minecraft mods. 3 | 4 | As this library is composite of classes from multiple classes from other mods of mine, each individual class falls under the license of the project it comes from. 5 | 6 | * [Botania License](http://botaniamod.net/license.php) 7 | * [Psi License](http://psi.vazkii.us/license.php) 8 | * [Quark License](https://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_GB) 9 | * [AutoRegLib classes License](http://www.wtfpl.net/) 10 | 11 | ## Maven 12 | 13 | `http://maven.blamejared.com/` 14 | 15 | **1.12**: `vazkii.autoreglib:AutoRegLib` 16 | **1.14**: `vazkii.arl:AutoRegLib` 17 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | gradlew build sortArtifacts incrementBuildNumber 2 | pause -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url = 'https://maven.minecraftforge.net' } 4 | mavenCentral() 5 | } 6 | dependencies { 7 | classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1+', changing: true 8 | } 9 | } 10 | 11 | apply plugin: 'net.minecraftforge.gradle' 12 | apply plugin: 'eclipse' 13 | apply plugin: 'maven-publish' 14 | 15 | ext.configFile = file('build.properties') 16 | ext.config = parseConfig(configFile) 17 | 18 | version = "${config.version}-${config.build_number}" 19 | group = "vazkii.${config.mod_id}" // http://maven.apache.org/guides/mini/guide-naming-conventions.html 20 | archivesBaseName = config.mod_name 21 | 22 | java { 23 | toolchain.languageVersion = JavaLanguageVersion.of(17) 24 | withSourcesJar() 25 | } 26 | 27 | println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) 28 | 29 | if (System.getenv('BUILD_NUMBER') != null) { 30 | version += "." + System.getenv('BUILD_NUMBER') 31 | } 32 | 33 | minecraft { 34 | // The mappings can be changed at any time, and must be in the following format. 35 | // snapshot_YYYYMMDD Snapshot are built nightly. 36 | // stable_# Stables are built at the discretion of the MCP team. 37 | // Use non-default mappings at your own risk. they may not always work. 38 | // Simply re-run your setup task after changing the mappings to update your workspace. 39 | 40 | mappings channel: "${config.mapping_channel}", version: "${config.mapping_version}" 41 | // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. 42 | 43 | // Default run configurations. 44 | // These can be tweaked, removed, or duplicated as needed. 45 | runs { 46 | client { 47 | workingDirectory project.file('run') 48 | 49 | // Recommended logging data for a userdev environment 50 | property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' 51 | 52 | // Recommended logging level for the console 53 | property 'forge.logging.console.level', 'debug' 54 | 55 | mods { 56 | autoreglib { 57 | source sourceSets.main 58 | } 59 | } 60 | } 61 | 62 | server { 63 | workingDirectory project.file('run') 64 | 65 | // Recommended logging data for a userdev environment 66 | property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' 67 | 68 | // Recommended logging level for the console 69 | property 'forge.logging.console.level', 'debug' 70 | 71 | mods { 72 | autoreglib { 73 | source sourceSets.main 74 | } 75 | } 76 | } 77 | } 78 | } 79 | 80 | dependencies { 81 | minecraft "net.minecraftforge:forge:${config.mc_version}-${config.forge_version}" 82 | } 83 | 84 | processResources { 85 | // copy everything excluding psd files 86 | from(sourceSets.main.resources.srcDirs) { 87 | exclude '**/psd/**' 88 | duplicatesStrategy 'include' 89 | } 90 | } 91 | 92 | task incrementBuildNumber { 93 | doFirst { 94 | config.build_number = (config.build_number.toString().toInteger()) + 1 95 | configFile.withWriter { 96 | config.toProperties().store(it, "") 97 | } 98 | } 99 | 100 | //file('web/versions.ini').append("\n${version}=${minecraft.version}") 101 | //file("${config.dir_repo}/version/${minecraft.version}.txt").write("${version}") 102 | } 103 | 104 | import java.util.regex.Pattern 105 | task sortArtifacts(type: Copy) { 106 | from jar.destinationDir 107 | into config.dir_output 108 | //Put each jar with a classifier in a subfolder with the classifier as its name 109 | eachFile { 110 | //This matcher is used to get the classifier of the jar 111 | def matcher = Pattern.compile(Pattern.quote("$config.mod_name-$version") + "-(?\\w+).jar").matcher(it.name) 112 | //Only change the destination for full matches, i.e jars with classifiers 113 | if (matcher.matches()) 114 | { 115 | def classifier = matcher.group('classifier') 116 | /* Set the relative path to change the destination, since 117 | * Gradle doesn't seem to like the absolute path being set*/ 118 | it.relativePath = it.relativePath.parent.append(false, classifier, it.name) 119 | } 120 | } 121 | } 122 | 123 | def parseConfig(File config) { 124 | config.withReader { 125 | def prop = new Properties() 126 | prop.load(it) 127 | return (new ConfigSlurper().parse(prop)) 128 | } 129 | } 130 | 131 | jar { 132 | //rename the default output, for some better... sanity with scipts 133 | archiveName = "${baseName}-${version}.${extension}" 134 | 135 | manifest { 136 | attributes([ 137 | "Specification-Title": "${config.mod_id}", 138 | "Specification-Vendor": "vazkii", 139 | "Specification-Version": "1", // We are version 1 of ourselves 140 | "Implementation-Title": "${config.mod_id}", 141 | "Implementation-Version": "${version}", 142 | "Implementation-Vendor" :"vazkii", 143 | "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") 144 | ]) 145 | } 146 | 147 | exclude "**/*.bat" 148 | exclude "**/*.psd" 149 | exclude "**/*.exe" 150 | exclude "**/unused" 151 | } 152 | 153 | task deobfJar(type: Jar) { 154 | classifier = "deobf" 155 | from sourceSets.main.output 156 | } 157 | 158 | artifacts { 159 | archives deobfJar 160 | } 161 | 162 | publish.dependsOn(project.tasks.getByName("assemble")) 163 | publish.mustRunAfter(project.tasks.getByName("build")) 164 | 165 | publishing { 166 | 167 | publications { 168 | 169 | mavenJava(MavenPublication) { 170 | 171 | groupId project.group 172 | artifactId project.archivesBaseName 173 | version project.version 174 | from components.java 175 | 176 | // Allows the maven pom file to be modified. 177 | pom.withXml { 178 | 179 | // Go through all the dependencies. 180 | asNode().dependencies.dependency.each { dep -> 181 | 182 | println 'Surpressing artifact ' + dep.artifactId.last().value().last() + ' from maven dependencies.' 183 | assert dep.parent().remove(dep) 184 | } 185 | } 186 | } 187 | } 188 | 189 | repositories { 190 | maven { 191 | url "file://" + System.getenv("local_maven") 192 | } 193 | } 194 | } 195 | 196 | // Disables Gradle's custom module metadata from being published to maven. The 197 | // metadata includes mapped dependencies which are not reasonably consumable by 198 | // other mod developers. 199 | tasks.withType(GenerateModuleMetadata) { 200 | 201 | enabled = false 202 | } 203 | 204 | defaultTasks 'clean', 'build', 'sortArtifacts', 'incrementBuildNumber' -------------------------------------------------------------------------------- /build.properties: -------------------------------------------------------------------------------- 1 | # 2 | #Sun Nov 20 13:37:16 WET 2022 3 | mapping_channel=official 4 | forge_version=45.0.64 5 | mod_id=autoreglib 6 | build_number=58 7 | dir_output=../Build Output/ARL/ 8 | mapping_version=1.19.4 9 | version=1.9 10 | mod_name=AutoRegLib 11 | mc_version=1.19.4 12 | -------------------------------------------------------------------------------- /clean.bat: -------------------------------------------------------------------------------- 1 | gradlew clean 2 | pause -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VazkiiMods/AutoRegLib/edfb9bcd46577bb022c996dbe5db4c8cc9a8ae12/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/VazkiiMods/AutoRegLib/edfb9bcd46577bb022c996dbe5db4c8cc9a8ae12/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 | -------------------------------------------------------------------------------- /logs/debug.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VazkiiMods/AutoRegLib/edfb9bcd46577bb022c996dbe5db4c8cc9a8ae12/logs/debug.log -------------------------------------------------------------------------------- /logs/latest.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VazkiiMods/AutoRegLib/edfb9bcd46577bb022c996dbe5db4c8cc9a8ae12/logs/latest.log -------------------------------------------------------------------------------- /runClient.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /runServer.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/AutoRegLib.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This class is licensed under the WTFPL 3 | * http://www.wtfpl.net/ 4 | */ 5 | package vazkii.arl; 6 | 7 | import org.apache.logging.log4j.LogManager; 8 | import org.apache.logging.log4j.Logger; 9 | 10 | import net.minecraftforge.fml.common.Mod; 11 | 12 | @Mod(AutoRegLib.MOD_ID) 13 | public class AutoRegLib { 14 | 15 | public static final String MOD_ID = "autoreglib"; 16 | 17 | public static final Logger LOGGER = LogManager.getLogger(MOD_ID); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/block/BasicBlock.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.block; 2 | 3 | import net.minecraft.world.level.block.Block; 4 | import vazkii.arl.util.RegistryHelper; 5 | 6 | import net.minecraft.world.level.block.state.BlockBehaviour.Properties; 7 | 8 | public class BasicBlock extends Block { 9 | 10 | public BasicBlock(String regname, Properties properties) { 11 | super(properties); 12 | 13 | RegistryHelper.registerBlock(this, regname); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/block/be/ARLBlockEntity.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This class was created by . It's distributed as 3 | * part of the Botania Mod. Get the Source Code in github: 4 | * https://github.com/Vazkii/Botania 5 | * 6 | * Botania is Open Source and distributed under the 7 | * Botania License: http://botaniamod.net/license.php 8 | * 9 | * File Created @ [Jan 21, 2014, 9:18:28 PM (GMT)] 10 | */ 11 | package vazkii.arl.block.be; 12 | 13 | import net.minecraft.core.BlockPos; 14 | import net.minecraft.nbt.CompoundTag; 15 | import net.minecraft.network.Connection; 16 | import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; 17 | import net.minecraft.world.level.block.entity.BlockEntity; 18 | import net.minecraft.world.level.block.entity.BlockEntityType; 19 | import net.minecraft.world.level.block.state.BlockState; 20 | import vazkii.arl.util.VanillaPacketDispatcher; 21 | 22 | public abstract class ARLBlockEntity extends BlockEntity { 23 | 24 | public ARLBlockEntity(BlockEntityType tileEntityTypeIn, BlockPos pos, BlockState state) { 25 | super(tileEntityTypeIn, pos, state); 26 | } 27 | 28 | @Override 29 | protected void saveAdditional(CompoundTag nbt) { 30 | super.saveAdditional(nbt); 31 | 32 | writeSharedNBT(nbt); 33 | } 34 | 35 | @Override 36 | public void load(CompoundTag nbt) { 37 | super.load(nbt); 38 | 39 | readSharedNBT(nbt); 40 | } 41 | 42 | public void writeSharedNBT(CompoundTag cmp) { 43 | // NO-OP 44 | } 45 | 46 | public void readSharedNBT(CompoundTag cmp) { 47 | // NO-OP 48 | } 49 | 50 | public void sync() { 51 | VanillaPacketDispatcher.dispatchTEToNearbyPlayers(this); 52 | } 53 | 54 | @Override 55 | public CompoundTag getUpdateTag() { 56 | CompoundTag cmp = new CompoundTag(); 57 | writeSharedNBT(cmp); 58 | return cmp; 59 | } 60 | 61 | @Override 62 | public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket packet) { 63 | super.onDataPacket(net, packet); 64 | 65 | if(packet != null) 66 | readSharedNBT(packet.getTag()); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/block/be/SimpleInventoryBlockEntity.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This class was created by . It's distributed as 3 | * part of the Psi Mod. Get the Source Code in github: 4 | * https://github.com/Vazkii/Psi 5 | * 6 | * Psi is Open Source and distributed under the 7 | * Psi License: http://psi.vazkii.us/license.php 8 | * 9 | * File Created @ [10/01/2016, 15:13:46 (GMT)] 10 | */ 11 | package vazkii.arl.block.be; 12 | 13 | import javax.annotation.Nonnull; 14 | 15 | import net.minecraft.world.entity.player.Player; 16 | import net.minecraft.world.WorldlyContainer; 17 | import net.minecraft.world.item.ItemStack; 18 | import net.minecraft.nbt.CompoundTag; 19 | import net.minecraft.nbt.ListTag; 20 | import net.minecraft.world.level.block.entity.BlockEntityType; 21 | import net.minecraft.world.level.block.state.BlockState; 22 | import net.minecraft.core.BlockPos; 23 | import net.minecraft.core.Direction; 24 | import net.minecraft.core.NonNullList; 25 | import net.minecraftforge.common.capabilities.Capability; 26 | import net.minecraftforge.common.util.LazyOptional; 27 | import net.minecraftforge.items.CapabilityItemHandler; 28 | import net.minecraftforge.items.wrapper.SidedInvWrapper; 29 | 30 | public abstract class SimpleInventoryBlockEntity extends ARLBlockEntity implements WorldlyContainer { 31 | 32 | public SimpleInventoryBlockEntity(BlockEntityType tileEntityTypeIn, BlockPos pos, BlockState state) { 33 | super(tileEntityTypeIn, pos, state); 34 | } 35 | 36 | protected NonNullList inventorySlots = NonNullList.withSize(getContainerSize(), ItemStack.EMPTY); 37 | 38 | @Override 39 | public void readSharedNBT(CompoundTag par1NBTTagCompound) { 40 | if(!needsToSyncInventory()) 41 | return; 42 | 43 | ListTag var2 = par1NBTTagCompound.getList("Items", 10); 44 | clearContent(); 45 | for(int var3 = 0; var3 < var2.size(); ++var3) { 46 | CompoundTag var4 = var2.getCompound(var3); 47 | byte var5 = var4.getByte("Slot"); 48 | if (var5 >= 0 && var5 < inventorySlots.size()) 49 | inventorySlots.set(var5, ItemStack.of(var4)); 50 | } 51 | } 52 | 53 | @Override 54 | public void writeSharedNBT(CompoundTag par1NBTTagCompound) { 55 | if(!needsToSyncInventory()) 56 | return; 57 | 58 | ListTag var2 = new ListTag(); 59 | for (int var3 = 0; var3 < inventorySlots.size(); ++var3) { 60 | if(!inventorySlots.get(var3).isEmpty()) { 61 | CompoundTag var4 = new CompoundTag(); 62 | var4.putByte("Slot", (byte)var3); 63 | inventorySlots.get(var3).save(var4); 64 | var2.add(var4); 65 | } 66 | } 67 | par1NBTTagCompound.put("Items", var2); 68 | } 69 | 70 | protected boolean needsToSyncInventory() { 71 | return true; 72 | } 73 | 74 | @Nonnull 75 | @Override 76 | public ItemStack getItem(int i) { 77 | return inventorySlots.get(i); 78 | } 79 | 80 | @Nonnull 81 | @Override 82 | public ItemStack removeItem(int i, int j) { 83 | if (!inventorySlots.get(i).isEmpty()) { 84 | ItemStack stackAt; 85 | 86 | if (inventorySlots.get(i).getCount() <= j) { 87 | stackAt = inventorySlots.get(i); 88 | inventorySlots.set(i, ItemStack.EMPTY); 89 | inventoryChanged(i); 90 | return stackAt; 91 | } else { 92 | stackAt = inventorySlots.get(i).split(j); 93 | 94 | if (inventorySlots.get(i).getCount() == 0) 95 | inventorySlots.set(i, ItemStack.EMPTY); 96 | inventoryChanged(i); 97 | 98 | return stackAt; 99 | } 100 | } 101 | 102 | return ItemStack.EMPTY; 103 | } 104 | 105 | @Nonnull 106 | @Override 107 | public ItemStack removeItemNoUpdate(int i) { 108 | ItemStack stack = getItem(i); 109 | setItem(i, ItemStack.EMPTY); 110 | inventoryChanged(i); 111 | return stack; 112 | } 113 | 114 | @Override 115 | public void setItem(int i, @Nonnull ItemStack itemstack) { 116 | inventorySlots.set(i, itemstack); 117 | inventoryChanged(i); 118 | } 119 | 120 | @Override 121 | public int getMaxStackSize() { 122 | return 64; 123 | } 124 | 125 | @Override 126 | public boolean isEmpty() { 127 | for(int i = 0; i < getContainerSize(); i++) { 128 | ItemStack stack = getItem(i); 129 | if(!stack.isEmpty()) 130 | return false; 131 | } 132 | 133 | return true; 134 | } 135 | 136 | @Override 137 | public boolean stillValid(@Nonnull Player entityplayer) { 138 | return getLevel().getBlockEntity(getBlockPos()) == this && entityplayer.distanceToSqr(worldPosition.getX() + 0.5D, worldPosition.getY() + 0.5D, worldPosition.getZ() + 0.5D) <= 64; 139 | } 140 | 141 | @SuppressWarnings("unchecked") 142 | @Override 143 | public LazyOptional getCapability(@Nonnull Capability capability, Direction facing) { 144 | if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) 145 | return (LazyOptional) LazyOptional.of(() -> new SidedInvWrapper(this, facing)); 146 | 147 | return LazyOptional.empty(); 148 | } 149 | 150 | @Override 151 | public boolean canPlaceItem(int i, @Nonnull ItemStack itemstack) { 152 | return true; 153 | } 154 | 155 | @Override 156 | public void startOpen(@Nonnull Player player) { 157 | // NO-OP 158 | } 159 | 160 | @Override 161 | public void stopOpen(@Nonnull Player player) { 162 | // NO-OP 163 | } 164 | 165 | @Override 166 | public void clearContent() { 167 | inventorySlots = NonNullList.withSize(getContainerSize(), ItemStack.EMPTY); 168 | } 169 | 170 | public void inventoryChanged(int i) { 171 | // NO-OP 172 | } 173 | 174 | public boolean isAutomationEnabled() { 175 | return true; 176 | } 177 | 178 | @Override 179 | public boolean canTakeItemThroughFace(int index, @Nonnull ItemStack stack, @Nonnull Direction direction) { 180 | return isAutomationEnabled(); 181 | } 182 | 183 | @Override 184 | public boolean canPlaceItemThroughFace(int index, @Nonnull ItemStack itemStackIn, @Nonnull Direction direction) { 185 | return isAutomationEnabled(); 186 | } 187 | 188 | @Nonnull 189 | @Override 190 | public int[] getSlotsForFace(@Nonnull Direction side) { 191 | if(isAutomationEnabled()) { 192 | int[] slots = new int[getContainerSize()]; 193 | for(int i = 0; i < slots.length; i++) 194 | slots[i] = i; 195 | return slots; 196 | } 197 | 198 | return new int[0]; 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/container/ContainerBasic.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.container; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | import net.minecraft.world.entity.player.Player; 6 | import net.minecraft.world.entity.player.Inventory; 7 | import net.minecraft.world.Container; 8 | import net.minecraft.world.inventory.AbstractContainerMenu; 9 | import net.minecraft.world.inventory.MenuType; 10 | import net.minecraft.world.inventory.Slot; 11 | import net.minecraft.world.item.ItemStack; 12 | 13 | public abstract class ContainerBasic extends AbstractContainerMenu { 14 | 15 | protected final T tile; 16 | protected final int tileSlots; 17 | 18 | public ContainerBasic(MenuType type, int windowId, Inventory playerInv, T tile) { 19 | super(type, windowId); 20 | this.tile = tile; 21 | tileSlots = addSlots(); 22 | 23 | for(int i = 0; i < 3; ++i) 24 | for(int j = 0; j < 9; ++j) 25 | addSlot(new Slot(playerInv, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); 26 | 27 | for(int k = 0; k < 9; ++k) 28 | addSlot(new Slot(playerInv, k, 8 + k * 18, 142)); 29 | } 30 | 31 | public abstract int addSlots(); 32 | 33 | @Override 34 | public boolean stillValid(@Nonnull Player playerIn) { 35 | return tile.stillValid(playerIn); 36 | } 37 | 38 | @Nonnull 39 | @Override 40 | public ItemStack quickMoveStack(Player playerIn, int index) { 41 | ItemStack itemstack = ItemStack.EMPTY; 42 | Slot slot = slots.get(index); 43 | 44 | if(slot != null && slot.hasItem()) { 45 | ItemStack itemstack1 = slot.getItem(); 46 | itemstack = itemstack1.copy(); 47 | 48 | if(index < tileSlots) { 49 | if(!moveItemStackTo(itemstack1, tileSlots, slots.size(), true)) 50 | return ItemStack.EMPTY; 51 | } 52 | else if(!moveItemStackTo(itemstack1, 0, tileSlots, false)) 53 | return ItemStack.EMPTY; 54 | 55 | if(itemstack1.isEmpty()) 56 | slot.set(ItemStack.EMPTY); 57 | else 58 | slot.setChanged(); 59 | } 60 | 61 | return itemstack; 62 | } 63 | 64 | // Shamelessly stolen from CoFHCore because KL is awesome 65 | // and was like yeah just take whatever you want lol 66 | // https://github.com/CoFH/CoFHCore/blob/d4a79b078d257e88414f5eed598d57490ec8e97f/src/main/java/cofh/core/util/helpers/InventoryHelper.java 67 | @Override 68 | public boolean moveItemStackTo(ItemStack stack, int start, int length, boolean r) { 69 | boolean successful = false; 70 | int i = !r ? start : length - 1; 71 | int iterOrder = !r ? 1 : -1; 72 | 73 | Slot slot; 74 | ItemStack existingStack; 75 | 76 | if(stack.isStackable()) { 77 | while(stack.getCount() > 0 && (!r && i < length || r && i >= start)) { 78 | slot = slots.get(i); 79 | 80 | existingStack = slot.getItem(); 81 | 82 | if(!existingStack.isEmpty()) { 83 | int maxStack = Math.min(stack.getMaxStackSize(), slot.getMaxStackSize()); 84 | int rmv = Math.min(maxStack, stack.getCount()); 85 | 86 | if(slot.mayPlace(cloneStack(stack, rmv)) && existingStack.getItem().equals(stack.getItem()) && ItemStack.tagMatches(stack, existingStack)) { 87 | int existingSize = existingStack.getCount() + stack.getCount(); 88 | 89 | if(existingSize <= maxStack) { 90 | stack.setCount(0); 91 | existingStack.setCount(existingSize); 92 | slot.set(existingStack); 93 | successful = true; 94 | } else if(existingStack.getCount() < maxStack) { 95 | stack.shrink(maxStack - existingStack.getCount()); 96 | existingStack.setCount(maxStack); 97 | slot.set(existingStack); 98 | successful = true; 99 | } 100 | } 101 | } 102 | i += iterOrder; 103 | } 104 | } 105 | if(stack.getCount() > 0) { 106 | i = !r ? start : length - 1; 107 | while(stack.getCount() > 0 && (!r && i < length || r && i >= start)) { 108 | slot = slots.get(i); 109 | existingStack = slot.getItem(); 110 | 111 | if(existingStack.isEmpty()) { 112 | int maxStack = Math.min(stack.getMaxStackSize(), slot.getMaxStackSize()); 113 | int rmv = Math.min(maxStack, stack.getCount()); 114 | 115 | if(slot.mayPlace(cloneStack(stack, rmv))) { 116 | existingStack = stack.split(rmv); 117 | slot.set(existingStack); 118 | successful = true; 119 | } 120 | } 121 | i += iterOrder; 122 | } 123 | } 124 | return successful; 125 | } 126 | 127 | private static ItemStack cloneStack(ItemStack stack, int size) { 128 | if(stack.isEmpty()) 129 | return ItemStack.EMPTY; 130 | 131 | ItemStack copy = stack.copy(); 132 | copy.setCount(size); 133 | return copy; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/container/slot/SlotFiltered.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.container.slot; 2 | 3 | import java.util.function.Predicate; 4 | 5 | import net.minecraft.world.Container; 6 | import net.minecraft.world.inventory.Slot; 7 | import net.minecraft.world.item.ItemStack; 8 | 9 | public class SlotFiltered extends Slot { 10 | 11 | private final Predicate pred; 12 | 13 | public SlotFiltered(Container inventoryIn, int index, int xPosition, int yPosition, Predicate pred) { 14 | super(inventoryIn, index, xPosition, yPosition); 15 | this.pred = pred; 16 | } 17 | 18 | @Override 19 | public boolean mayPlace(ItemStack stack) { 20 | return pred.test(stack); 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/container/slot/SlotType.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.container.slot; 2 | 3 | import net.minecraft.world.Container; 4 | 5 | public class SlotType extends SlotFiltered { 6 | 7 | public SlotType(Container inventoryIn, int index, int xPosition, int yPosition, Class clazz) { 8 | super(inventoryIn, index, xPosition, yPosition, 9 | (stack) -> clazz.isAssignableFrom(stack.getItem().getClass())); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/interf/IBlockColorProvider.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.interf; 2 | 3 | import net.minecraft.client.color.block.BlockColor; 4 | import net.minecraftforge.api.distmarker.Dist; 5 | import net.minecraftforge.api.distmarker.OnlyIn; 6 | 7 | public interface IBlockColorProvider extends IItemColorProvider { 8 | 9 | @OnlyIn(Dist.CLIENT) 10 | public BlockColor getBlockColor(); 11 | 12 | } -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/interf/IBlockItemProvider.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.interf; 2 | 3 | import net.minecraft.world.level.block.Block; 4 | import net.minecraft.world.item.BlockItem; 5 | import net.minecraft.world.item.Item; 6 | 7 | public interface IBlockItemProvider { 8 | 9 | BlockItem provideItemBlock(Block block, Item.Properties props); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/interf/ICreativeExtras.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.interf; 2 | 3 | import net.minecraft.world.item.CreativeModeTab; 4 | import net.minecraftforge.event.CreativeModeTabEvent; 5 | 6 | public interface ICreativeExtras { 7 | 8 | public default boolean canAddToCreativeTab(CreativeModeTab tab) { 9 | return true; 10 | } 11 | 12 | public void addCreativeModeExtras(CreativeModeTab tab, CreativeModeTabEvent.BuildContents event); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/interf/IItemColorProvider.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.interf; 2 | 3 | import net.minecraft.client.color.item.ItemColor; 4 | import net.minecraftforge.api.distmarker.Dist; 5 | import net.minecraftforge.api.distmarker.OnlyIn; 6 | 7 | public interface IItemColorProvider { 8 | 9 | @OnlyIn(Dist.CLIENT) 10 | public ItemColor getItemColor(); 11 | 12 | } -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/interf/IItemPropertiesFiller.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.interf; 2 | 3 | import net.minecraft.world.item.Item; 4 | 5 | public interface IItemPropertiesFiller { 6 | 7 | void fillItemProperties(Item.Properties props); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/item/BasicItem.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.item; 2 | 3 | import net.minecraft.world.item.Item; 4 | import vazkii.arl.util.RegistryHelper; 5 | 6 | import net.minecraft.world.item.Item.Properties; 7 | 8 | public class BasicItem extends Item { 9 | 10 | public BasicItem(String regname, Properties properties) { 11 | super(properties); 12 | 13 | RegistryHelper.registerItem(this, regname); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/network/BlockEntityMessage.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This class was created by . It's distributed as 3 | * part of the Psi Mod. Get the Source Code in github: 4 | * https://github.com/Vazkii/Psi 5 | * 6 | * Psi is Open Source and distributed under the 7 | * Psi License: http://psi.vazkii.us/license.php 8 | * 9 | * File Created @ [16/01/2016, 18:51:44 (GMT)] 10 | */ 11 | package vazkii.arl.network; 12 | 13 | import net.minecraft.core.BlockPos; 14 | import net.minecraft.resources.ResourceLocation; 15 | import net.minecraft.server.level.ServerLevel; 16 | import net.minecraft.world.level.block.entity.BlockEntity; 17 | import net.minecraft.world.level.block.entity.BlockEntityType; 18 | import net.minecraftforge.network.NetworkEvent; 19 | import net.minecraftforge.registries.ForgeRegistries; 20 | 21 | public abstract class BlockEntityMessage implements IMessage { 22 | 23 | private static final long serialVersionUID = 4703277631856386752L; 24 | 25 | public BlockPos pos; 26 | public ResourceLocation typeExpected; 27 | 28 | public BlockEntityMessage() { } 29 | 30 | public BlockEntityMessage(BlockPos pos, BlockEntityType type) { 31 | this.pos = pos; 32 | typeExpected = ForgeRegistries.BLOCK_ENTITY_TYPES.getKey(type); 33 | } 34 | 35 | @SuppressWarnings({ "deprecation", "unchecked" }) 36 | @Override 37 | public final boolean receive(NetworkEvent.Context context) { 38 | ServerLevel world = context.getSender().getLevel(); 39 | if(world.hasChunkAt(pos)) { 40 | BlockEntity tile = world.getBlockEntity(pos); 41 | if(tile != null && ForgeRegistries.BLOCK_ENTITY_TYPES.getKey(tile.getType()).equals(typeExpected)) 42 | context.enqueueWork(() -> receive((T) tile, context)); 43 | } 44 | 45 | return true; 46 | } 47 | 48 | public abstract void receive(T tile, NetworkEvent.Context context); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/network/IMessage.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.network; 2 | 3 | import java.io.Serializable; 4 | 5 | import net.minecraftforge.network.NetworkEvent; 6 | 7 | public interface IMessage extends Serializable { 8 | 9 | public boolean receive(NetworkEvent.Context context); 10 | 11 | } -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/network/MessageSerializer.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.network; 2 | 3 | import java.lang.reflect.Array; 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.Modifier; 6 | import java.util.Arrays; 7 | import java.util.Comparator; 8 | import java.util.Date; 9 | import java.util.HashMap; 10 | import java.util.UUID; 11 | import java.util.function.BiConsumer; 12 | import java.util.function.Function; 13 | 14 | import org.apache.commons.lang3.tuple.Pair; 15 | 16 | import net.minecraft.world.item.ItemStack; 17 | import net.minecraft.nbt.CompoundTag; 18 | import net.minecraft.network.FriendlyByteBuf; 19 | import net.minecraft.resources.ResourceLocation; 20 | import net.minecraft.core.BlockPos; 21 | import net.minecraft.world.phys.BlockHitResult; 22 | import net.minecraft.network.chat.Component; 23 | 24 | @SuppressWarnings({ "unchecked", "rawtypes", "unused" }) 25 | public final class MessageSerializer { 26 | 27 | private static final HashMap, Pair> handlers = new HashMap<>(); 28 | private static final HashMap, Field[]> fieldCache = new HashMap<>(); 29 | 30 | static { 31 | MessageSerializer. mapFunctions(byte.class, FriendlyByteBuf::readByte, FriendlyByteBuf::writeByte); 32 | MessageSerializer. mapFunctions(short.class, FriendlyByteBuf::readShort, FriendlyByteBuf::writeShort); 33 | MessageSerializer. mapFunctions(int.class, FriendlyByteBuf::readInt, FriendlyByteBuf::writeInt); 34 | MessageSerializer. mapFunctions(long.class, FriendlyByteBuf::readLong, FriendlyByteBuf::writeLong); 35 | MessageSerializer. mapFunctions(float.class, FriendlyByteBuf::readFloat, FriendlyByteBuf::writeFloat); 36 | MessageSerializer. mapFunctions(double.class, FriendlyByteBuf::readDouble, FriendlyByteBuf::writeDouble); 37 | MessageSerializer. mapFunctions(boolean.class, FriendlyByteBuf::readBoolean, FriendlyByteBuf::writeBoolean); 38 | MessageSerializer. mapFunctions(char.class, FriendlyByteBuf::readChar, FriendlyByteBuf::writeChar); 39 | 40 | mapFunctions(BlockPos.class, FriendlyByteBuf::readBlockPos, FriendlyByteBuf::writeBlockPos); 41 | mapFunctions(Component.class, FriendlyByteBuf::readComponent, FriendlyByteBuf::writeComponent); 42 | mapFunctions(UUID.class, FriendlyByteBuf::readUUID, FriendlyByteBuf::writeUUID); 43 | mapFunctions(CompoundTag.class, FriendlyByteBuf::readNbt, FriendlyByteBuf::writeNbt); 44 | mapFunctions(ItemStack.class, FriendlyByteBuf::readItem, MessageSerializer::writeItemStack); 45 | mapFunctions(String.class, MessageSerializer::readString, MessageSerializer::writeString); 46 | mapFunctions(ResourceLocation.class, FriendlyByteBuf::readResourceLocation, FriendlyByteBuf::writeResourceLocation); 47 | mapFunctions(Date.class, FriendlyByteBuf::readDate, FriendlyByteBuf::writeDate); 48 | mapFunctions(BlockHitResult.class, FriendlyByteBuf::readBlockHitResult, FriendlyByteBuf::writeBlockHitResult); 49 | } 50 | 51 | public static void readObject(Object obj, FriendlyByteBuf buf) { 52 | try { 53 | Class clazz = obj.getClass(); 54 | Field[] clFields = getClassFields(clazz); 55 | for(Field f : clFields) { 56 | Class type = f.getType(); 57 | if(acceptField(f, type)) 58 | readField(obj, f, type, buf); 59 | } 60 | } catch(Exception e) { 61 | throw new RuntimeException("Error at reading message " + obj, e); 62 | } 63 | } 64 | 65 | public static void writeObject(Object obj, FriendlyByteBuf buf) { 66 | try { 67 | Class clazz = obj.getClass(); 68 | Field[] clFields = getClassFields(clazz); 69 | for(Field f : clFields) { 70 | Class type = f.getType(); 71 | if(acceptField(f, type)) 72 | writeField(obj, f, type, buf); 73 | } 74 | } catch(Exception e) { 75 | throw new RuntimeException("Error at writing message " + obj, e); 76 | } 77 | } 78 | 79 | private static Field[] getClassFields(Class clazz) { 80 | if(fieldCache.containsKey(clazz)) 81 | return fieldCache.get(clazz); 82 | else { 83 | Field[] fields = clazz.getFields(); 84 | Arrays.sort(fields, Comparator.comparing(Field::getName)); 85 | fieldCache.put(clazz, fields); 86 | return fields; 87 | } 88 | } 89 | 90 | private static void writeField(Object obj, Field f, Class clazz, FriendlyByteBuf buf) throws IllegalArgumentException, IllegalAccessException { 91 | Pair handler = getHandler(clazz); 92 | handler.getRight().write(buf, f, f.get(obj)); 93 | } 94 | 95 | private static void readField(Object obj, Field f, Class clazz, FriendlyByteBuf buf) throws IllegalArgumentException, IllegalAccessException { 96 | Pair handler = getHandler(clazz); 97 | f.set(obj, handler.getLeft().read(buf, f)); 98 | } 99 | 100 | private static Pair getHandler(Class clazz) { 101 | Pair pair = handlers.get(clazz); 102 | if(pair == null) 103 | throw new RuntimeException("No R/W handler for " + clazz); 104 | return pair; 105 | } 106 | 107 | private static boolean acceptField(Field f, Class type) { 108 | int mods = f.getModifiers(); 109 | if(Modifier.isFinal(mods) || Modifier.isStatic(mods) || Modifier.isTransient(mods)) 110 | return false; 111 | 112 | return handlers.containsKey(type); 113 | } 114 | 115 | private static void mapFunctions(Class type, Function readerLower, BiConsumer writerLower) { 116 | Reader reader = (buf, field) -> readerLower.apply(buf); 117 | Writer writer = (buf, field, t) -> writerLower.accept(buf, t); 118 | mapHandlers(type, reader, writer); 119 | } 120 | 121 | private static void mapWriterFunction(Class type, Reader reader, BiConsumer writerLower) { 122 | Writer writer = (buf, field, t) -> writerLower.accept(buf, t); 123 | mapHandlers(type, reader, writer); 124 | } 125 | 126 | private static void mapReaderFunction(Class type, Function readerLower, Writer writer) { 127 | Reader reader = (buf, field) -> readerLower.apply(buf); 128 | mapHandlers(type, reader, writer); 129 | } 130 | 131 | public static void mapHandlers(Class type, Reader reader, Writer writer) { 132 | Class arrayType = (Class) Array.newInstance(type, 0).getClass(); 133 | 134 | Reader arrayReader = (buf, field) -> { 135 | int count = buf.readInt(); 136 | T[] arr = (T[]) Array.newInstance(type, count); 137 | 138 | for(int i = 0; i < count; i++) 139 | arr[i] = reader.read(buf, field); 140 | 141 | return arr; 142 | }; 143 | 144 | Writer arrayWriter = (buf, field, t) -> { 145 | int count = t.length; 146 | buf.writeInt(count); 147 | 148 | for(int i = 0; i < count; i++) 149 | writer.write(buf, field, t[i]); 150 | }; 151 | 152 | handlers.put(type, Pair.of(reader, writer)); 153 | handlers.put(arrayType, Pair.of(arrayReader, arrayWriter)); 154 | } 155 | 156 | // ================================================================ 157 | // Auxiliary I/O 158 | // ================================================================ 159 | 160 | // Needed because the methods are overloaded 161 | 162 | private static void writeItemStack(FriendlyByteBuf buf, ItemStack stack) { 163 | buf.writeItem(stack); 164 | } 165 | 166 | private static String readString(FriendlyByteBuf buf) { 167 | return buf.readUtf(32767); 168 | } 169 | 170 | private static void writeString(FriendlyByteBuf buf, String string) { 171 | buf.writeUtf(string); 172 | } 173 | 174 | // ================================================================ 175 | // Functional interfaces 176 | // ================================================================ 177 | 178 | public static interface Reader { 179 | public T read(FriendlyByteBuf buf, Field field); 180 | } 181 | 182 | public static interface Writer { 183 | public void write(FriendlyByteBuf buf, Field field, T t); 184 | } 185 | 186 | } 187 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/network/NetworkHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This class was created by . It's distributed as 3 | * part of the Psi Mod. Get the Source Code in github: 4 | * https://github.com/Vazkii/Psi 5 | * 6 | * Psi is Open Source and distributed under the 7 | * Psi License: http://psi.vazkii.us/license.php 8 | * 9 | * File Created @ [11/01/2016, 21:58:25 (GMT)] 10 | */ 11 | package vazkii.arl.network; 12 | 13 | import java.util.function.BiConsumer; 14 | import java.util.function.Function; 15 | import java.util.function.Supplier; 16 | 17 | import net.minecraft.network.FriendlyByteBuf; 18 | import net.minecraft.resources.ResourceLocation; 19 | import net.minecraft.server.level.ServerPlayer; 20 | import net.minecraftforge.network.NetworkDirection; 21 | import net.minecraftforge.network.NetworkEvent; 22 | import net.minecraftforge.network.NetworkRegistry; 23 | import net.minecraftforge.network.simple.SimpleChannel; 24 | 25 | public class NetworkHandler { 26 | 27 | public final SimpleChannel channel; 28 | 29 | private int i = 0; 30 | 31 | public NetworkHandler(String modid, int protocol) { 32 | this(modid, "main", protocol); 33 | } 34 | 35 | public NetworkHandler(String modid, String channelName, int protocol) { 36 | String protocolStr = Integer.toString(protocol); 37 | 38 | channel = NetworkRegistry.ChannelBuilder 39 | .named(new ResourceLocation(modid, channelName)) 40 | .networkProtocolVersion(() -> protocolStr) 41 | .clientAcceptedVersions(protocolStr::equals) 42 | .serverAcceptedVersions(protocolStr::equals) 43 | .simpleChannel(); 44 | } 45 | 46 | public void register(Class clazz, NetworkDirection dir) { 47 | BiConsumer encoder = MessageSerializer::writeObject; 48 | 49 | Function decoder = (buf) -> { 50 | try { 51 | T msg = clazz.getDeclaredConstructor().newInstance(); 52 | MessageSerializer.readObject(msg, buf); 53 | return msg; 54 | } catch (ReflectiveOperationException e) { 55 | throw new RuntimeException(e); 56 | } 57 | }; 58 | 59 | BiConsumer> consumer = (msg, supp) -> { 60 | NetworkEvent.Context context = supp.get(); 61 | if(context.getDirection() != dir) 62 | return; 63 | 64 | context.setPacketHandled(msg.receive(context)); 65 | }; 66 | 67 | channel.registerMessage(i, clazz, encoder, decoder, consumer); 68 | i++; 69 | } 70 | 71 | public void sendToPlayer(IMessage msg, ServerPlayer player) { 72 | channel.sendTo(msg, player.connection.connection, NetworkDirection.PLAY_TO_CLIENT); 73 | } 74 | 75 | public void sendToServer(IMessage msg) { 76 | channel.sendToServer(msg); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/util/ARLClientInitializer.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.util; 2 | 3 | import net.minecraftforge.api.distmarker.Dist; 4 | import net.minecraftforge.client.event.RegisterColorHandlersEvent; 5 | import net.minecraftforge.eventbus.api.SubscribeEvent; 6 | import net.minecraftforge.fml.common.Mod; 7 | import vazkii.arl.AutoRegLib; 8 | 9 | @Mod.EventBusSubscriber(value = Dist.CLIENT, modid = AutoRegLib.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) 10 | public class ARLClientInitializer { 11 | @SubscribeEvent 12 | public static void registerBlockColors(RegisterColorHandlersEvent.Block evt) { 13 | RegistryHelper.submitBlockColors(evt.getBlockColors()::register); 14 | } 15 | 16 | @SubscribeEvent 17 | public static void registerItemColors(RegisterColorHandlersEvent.Item evt) { 18 | RegistryHelper.submitItemColors(evt.getItemColors()::register); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/util/ClientTicker.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.util; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.screens.Screen; 5 | import net.minecraftforge.api.distmarker.Dist; 6 | import net.minecraftforge.api.distmarker.OnlyIn; 7 | import net.minecraftforge.event.TickEvent.ClientTickEvent; 8 | import net.minecraftforge.event.TickEvent.Phase; 9 | import net.minecraftforge.event.TickEvent.RenderTickEvent; 10 | import net.minecraftforge.eventbus.api.SubscribeEvent; 11 | import net.minecraftforge.fml.common.Mod; 12 | import vazkii.arl.AutoRegLib; 13 | 14 | @Mod.EventBusSubscriber(value = Dist.CLIENT, modid = AutoRegLib.MOD_ID) 15 | public final class ClientTicker { 16 | 17 | public static int ticksInGame = 0; 18 | public static float partialTicks = 0; 19 | public static float delta = 0; 20 | public static float total = 0; 21 | 22 | @OnlyIn(Dist.CLIENT) 23 | private static void calcDelta() { 24 | float oldTotal = total; 25 | total = ticksInGame + partialTicks; 26 | delta = total - oldTotal; 27 | } 28 | 29 | @SubscribeEvent 30 | @OnlyIn(Dist.CLIENT) 31 | public static void renderTick(RenderTickEvent event) { 32 | if(event.phase == Phase.START) 33 | partialTicks = event.renderTickTime; 34 | else calcDelta(); 35 | } 36 | 37 | @SubscribeEvent 38 | @OnlyIn(Dist.CLIENT) 39 | public static void clientTickEnd(ClientTickEvent event) { 40 | if(event.phase == Phase.END) { 41 | Screen gui = Minecraft.getInstance().screen; 42 | if(gui == null || !gui.isPauseScreen()) { 43 | ticksInGame++; 44 | partialTicks = 0; 45 | } 46 | 47 | calcDelta(); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/util/CreativeTabHandler.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.util; 2 | 3 | import com.google.common.collect.HashMultimap; 4 | import com.google.common.collect.Multimap; 5 | 6 | import net.minecraft.world.item.CreativeModeTab; 7 | import net.minecraft.world.item.Item; 8 | import net.minecraft.world.level.ItemLike; 9 | import net.minecraftforge.event.CreativeModeTabEvent; 10 | import net.minecraftforge.eventbus.api.SubscribeEvent; 11 | import net.minecraftforge.fml.common.Mod; 12 | import net.minecraftforge.fml.common.Mod.EventBusSubscriber; 13 | import vazkii.arl.AutoRegLib; 14 | import vazkii.arl.interf.ICreativeExtras; 15 | 16 | @EventBusSubscriber(modid = AutoRegLib.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) 17 | public class CreativeTabHandler { 18 | 19 | protected static Multimap itemsPerCreativeTab = HashMultimap.create(); 20 | 21 | @SubscribeEvent 22 | public static void buildContents(CreativeModeTabEvent.BuildContents event) { 23 | CreativeModeTab tab = event.getTab(); 24 | if(itemsPerCreativeTab.containsKey(tab)) 25 | for(ItemLike il : itemsPerCreativeTab.get(tab)) { 26 | Item item = il.asItem(); 27 | 28 | if(item instanceof ICreativeExtras extras && !extras.canAddToCreativeTab(tab)) 29 | continue; 30 | 31 | event.accept(item); 32 | 33 | if(item instanceof ICreativeExtras extras) 34 | extras.addCreativeModeExtras(tab, event); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/util/InventoryIIH.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.util; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | import net.minecraft.world.item.ItemStack; 6 | import net.minecraftforge.common.util.LazyOptional; 7 | import net.minecraftforge.items.CapabilityItemHandler; 8 | import net.minecraftforge.items.IItemHandler; 9 | import net.minecraftforge.items.IItemHandlerModifiable; 10 | 11 | public class InventoryIIH implements IItemHandlerModifiable { 12 | 13 | private final IItemHandlerModifiable iih; 14 | final ItemStack stack; 15 | 16 | public InventoryIIH(ItemStack stack) { 17 | this.stack = stack; 18 | LazyOptional opt = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); 19 | 20 | if(opt.isPresent()) { 21 | IItemHandler handler = opt.orElse(null); 22 | if(handler instanceof IItemHandlerModifiable) 23 | iih = (IItemHandlerModifiable) handler; 24 | else iih = null; 25 | } else iih = null; 26 | 27 | if(iih == null) 28 | throw new RuntimeException("Can't load InventoryIIH without a proper IItemHandlerModifiable"); 29 | } 30 | 31 | @Override 32 | public void setStackInSlot(int slot, @Nonnull ItemStack stack) { 33 | iih.setStackInSlot(slot, stack); 34 | } 35 | 36 | @Override 37 | public int getSlots() { 38 | return iih.getSlots(); 39 | } 40 | 41 | @Nonnull 42 | @Override 43 | public ItemStack getStackInSlot(int slot) { 44 | return iih.getStackInSlot(slot); 45 | } 46 | 47 | @Nonnull 48 | @Override 49 | public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { 50 | return iih.insertItem(slot, stack, simulate); 51 | } 52 | 53 | @Nonnull 54 | @Override 55 | public ItemStack extractItem(int slot, int amount, boolean simulate) { 56 | return iih.extractItem(slot, amount, simulate); 57 | } 58 | 59 | @Override 60 | public int getSlotLimit(int slot) { 61 | return iih.getSlotLimit(slot); 62 | } 63 | 64 | @Override 65 | public boolean isItemValid(int slot, ItemStack stack) { 66 | return iih.isItemValid(slot, stack); 67 | } 68 | } -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/util/ItemNBTHelper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This class was created by . It's distributed as 3 | * part of the ThaumicTinkerer Mod. 4 | * 5 | * ThaumicTinkerer is a Derivative Work on Thaumcraft 4. 6 | * Thaumcraft 4 (c) Azanor 2012 7 | * (http://www.minecraftforum.net/topic/1585216-) 8 | * 9 | * File Created @ [8 Sep 2013, 19:36:25 (GMT)] 10 | */ 11 | package vazkii.arl.util; 12 | 13 | import net.minecraft.world.item.ItemStack; 14 | import net.minecraft.nbt.CompoundTag; 15 | import net.minecraft.nbt.ListTag; 16 | 17 | public final class ItemNBTHelper { 18 | 19 | /** Checks if an ItemStack has a Tag Compound **/ 20 | public static boolean detectNBT(ItemStack stack) { 21 | return stack.hasTag(); 22 | } 23 | 24 | /** Tries to initialize an NBT Tag Compound in an ItemStack, 25 | * this will not do anything if the stack already has a tag 26 | * compound **/ 27 | public static void initNBT(ItemStack stack) { 28 | if(!detectNBT(stack)) 29 | injectNBT(stack, new CompoundTag()); 30 | } 31 | 32 | /** Injects an NBT Tag Compound to an ItemStack, no checks 33 | * are made previously **/ 34 | public static void injectNBT(ItemStack stack, CompoundTag nbt) { 35 | stack.setTag(nbt); 36 | } 37 | 38 | /** Gets the CompoundNBT in an ItemStack. Tries to init it 39 | * previously in case there isn't one present **/ 40 | public static CompoundTag getNBT(ItemStack stack) { 41 | initNBT(stack); 42 | return stack.getTag(); 43 | } 44 | 45 | // SETTERS /////////////////////////////////////////////////////////////////// 46 | 47 | public static void setBoolean(ItemStack stack, String tag, boolean b) { 48 | getNBT(stack).putBoolean(tag, b); 49 | } 50 | 51 | public static void setByte(ItemStack stack, String tag, byte b) { 52 | getNBT(stack).putByte(tag, b); 53 | } 54 | 55 | public static void setShort(ItemStack stack, String tag, short s) { 56 | getNBT(stack).putShort(tag, s); 57 | } 58 | 59 | public static void setInt(ItemStack stack, String tag, int i) { 60 | getNBT(stack).putInt(tag, i); 61 | } 62 | 63 | public static void setLong(ItemStack stack, String tag, long l) { 64 | getNBT(stack).putLong(tag, l); 65 | } 66 | 67 | public static void setFloat(ItemStack stack, String tag, float f) { 68 | getNBT(stack).putFloat(tag, f); 69 | } 70 | 71 | public static void setDouble(ItemStack stack, String tag, double d) { 72 | getNBT(stack).putDouble(tag, d); 73 | } 74 | 75 | public static void setCompound(ItemStack stack, String tag, CompoundTag cmp) { 76 | if(!tag.equalsIgnoreCase("ench")) // not override the enchantments 77 | getNBT(stack).put(tag, cmp); 78 | } 79 | 80 | public static void setString(ItemStack stack, String tag, String s) { 81 | getNBT(stack).putString(tag, s); 82 | } 83 | 84 | public static void setList(ItemStack stack, String tag, ListTag list) { 85 | getNBT(stack).put(tag, list); 86 | } 87 | 88 | // GETTERS /////////////////////////////////////////////////////////////////// 89 | 90 | 91 | public static boolean verifyExistence(ItemStack stack, String tag) { 92 | return !stack.isEmpty() && detectNBT(stack) && getNBT(stack).contains(tag); 93 | } 94 | 95 | @Deprecated 96 | public static boolean verifyExistance(ItemStack stack, String tag) { 97 | return verifyExistence(stack, tag); 98 | } 99 | 100 | public static boolean getBoolean(ItemStack stack, String tag, boolean defaultExpected) { 101 | return verifyExistence(stack, tag) ? getNBT(stack).getBoolean(tag) : defaultExpected; 102 | } 103 | 104 | public static byte getByte(ItemStack stack, String tag, byte defaultExpected) { 105 | return verifyExistence(stack, tag) ? getNBT(stack).getByte(tag) : defaultExpected; 106 | } 107 | 108 | public static short getShort(ItemStack stack, String tag, short defaultExpected) { 109 | return verifyExistence(stack, tag) ? getNBT(stack).getShort(tag) : defaultExpected; 110 | } 111 | 112 | public static int getInt(ItemStack stack, String tag, int defaultExpected) { 113 | return verifyExistence(stack, tag) ? getNBT(stack).getInt(tag) : defaultExpected; 114 | } 115 | 116 | public static long getLong(ItemStack stack, String tag, long defaultExpected) { 117 | return verifyExistence(stack, tag) ? getNBT(stack).getLong(tag) : defaultExpected; 118 | } 119 | 120 | public static float getFloat(ItemStack stack, String tag, float defaultExpected) { 121 | return verifyExistence(stack, tag) ? getNBT(stack).getFloat(tag) : defaultExpected; 122 | } 123 | 124 | public static double getDouble(ItemStack stack, String tag, double defaultExpected) { 125 | return verifyExistence(stack, tag) ? getNBT(stack).getDouble(tag) : defaultExpected; 126 | } 127 | 128 | /** If nullifyOnFail is true it'll return null if it doesn't find any 129 | * compounds, otherwise it'll return a new one. **/ 130 | public static CompoundTag getCompound(ItemStack stack, String tag, boolean nullifyOnFail) { 131 | return verifyExistence(stack, tag) ? getNBT(stack).getCompound(tag) : nullifyOnFail ? null : new CompoundTag(); 132 | } 133 | 134 | public static String getString(ItemStack stack, String tag, String defaultExpected) { 135 | return verifyExistence(stack, tag) ? getNBT(stack).getString(tag) : defaultExpected; 136 | } 137 | 138 | public static ListTag getList(ItemStack stack, String tag, int objtype, boolean nullifyOnFail) { 139 | return verifyExistence(stack, tag) ? getNBT(stack).getList(tag, objtype) : nullifyOnFail ? null : new ListTag(); 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/util/RegistryHelper.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.util; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Collection; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.Queue; 8 | import java.util.function.BiConsumer; 9 | import java.util.function.Supplier; 10 | 11 | import com.google.common.collect.ArrayListMultimap; 12 | import com.mojang.datafixers.util.Pair; 13 | 14 | import net.minecraft.client.color.block.BlockColor; 15 | import net.minecraft.client.color.item.ItemColor; 16 | import net.minecraft.core.Registry; 17 | import net.minecraft.resources.ResourceKey; 18 | import net.minecraft.resources.ResourceLocation; 19 | import net.minecraft.world.item.BlockItem; 20 | import net.minecraft.world.item.CreativeModeTab; 21 | import net.minecraft.world.item.Item; 22 | import net.minecraft.world.level.ItemLike; 23 | import net.minecraft.world.level.block.Block; 24 | import net.minecraftforge.eventbus.api.SubscribeEvent; 25 | import net.minecraftforge.fml.ModLoadingContext; 26 | import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 27 | import net.minecraftforge.registries.ForgeRegistries; 28 | import net.minecraftforge.registries.GameData; 29 | import net.minecraftforge.registries.IForgeRegistry; 30 | import net.minecraftforge.registries.RegisterEvent; 31 | import vazkii.arl.AutoRegLib; 32 | import vazkii.arl.interf.IBlockColorProvider; 33 | import vazkii.arl.interf.IBlockItemProvider; 34 | import vazkii.arl.interf.IItemColorProvider; 35 | import vazkii.arl.interf.IItemPropertiesFiller; 36 | 37 | public final class RegistryHelper { 38 | 39 | private static final Map modData = new HashMap<>(); 40 | 41 | private static final Queue> itemColors = new ArrayDeque<>(); 42 | private static final Queue> blockColors = new ArrayDeque<>(); 43 | 44 | private static final Map internalNames = new HashMap<>(); 45 | 46 | private static ModData getCurrentModData() { 47 | return getModData(ModLoadingContext.get().getActiveNamespace()); 48 | } 49 | 50 | private static ModData getModData(String modid) { 51 | ModData data = modData.get(modid); 52 | if(data == null) { 53 | data = new ModData(); 54 | modData.put(modid, data); 55 | 56 | FMLJavaModLoadingContext.get().getModEventBus().register(RegistryHelper.class); 57 | } 58 | 59 | return data; 60 | } 61 | 62 | public static ResourceLocation getRegistryName(T obj, IForgeRegistry registry) { 63 | if(internalNames.containsKey(obj)) 64 | return getInternalName(obj); 65 | 66 | return registry.getKey(obj); 67 | } 68 | 69 | public static void setInternalName(Object obj, ResourceLocation name) { 70 | internalNames.put(obj, name); 71 | } 72 | 73 | public static ResourceLocation getInternalName(Object obj) { 74 | return internalNames.get(obj); 75 | } 76 | 77 | @SubscribeEvent 78 | public static void onRegistryEvent(RegisterEvent event) { 79 | getCurrentModData().register(event.getForgeRegistry()); 80 | } 81 | 82 | public static void registerBlock(Block block, String resloc) { 83 | registerBlock(block, resloc, true); 84 | } 85 | 86 | public static void registerBlock(Block block, String resloc, boolean hasBlockItem) { 87 | register(block, resloc, ForgeRegistries.BLOCKS); 88 | 89 | if(hasBlockItem) { 90 | ModData data = getCurrentModData(); 91 | data.defers.put(ForgeRegistries.ITEMS.getRegistryName(), () -> data.createItemBlock(block)); 92 | } 93 | 94 | if(block instanceof IBlockColorProvider) 95 | blockColors.add(Pair.of(block, (IBlockColorProvider) block)); 96 | } 97 | 98 | public static void registerItem(Item item, String resloc) { 99 | register(item, resloc, ForgeRegistries.ITEMS); 100 | 101 | if(item instanceof IItemColorProvider) 102 | itemColors.add(Pair.of(item, (IItemColorProvider) item)); 103 | } 104 | 105 | public static void register(T obj, String resloc, IForgeRegistry registry) { 106 | if(obj == null) 107 | throw new IllegalArgumentException("Can't register null object."); 108 | 109 | setInternalName(obj, GameData.checkPrefix(resloc, false)); 110 | getCurrentModData().defers.put(registry.getRegistryName(), () -> obj); 111 | } 112 | 113 | // public static void register(T obj, ResourceKey> registry) { 114 | // if(obj == null) 115 | // throw new IllegalArgumentException("Can't register null object."); 116 | // if(getInternalName(obj) == null) 117 | // throw new IllegalArgumentException("Can't register object without registry name."); 118 | // 119 | // getCurrentModData().defers.put(registry.location(), () -> obj); 120 | // } 121 | 122 | public static void setCreativeTab(ItemLike itemlike, CreativeModeTab group) { 123 | ResourceLocation res = getInternalName(itemlike); 124 | if(res == null) 125 | throw new IllegalArgumentException("Can't set the creative tab for an ItemLike without a registry name yet"); 126 | 127 | CreativeTabHandler.itemsPerCreativeTab.put(group, itemlike); 128 | } 129 | 130 | public static void submitBlockColors(BiConsumer consumer) { 131 | blockColors.forEach(p -> consumer.accept(p.getSecond().getBlockColor(), p.getFirst())); 132 | blockColors.clear(); 133 | } 134 | 135 | public static void submitItemColors(BiConsumer consumer) { 136 | itemColors.forEach(p -> consumer.accept(p.getSecond().getItemColor(), p.getFirst())); 137 | itemColors.clear(); 138 | } 139 | 140 | private static class ModData { 141 | 142 | private ArrayListMultimap> defers = ArrayListMultimap.create(); 143 | 144 | @SuppressWarnings({ "unchecked" }) 145 | private void register(IForgeRegistry registry) { 146 | ResourceLocation registryRes = registry.getRegistryName(); 147 | 148 | if(defers.containsKey(registryRes)) { 149 | Collection> ourEntries = defers.get(registryRes); 150 | for(Supplier supplier : ourEntries) { 151 | T entry = (T) supplier.get(); 152 | ResourceLocation name = getInternalName(entry); 153 | registry.register(name, entry); 154 | AutoRegLib.LOGGER.debug("Registering to " + registryRes + " - " + name); 155 | } 156 | 157 | defers.removeAll(registryRes); 158 | } 159 | } 160 | 161 | private Item createItemBlock(Block block) { 162 | Item.Properties props = new Item.Properties(); 163 | ResourceLocation registryName = getInternalName(block); 164 | 165 | if(block instanceof IItemPropertiesFiller) 166 | ((IItemPropertiesFiller) block).fillItemProperties(props); 167 | 168 | BlockItem blockitem; 169 | if(block instanceof IBlockItemProvider) 170 | blockitem = ((IBlockItemProvider) block).provideItemBlock(block, props); 171 | else blockitem = new BlockItem(block, props); 172 | 173 | if(block instanceof IItemColorProvider) 174 | itemColors.add(Pair.of(blockitem, (IItemColorProvider) block)); 175 | 176 | setInternalName(blockitem, registryName); 177 | return blockitem; 178 | } 179 | 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/util/RenderHelper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This class was created by . It's distributed as 3 | * part of the Botania Mod. Get the Source Code in github: 4 | * https://github.com/Vazkii/Botania 5 | * 6 | * Botania is Open Source and distributed under the 7 | * Botania License: http://botaniamod.net/license.php 8 | * 9 | * File Created @ [Jan 19, 2014, 5:40:38 PM (GMT)] 10 | */ 11 | package vazkii.arl.util; 12 | 13 | import net.minecraft.client.KeyMapping; 14 | import net.minecraft.client.Minecraft; 15 | import net.minecraft.client.resources.language.I18n; 16 | import net.minecraftforge.api.distmarker.Dist; 17 | import net.minecraftforge.api.distmarker.OnlyIn; 18 | 19 | @OnlyIn(Dist.CLIENT) 20 | public final class RenderHelper { 21 | 22 | public static String getKeyDisplayString(String keyName) { 23 | String key = null; 24 | KeyMapping[] keys = Minecraft.getInstance().options.keyMappings; 25 | for(KeyMapping otherKey : keys) 26 | if(otherKey.getName().equals(keyName)) { 27 | key = otherKey.saveString(); 28 | break; 29 | } 30 | 31 | return I18n.get(key); 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/util/RotationHandler.java: -------------------------------------------------------------------------------- 1 | package vazkii.arl.util; 2 | 3 | import net.minecraft.core.Direction; 4 | import net.minecraft.world.level.block.Rotation; 5 | 6 | public final class RotationHandler { 7 | 8 | private static final Rotation[] FACING_TO_ROTATION = new Rotation[] { 9 | Rotation.NONE, 10 | Rotation.NONE, 11 | Rotation.NONE, 12 | Rotation.CLOCKWISE_180, 13 | Rotation.COUNTERCLOCKWISE_90, 14 | Rotation.CLOCKWISE_90 15 | }; 16 | 17 | public static Direction rotateFacing(Direction facing, Rotation rot) { 18 | return rot.rotate(facing); 19 | } 20 | 21 | public static Direction rotateFacing(Direction facing, Direction rot) { 22 | return rotateFacing(facing, getRotationFromFacing(rot)); 23 | } 24 | 25 | public static Rotation getRotationFromFacing(Direction facing) { 26 | return FACING_TO_ROTATION[facing.ordinal()]; 27 | } 28 | 29 | public static int[] applyRotation(Rotation rot, int x, int z) { 30 | switch(rot) { 31 | case CLOCKWISE_180: return new int[] { -x, -z }; 32 | case CLOCKWISE_90: return new int[] { z, -x }; 33 | case COUNTERCLOCKWISE_90: return new int[] { -z, x }; 34 | default: return new int[] { x, z }; 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/util/TooltipHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This class was created by . It's distributed as 3 | * part of the Psi Mod. Get the Source Code in github: 4 | * https://github.com/Vazkii/Psi 5 | * 6 | * Psi is Open Source and distributed under the 7 | * Psi License: http://psi.vazkii.us/license.php 8 | * 9 | * File Created @ [16/01/2016, 18:30:59 (GMT)] 10 | */ 11 | package vazkii.arl.util; 12 | 13 | import net.minecraft.client.gui.screens.Screen; 14 | import net.minecraft.client.resources.language.I18n; 15 | import net.minecraftforge.api.distmarker.Dist; 16 | import net.minecraftforge.api.distmarker.OnlyIn; 17 | 18 | import java.util.List; 19 | 20 | public final class TooltipHandler { 21 | 22 | @OnlyIn(Dist.CLIENT) 23 | public static void tooltipIfShift(List tooltip, Runnable r) { 24 | if(Screen.hasShiftDown()) 25 | r.run(); 26 | else addToTooltip(tooltip, "arl.misc.shift_for_info"); 27 | } 28 | 29 | @OnlyIn(Dist.CLIENT) 30 | public static void addToTooltip(List tooltip, String s, Object... format) { 31 | s = I18n.get(s).replaceAll("&", "\u00a7"); 32 | 33 | Object[] formatVals = new String[format.length]; 34 | for(int i = 0; i < format.length; i++) 35 | formatVals[i] = I18n.get(format[i].toString()).replaceAll("&", "\u00a7"); 36 | 37 | if(formatVals.length > 0) 38 | s = String.format(s, formatVals); 39 | 40 | tooltip.add(s); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/vazkii/arl/util/VanillaPacketDispatcher.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This class was created by . It's distributed as 3 | * part of the Botania Mod. Get the Source Code in github: 4 | * https://github.com/Vazkii/Botania 5 | * 6 | * Botania is Open Source and distributed under the 7 | * Botania License: http://botaniamod.net/license.php 8 | * 9 | * File Created @ [Apr 9, 2015, 9:38:44 PM (GMT)] 10 | */ 11 | package vazkii.arl.util; 12 | 13 | import net.minecraft.core.BlockPos; 14 | import net.minecraft.network.protocol.Packet; 15 | import net.minecraft.network.protocol.game.ClientGamePacketListener; 16 | import net.minecraft.server.level.ServerLevel; 17 | import net.minecraft.server.level.ServerPlayer; 18 | import net.minecraft.world.entity.player.Player; 19 | import net.minecraft.world.level.Level; 20 | import net.minecraft.world.level.block.entity.BlockEntity; 21 | 22 | public final class VanillaPacketDispatcher { 23 | 24 | public static void dispatchTEToNearbyPlayers(BlockEntity tile) { 25 | Level world = tile.getLevel(); 26 | if(world instanceof ServerLevel) { 27 | Packet packet = tile.getUpdatePacket(); 28 | BlockPos pos = tile.getBlockPos(); 29 | 30 | for(Player player : world.players()) { 31 | if(player instanceof ServerPlayer && pointDistancePlane(player.getX(), player.getZ(), pos.getX(), pos.getZ()) < 64) 32 | ((ServerPlayer) player).connection.send(packet); 33 | } 34 | } 35 | } 36 | 37 | public static void dispatchTEToNearbyPlayers(Level world, BlockPos pos) { 38 | BlockEntity tile = world.getBlockEntity(pos); 39 | if(tile != null) 40 | dispatchTEToNearbyPlayers(tile); 41 | } 42 | 43 | public static float pointDistancePlane(double x1, double y1, double x2, double y2) { 44 | return (float) Math.hypot(x1 - x2, y1 - y2); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | modLoader="javafml" 2 | loaderVersion="[38,)" 3 | issueTrackerURL="https://github.com/Vazkii/AutoRegLib" 4 | license="https://github.com/Vazkii/AutoRegLib/blob/master/README.md" 5 | 6 | [[mods]] 7 | modId="autoreglib" 8 | displayName="AutoRegLib" 9 | version="${file.jarVersion}" 10 | authors="Vazkii" 11 | description='''Automatically item, block, and model registration for mods.''' 12 | -------------------------------------------------------------------------------- /src/main/resources/assets/autoreglib/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "arl.misc.shift_for_info": "&7Hold &bSHIFT&7 for more info", 3 | "arl.misc.right_click_add": "Right-Click to Add" 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/autoreglib/lang/es_ar.json: -------------------------------------------------------------------------------- 1 | { 2 | "arl.misc.shift_for_info": "&7Mantené &bSHIFT&7 para más información", 3 | "arl.misc.right_click_add": "Clic derecho para agregar" 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/autoreglib/lang/es_es.json: -------------------------------------------------------------------------------- 1 | { 2 | "arl.misc.shift_for_info": "&7Mantén &bSHIFT&7 para más información", 3 | "arl.misc.right_click_add": "Clic derecho para agregar" 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/autoreglib/lang/es_mx.json: -------------------------------------------------------------------------------- 1 | { 2 | "arl.misc.shift_for_info": "&7Mantén &bSHIFT&7 para más información", 3 | "arl.misc.right_click_add": "Clic derecho para agregar" 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/autoreglib/lang/fr_fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "arl.misc.shift_for_info": "&7Hold &bSHIFT&7 pour plus d'informations", 3 | "arl.misc.right_click_add": "Clic-droit pour Ajouter" 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/autoreglib/lang/hr_hr.json: -------------------------------------------------------------------------------- 1 | { 2 | "arl.misc.shift_for_info": "&7Zadrži &bSHIFT&7 za više informacija", 3 | "arl.misc.right_click_add": "Desni klik za dodavanje" 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/autoreglib/lang/ko_kr.json: -------------------------------------------------------------------------------- 1 | { 2 | "arl.misc.shift_for_info": "&7SHIFT를 &b누르고 있으면&7 자세한 내용을 볼 수 있습니다.", 3 | "arl.misc.right_click_add": "추가하려면 마우스 오른쪽 단추를 클릭하십시오." 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/autoreglib/lang/pl_pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "arl.misc.shift_for_info": "&7Przytrzymaj &bSHIFT&7 po więcej informacji", 3 | "arl.misc.right_click_add": "Wciśnij PPM aby Dodać" 4 | } -------------------------------------------------------------------------------- /src/main/resources/assets/autoreglib/lang/ru_ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "arl.misc.shift_for_info": "&7Удерживайте &bSHIFT&7 для дополнительной информации", 3 | "arl.misc.right_click_add": "Нажмите ПКМ для добавления" 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "AutoRegLib Resources", 4 | "pack_format": 4, 5 | "_comment": "A pack_format of 4 requires json lang files. Note: we require v4 pack meta for all mods." 6 | } 7 | } 8 | --------------------------------------------------------------------------------