diff --git a/README.md b/README.md index 6513ab85..d7a97450 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ The project is under the All Rights Reserved license, which means that redistrib This rule only applies to the source code, assets are copyrighted and belong to their respective owners (music to qwertygiy, all other assets to me), and cannot be used in other projects without the owner's permission! -If you find a handy method or even an entire class (such as BlockReplaceHelper), I don't mind if you use it in your project (don't copy everything you see though, that's not how you learn to mod). Giving credit is only required if your project has publicly visible source, in that case use javadoc and link back to the original source. +If you find a handy method or even an entire class (such as ~~BlockReplaceHelper~~ NH deleted this class because it was an awful hack), I don't mind if you use it in your project (don't copy everything you see though, that's not how you learn to mod). Giving credit is only required if your project has publicly visible source, in that case use javadoc and link back to the original source. ### I want to modify something in HEE diff --git a/build.gradle b/build.gradle index e57a16f9..8ea289e1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,3 @@ -//version: 1707058017 - plugins { id 'com.gtnewhorizons.gtnhconvention' } diff --git a/dependencies.gradle b/dependencies.gradle index 31be3b53..fe34c88f 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,8 +1,8 @@ // Add your dependencies here dependencies { - implementation('com.github.GTNewHorizons:GTNHLib:0.6.15:dev') - implementation('com.github.GTNewHorizons:NotEnoughItems:2.7.30-GTNH:dev') + implementation('com.github.GTNewHorizons:GTNHLib:0.6.21:dev') + implementation('com.github.GTNewHorizons:NotEnoughItems:2.7.40-GTNH:dev') compileOnly('thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev') compileOnly('com.github.GTNewHorizons:Mobs-Info:0.5.2-GTNH:dev') diff --git a/gradle.properties b/gradle.properties index abb3bd0b..7c732938 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ modId = HardcoreEnderExpansion modGroup = chylex.hee # Whether to use modGroup as the maven publishing group. -# Due to a history of using JitPack, the default is com.github.GTNewHorizons for all mods. +# When false, com.github.GTNewHorizons is used. useModGroupForPublishing = false # Updates your build.gradle and settings.gradle automatically whenever an update is available. @@ -41,11 +41,11 @@ developmentEnvironmentUserName = "Developer" # Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8. # See https://github.com/bsideup/jabel for details on how this works. -enableModernJavaSyntax = false +enableModernJavaSyntax = true # Enables injecting missing generics into the decompiled source code for a better coding experience. # Turns most publicly visible List, Map, etc. into proper List, Map types. -enableGenericInjection = false +enableGenericInjection = true # Generate a class with a String field for the mod version named as defined below. # If generateGradleTokenClass is empty or not missing, no such class will be generated. @@ -83,7 +83,7 @@ apiPackage = accessTransformersFile = # Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled! -usesMixins = false +usesMixins = true # Set to a non-empty string to configure mixins in a separate source set under src/VALUE, instead of src/main. # This can speed up compile times thanks to not running the mixin annotation processor on all input sources. @@ -97,12 +97,12 @@ usesMixinDebug = false mixinPlugin = # Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail! -mixinsPackage = +mixinsPackage = mixins # Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin! # This parameter is for legacy compatibility only # Example value: (coreModClass = asm.FMLPlugin) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.asm.FMLPlugin -coreModClass = +coreModClass = HEECore # If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class # that is annotated with @Mod) you want this to be true. When in doubt: leave it on false! diff --git a/settings.gradle b/settings.gradle index 40fb369e..ff436f2c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,7 +17,7 @@ pluginManagement { } plugins { - id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.37' + id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.38' } diff --git a/src/main/java/chylex/hee/HEECore.java b/src/main/java/chylex/hee/HEECore.java new file mode 100644 index 00000000..196131e0 --- /dev/null +++ b/src/main/java/chylex/hee/HEECore.java @@ -0,0 +1,47 @@ +package chylex.hee; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.gtnewhorizon.gtnhlib.mixin.IMixins; +import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader; + +import chylex.hee.mixins.Mixins; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; + +public class HEECore implements IFMLLoadingPlugin, IEarlyMixinLoader { + + @Override + public String getMixinConfig() { + return "mixins.HardcoreEnderExpansion.early.json"; + } + + @Override + public List getMixins(Set loadedCoreMods) { + return IMixins.getEarlyMixins(Mixins.class, loadedCoreMods); + } + + @Override + public String[] getASMTransformerClass() { + return null; + } + + @Override + public String getModContainerClass() { + return null; + } + + @Override + public String getSetupClass() { + return null; + } + + @Override + public void injectData(Map data) {} + + @Override + public String getAccessTransformerClass() { + return null; + } +} diff --git a/src/main/java/chylex/hee/block/BlockReplaceHelper.java b/src/main/java/chylex/hee/block/BlockReplaceHelper.java deleted file mode 100644 index 401b3531..00000000 --- a/src/main/java/chylex/hee/block/BlockReplaceHelper.java +++ /dev/null @@ -1,108 +0,0 @@ -package chylex.hee.block; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Map; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.util.ObjectIntIdentityMap; - -import com.gtnewhorizon.gtnhlib.reflect.Fields; - -import chylex.hee.system.logging.Log; -import chylex.hee.system.logging.Stopwatch; -import chylex.hee.system.util.ReflectionUtils; -import cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry; -import cpw.mods.fml.common.registry.GameData; - -public class BlockReplaceHelper { - - public static void replaceBlock(Block toReplace, Block replacement) { - Stopwatch.time("BlockReplace"); - - Class[] classTest = new Class[4]; - Exception exception = null; - - try { - final Fields.ClassFields blocksFields = Fields.ofClass(Blocks.class); - for (Field blockField : Blocks.class.getFields()) { - if (Block.class.isAssignableFrom(blockField.getType())) { - Block block = (Block) blockField.get(null); - - if (block == toReplace) { - final Fields.ClassFields.Field fieldAccessor = blocksFields - .getUntypedField(Fields.LookupType.PUBLIC, blockField.getName()); - String registryName = Block.blockRegistry.getNameForObject(block); - int id = Block.getIdFromBlock(block); - - Log.debug("Replacing block - $0/$1", id, registryName); - - ReflectionUtils.setFieldValue( - ((ItemBlock) Item.getItemFromBlock(block)), - "field_150939_a", - replacement); - - FMLControlledNamespacedRegistry registryBlocks = GameData.getBlockRegistry(); - Log.debug("Got BlockRegistry."); - - Map registryObjects = ReflectionUtils.getFieldValue(registryBlocks, "registryObjects"); - Log.debug("Got registryObjects."); - ObjectIntIdentityMap underlyingIntegerMap = ReflectionUtils - .getFieldValue(registryBlocks, "underlyingIntegerMap"); - Log.debug("Got underlyingIntegerMap."); - registryObjects.put(registryName, replacement); - Log.debug( - "Put " + replacement.getUnlocalizedName() - + " in registryObjects with key: " - + registryName); - underlyingIntegerMap.func_148746_a(replacement, id); // OBFUSCATED put object - Log.debug("OBFUSCATED put object - underlyingIntegerMap"); - ReflectionUtils.setFieldValue(registryBlocks, "registryObjects", registryObjects); - Log.debug("Set new value for registryObjects: registryObjects. For object registryBlocks."); - ReflectionUtils.setFieldValue(registryBlocks, "underlyingIntegerMap", underlyingIntegerMap); - Log.debug( - "Set new value for underlyingIntegerMap: underlyingIntegerMap. For object registryBlocks."); - - Log.debug("Made " + blockField.getName() + " accessible."); - fieldAccessor.setValue(null, replacement); - Log.debug("Set " + blockField.getName() + " to " + replacement.getUnlocalizedName() + "."); - - Method delegateNameMethod = replacement.delegate.getClass() - .getDeclaredMethod("setName", String.class); - delegateNameMethod.setAccessible(true); - Log.debug("Made " + delegateNameMethod.getName() + " accessible."); - delegateNameMethod.invoke(replacement.delegate, toReplace.delegate.name()); - Log.debug("Invoked " + delegateNameMethod.getName() + "."); - - classTest[0] = blockField.get(null).getClass(); - classTest[1] = Block.blockRegistry.getObjectById(id).getClass(); - classTest[2] = ((ItemBlock) Item.getItemFromBlock(replacement)).field_150939_a.getClass(); - } - } - } - } catch (Exception e) { - exception = e; - } - - Stopwatch.finish("BlockReplace"); - - Log.debug("Check field: $0", classTest[0]); - Log.debug("Check block registry: $0", classTest[1]); - Log.debug("Check item: $0", classTest[2]); - - if (classTest[0] != classTest[1] || classTest[0] != classTest[2] || classTest[0] == null) { - throw new RuntimeException( - "HardcoreEnderExpansion was unable to replace block " + toReplace.getUnlocalizedName() - + "! Debug info to report: " - + classTest[0] - + "," - + classTest[1] - + "," - + classTest[2], - exception); - } - } -} diff --git a/src/main/java/chylex/hee/entity/block/EntityBlockTempleDragonEgg.java b/src/main/java/chylex/hee/entity/block/EntityBlockTempleDragonEgg.java index 5976fc30..2e47b296 100644 --- a/src/main/java/chylex/hee/entity/block/EntityBlockTempleDragonEgg.java +++ b/src/main/java/chylex/hee/entity/block/EntityBlockTempleDragonEgg.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import net.minecraft.block.Block; import net.minecraft.entity.item.EntityFallingBlock; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.world.World; @@ -104,9 +105,9 @@ public class EntityBlockTempleDragonEgg extends EntityFallingBlock { } if (deltaY > 6D) { - for (EntityPlayerMP player : new ArrayList(worldObj.playerEntities)) { + for (EntityPlayer player : new ArrayList<>(worldObj.playerEntities)) { if (player.ridingEntity != null) player.mountEntity(null); - DragonUtil.teleportToOverworld(player); + DragonUtil.teleportToOverworld((EntityPlayerMP) player); } TempleEvents.destroyWorld(); diff --git a/src/main/java/chylex/hee/entity/mob/EntityMobHomelandEnderman.java b/src/main/java/chylex/hee/entity/mob/EntityMobHomelandEnderman.java index 5cf9485d..b096f78e 100644 --- a/src/main/java/chylex/hee/entity/mob/EntityMobHomelandEnderman.java +++ b/src/main/java/chylex/hee/entity/mob/EntityMobHomelandEnderman.java @@ -16,7 +16,6 @@ import net.minecraft.entity.item.EntityTNTPrimed; import net.minecraft.entity.monster.EntityEnderman; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; @@ -755,9 +754,9 @@ public class EntityMobHomelandEnderman extends EntityMob implements IEndermanRen protected Entity findPlayerToAttack() { if (worldObj.isRemote) return null; - List players = worldObj.playerEntities; + List players = worldObj.playerEntities; - for (EntityPlayerMP player : players) { + for (EntityPlayer player : players) { if (!player.capabilities.disableDamage && getDistanceSqToEntity(player) <= 4096D) { if (isPlayerStaringIntoEyes(player)) { if (!shouldActHostile(player) && teleportRandomly(10D)) return null; diff --git a/src/main/java/chylex/hee/init/BlockList.java b/src/main/java/chylex/hee/init/BlockList.java index 9ee7754e..0d511ad8 100644 --- a/src/main/java/chylex/hee/init/BlockList.java +++ b/src/main/java/chylex/hee/init/BlockList.java @@ -26,7 +26,6 @@ import chylex.hee.block.BlockCustomSpawner; import chylex.hee.block.BlockDeathFlower; import chylex.hee.block.BlockDeathFlowerPot; import chylex.hee.block.BlockDecompositionTable; -import chylex.hee.block.BlockDragonEggCustom; import chylex.hee.block.BlockDungeonPuzzle; import chylex.hee.block.BlockEndPowderOre; import chylex.hee.block.BlockEnderGoo; @@ -48,7 +47,6 @@ import chylex.hee.block.BlockObsidianSpecial; import chylex.hee.block.BlockPersegrit; import chylex.hee.block.BlockRavagedBrick; import chylex.hee.block.BlockRavagedBrickSmooth; -import chylex.hee.block.BlockReplaceHelper; import chylex.hee.block.BlockSpecialEffects; import chylex.hee.block.BlockSphalerite; import chylex.hee.block.BlockSpookyLeaves; @@ -426,8 +424,6 @@ public final class BlockList { } public static void registerBlocks() { - BlockReplaceHelper.replaceBlock(Blocks.dragon_egg, new BlockDragonEggCustom()); - for (Entry entry : BlockList.blocks.entrySet()) { GameRegistryUtil.registerBlock(entry.getValue(), entry.getKey(), itemBlocks.get(entry.getKey())); } diff --git a/src/main/java/chylex/hee/mechanics/misc/TempleEvents.java b/src/main/java/chylex/hee/mechanics/misc/TempleEvents.java index ee4a6c54..596aaecf 100644 --- a/src/main/java/chylex/hee/mechanics/misc/TempleEvents.java +++ b/src/main/java/chylex/hee/mechanics/misc/TempleEvents.java @@ -116,11 +116,11 @@ public final class TempleEvents { if (world == null) setStage(DestroyStage.DELETE); else if (world.playerEntities.isEmpty()) setStage(DestroyStage.UNLOAD); else { - List players = new ArrayList<>(world.playerEntities); + List players = new ArrayList<>(world.playerEntities); - for (EntityPlayerMP player : players) { + for (EntityPlayer player : players) { if (player.ridingEntity != null) player.mountEntity(null); - DragonUtil.teleportToOverworld(player); + DragonUtil.teleportToOverworld((EntityPlayerMP) player); } } } else if (stage == DestroyStage.UNLOAD) { diff --git a/src/main/java/chylex/hee/mixins/Mixins.java b/src/main/java/chylex/hee/mixins/Mixins.java new file mode 100644 index 00000000..6e14e96d --- /dev/null +++ b/src/main/java/chylex/hee/mixins/Mixins.java @@ -0,0 +1,70 @@ +package chylex.hee.mixins; + +import static com.gtnewhorizon.gtnhlib.mixin.TargetedMod.VANILLA; + +import java.util.List; +import java.util.function.Supplier; + +import com.gtnewhorizon.gtnhlib.mixin.IMixins; +import com.gtnewhorizon.gtnhlib.mixin.ITargetedMod; +import com.gtnewhorizon.gtnhlib.mixin.MixinBuilder; +import com.gtnewhorizon.gtnhlib.mixin.Phase; +import com.gtnewhorizon.gtnhlib.mixin.Side; + +public enum Mixins implements IMixins { + + REPLACE_DRAGON_EGG(new MixinBuilder("Replaces the dragon egg").setApplyIf(() -> true) + .addMixinClasses("minecraft.MixinBlock").addTargetedMod(VANILLA).setSide(Side.BOTH).setPhase(Phase.EARLY)); + + private final List mixinClasses; + private final List targetedMods; + private final List excludedMods; + private final Supplier applyIf; + private final Phase phase; + private final Side side; + + Mixins(MixinBuilder builder) { + mixinClasses = builder.mixinClasses; + targetedMods = builder.targetedMods; + excludedMods = builder.excludedMods; + applyIf = builder.applyIf; + phase = builder.phase; + side = builder.side; + + if (mixinClasses.isEmpty()) throw new RuntimeException("No mixin class specified for Mixin : " + name()); + if (targetedMods.isEmpty()) throw new RuntimeException("No targeted mods specified for Mixin : " + name()); + if (applyIf == null) throw new RuntimeException("No ApplyIf function specified for Mixin : " + name()); + if (phase == null) throw new RuntimeException("No Phase specified for Mixin : " + name()); + if (side == null) throw new RuntimeException("No Side function specified for Mixin : " + name()); + } + + @Override + public List getMixinClasses() { + return mixinClasses; + } + + @Override + public Supplier getApplyIf() { + return applyIf; + } + + @Override + public Phase getPhase() { + return phase; + } + + @Override + public Side getSide() { + return side; + } + + @Override + public List getTargetedMods() { + return targetedMods; + } + + @Override + public List getExcludedMods() { + return excludedMods; + } +} diff --git a/src/main/java/chylex/hee/mixins/early/minecraft/MixinBlock.java b/src/main/java/chylex/hee/mixins/early/minecraft/MixinBlock.java new file mode 100644 index 00000000..2b770ca1 --- /dev/null +++ b/src/main/java/chylex/hee/mixins/early/minecraft/MixinBlock.java @@ -0,0 +1,26 @@ +package chylex.hee.mixins.early.minecraft; + +import net.minecraft.block.Block; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.Slice; + +import chylex.hee.block.BlockDragonEggCustom; + +@Mixin(Block.class) +public class MixinBlock { + + @ModifyArg( + method = "registerBlocks", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/util/RegistryNamespaced;addObject(ILjava/lang/String;Ljava/lang/Object;)V"), + slice = @Slice( + from = @At(value = "CONSTANT", args = "intValue=122"), + to = @At(value = "CONSTANT", args = "intValue=123"))) + private static Object hee$replaceDragonEgg(Object block) { + return new BlockDragonEggCustom(); + } +} diff --git a/src/main/java/chylex/hee/proxy/NotificationCommonProxy.java b/src/main/java/chylex/hee/proxy/NotificationCommonProxy.java index 1298faba..17052711 100644 --- a/src/main/java/chylex/hee/proxy/NotificationCommonProxy.java +++ b/src/main/java/chylex/hee/proxy/NotificationCommonProxy.java @@ -5,6 +5,7 @@ import java.util.Collections; import java.util.List; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; import net.minecraft.server.management.ServerConfigurationManager; import net.minecraftforge.common.ForgeHooks; @@ -53,7 +54,7 @@ public class NotificationCommonProxy { if (manager == null) return; boolean delivered = false; - List players = manager.playerEntityList; + List players = manager.playerEntityList; for (EntityPlayer player : players) { if (manager.func_152596_g(player.getGameProfile())) { diff --git a/src/main/resources/mixins.HardcoreEnderExpansion.early.json b/src/main/resources/mixins.HardcoreEnderExpansion.early.json new file mode 100644 index 00000000..15f85303 --- /dev/null +++ b/src/main/resources/mixins.HardcoreEnderExpansion.early.json @@ -0,0 +1,8 @@ +{ + "required": true, + "minVersion": "0.8.3-GTNH", + "package": "chylex.hee.mixins.early", + "refmap": "mixins.HardcoreEnderExpansion.refmap.json", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8" +} \ No newline at end of file diff --git a/src/main/resources/mixins.HardcoreEnderExpansion.json b/src/main/resources/mixins.HardcoreEnderExpansion.json new file mode 100644 index 00000000..b5c9fced --- /dev/null +++ b/src/main/resources/mixins.HardcoreEnderExpansion.json @@ -0,0 +1,7 @@ +{ + "required": true, + "minVersion": "0.8.3-GTNH", + "refmap": "mixins.HardcoreEnderExpansion.refmap.json", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8" +} \ No newline at end of file