diff --git a/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java b/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java index 3fd5dbab..4afd6ed8 100644 --- a/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java +++ b/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java @@ -4,16 +4,20 @@ import com.mitchej123.hodgepodge.client.HodgepodgeClient; import com.mitchej123.hodgepodge.commands.DebugCommand; +import com.mitchej123.hodgepodge.config.TweaksConfig; import com.mitchej123.hodgepodge.net.NetworkHandler; import com.mitchej123.hodgepodge.util.AnchorAlarm; +import com.mitchej123.hodgepodge.util.StatHandler; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.ICrashCallable; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLModIdMappingEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.event.FMLServerStartedEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.network.NetworkCheckHandler; import cpw.mods.fml.common.versioning.ArtifactVersion; @@ -90,6 +94,20 @@ public void onServerStarting(FMLServerStartingEvent aEvent) { EVENT_HANDLER.setAidTriggerDisabled(false); } + @EventHandler + public void onServerStarted(FMLServerStartedEvent event) { + if (TweaksConfig.addModEntityStats) { + StatHandler.addEntityStats(); + } + } + + @EventHandler + public void onModIdMapping(FMLModIdMappingEvent event) { + if (TweaksConfig.addModItemStats) { + StatHandler.remap(event.remappedIds); + } + } + /** * Block any clients older than 2.5.36 from joining servers to ensure the fastBlockPlacingDisableServerSide setting * is respected diff --git a/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java b/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java index 11ffc738..9fcf3270 100644 --- a/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java +++ b/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java @@ -158,6 +158,20 @@ public class TweaksConfig { @Config.RequiresMcRestart public static boolean unbindKeybindsByDefault; + @Config.Comment("Adds non-vanilla blocks/items to the statistics") + @Config.DefaultBoolean(true) + @Config.RequiresMcRestart + public static boolean addModItemStats; + + @Config.Comment("Adds non-vanilla entities to the statistics") + @Config.DefaultBoolean(true) + @Config.RequiresMcRestart + public static boolean addModEntityStats; + + @Config.Comment("Sort Mob stats lexicographically (Requires addModEntityStats)") + @Config.DefaultBoolean(true) + public static boolean sortEntityStats; + // Automagy @Config.Comment("Implement container for thirsty tank") diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java b/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java index c5dc1804..d3cdbf2c 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java @@ -200,8 +200,8 @@ public enum Mixins { FIX_BOGUS_INTEGRATED_SERVER_NPE(new Builder("Fix bogus FMLProxyPacket NPEs on integrated server crashes") .setPhase(Phase.EARLY).setSide(Side.BOTH) .addMixinClasses( - "forge.MixinFMLProxyPacket", - "forge.MixinNetworkDispatcher", + "fml.MixinFMLProxyPacket", + "fml.MixinNetworkDispatcher", "minecraft.NetworkManagerAccessor") .setApplyIf(() -> FixesConfig.fixBogusIntegratedServerNPEs).addTargetedMod(TargetedMod.VANILLA)), @@ -277,7 +277,7 @@ public enum Mixins { .setPhase(Phase.EARLY).addTargetedMod(TargetedMod.VANILLA).setApplyIf(() -> TweaksConfig.enhanceNightVision) .addMixinClasses("minecraft.MixinEntityRenderer_EnhanceNightVision")), OPTIMIZE_ASMDATATABLE_INDEX(new Builder("Optimize ASM DataTable Index").setPhase(Phase.EARLY).setSide(Side.BOTH) - .addMixinClasses("forge.MixinASMDataTable").setApplyIf(() -> SpeedupsConfig.optimizeASMDataTable) + .addMixinClasses("fml.MixinASMDataTable").setApplyIf(() -> SpeedupsConfig.optimizeASMDataTable) .addTargetedMod(TargetedMod.VANILLA)), SQUASH_BED_ERROR_MESSAGE(new Builder("Stop \"You can only sleep at night\" message filling the chat") .addMixinClasses("minecraft.MixinNetHandlerPlayClient").addTargetedMod(TargetedMod.VANILLA) @@ -297,7 +297,7 @@ public enum Mixins { .addMixinClasses("forge.MixinGuiIngameForge_CrosshairInvertColors").setSide(Side.CLIENT) .setApplyIf(() -> TweaksConfig.dontInvertCrosshairColor).addTargetedMod(TargetedMod.VANILLA)), FIX_OPENGUIHANDLER_WINDOWID(new Builder("Fix OpenGuiHandler").setPhase(Phase.EARLY).setSide(Side.BOTH) - .addMixinClasses("forge.MixinOpenGuiHandler").setApplyIf(() -> FixesConfig.fixForgeOpenGuiHandlerWindowId) + .addMixinClasses("fml.MixinOpenGuiHandler").setApplyIf(() -> FixesConfig.fixForgeOpenGuiHandlerWindowId) .addTargetedMod(TargetedMod.VANILLA)), FIX_KEYBIND_CONFLICTS(new Builder("Trigger all conflicting keybinds").setPhase(Phase.EARLY).setSide(Side.CLIENT) .addMixinClasses("minecraft.MixinKeyBinding", "minecraft.MixinMinecraft_UpdateKeys") @@ -398,6 +398,18 @@ public enum Mixins { .addMixinClasses("minecraft.MixinMinecraft_FixDuplicateSounds") .setApplyIf(() -> FixesConfig.fixDuplicateSounds)), + ADD_MOD_ITEM_STATS(new Builder("Add stats for modded items").addMixinClasses("fml.MixinGameRegistry") + .addTargetedMod(TargetedMod.VANILLA).setApplyIf(() -> TweaksConfig.addModItemStats).setPhase(Phase.EARLY) + .setSide(Side.BOTH)), + + ADD_MOD_ENTITY_STATS(new Builder("Add stats for modded entities").addMixinClasses("minecraft.MixinStatList") + .addTargetedMod(TargetedMod.VANILLA).setApplyIf(() -> TweaksConfig.addModEntityStats).setPhase(Phase.EARLY) + .setSide(Side.BOTH)), + + ADD_MOD_ENTITY_STATS_CLIENT(new Builder("Add stats for modded entities (client side)") + .addMixinClasses("minecraft.MixinStatsMobsList").addTargetedMod(TargetedMod.VANILLA) + .setApplyIf(() -> TweaksConfig.addModEntityStats).setPhase(Phase.EARLY).setSide(Side.CLIENT)), + // Ic2 adjustments IC2_UNPROTECTED_GET_BLOCK_FIX(new Builder("IC2 Kinetic Fix").setPhase(Phase.EARLY).setSide(Side.BOTH) .addMixinClasses("ic2.MixinIc2WaterKinetic").setApplyIf(() -> FixesConfig.fixIc2UnprotectedGetBlock) @@ -443,10 +455,10 @@ public enum Mixins { "ic2.MixinIC2ArmorSolarHelmet", "ic2.MixinIC2ArmorStaticBoots") .setApplyIf(() -> FixesConfig.fixIc2ArmorLag).addTargetedMod(TargetedMod.IC2)), - IC2_RESOURCE_PACK_TRANSLATION_FIX(new Builder("IC2 Resource Pack Translation Fix").setPhase(Phase.EARLY) - .setSide(Side.CLIENT) - .addMixinClasses("forge.MixinLanguageRegistry", "forge.MixinFMLClientHandler", "ic2.MixinLocalization") - .setApplyIf(() -> FixesConfig.fixIc2ResourcePackTranslation).addTargetedMod(TargetedMod.IC2)), + IC2_RESOURCE_PACK_TRANSLATION_FIX( + new Builder("IC2 Resource Pack Translation Fix").setPhase(Phase.EARLY).setSide(Side.CLIENT) + .addMixinClasses("fml.MixinLanguageRegistry", "fml.MixinFMLClientHandler", "ic2.MixinLocalization") + .setApplyIf(() -> FixesConfig.fixIc2ResourcePackTranslation).addTargetedMod(TargetedMod.IC2)), // Disable update checkers BIBLIOCRAFT_UPDATE_CHECK(new Builder("Yeet Bibliocraft Update Check").setPhase(Phase.LATE).setSide(Side.CLIENT) diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinASMDataTable.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinASMDataTable.java similarity index 97% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinASMDataTable.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinASMDataTable.java index 3aaaa7ba..86445a84 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinASMDataTable.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinASMDataTable.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import java.io.File; import java.util.HashMap; diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLClientHandler.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLClientHandler.java similarity index 94% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLClientHandler.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLClientHandler.java index 441d9b87..ec8aff01 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLClientHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLClientHandler.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLProxyPacket.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLProxyPacket.java similarity index 98% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLProxyPacket.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLProxyPacket.java index 92429c35..2f5f2eea 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLProxyPacket.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLProxyPacket.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import net.minecraft.network.Packet; diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java new file mode 100644 index 00000000..2f39c690 --- /dev/null +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java @@ -0,0 +1,80 @@ +package com.mitchej123.hodgepodge.mixins.early.fml; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.stats.StatCrafting; +import net.minecraft.stats.StatList; +import net.minecraft.util.ChatComponentTranslation; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; +import com.mitchej123.hodgepodge.Common; + +import cpw.mods.fml.common.registry.GameRegistry; + +@Mixin(GameRegistry.class) +public class MixinGameRegistry { + + @ModifyExpressionValue( + at = @At( + target = "Lcpw/mods/fml/common/registry/GameData;registerItem(Lnet/minecraft/item/Item;Ljava/lang/String;)I", + value = "INVOKE"), + method = "registerBlock(Lnet/minecraft/block/Block;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Object;)Lnet/minecraft/block/Block;", + remap = false) + private static int hodgepodge$registerBlockStats(int itemId, Block block, Class itemclass, + String name, Object[] itemCtorArgs, @Local ItemBlock i) { + if (block.getEnableStats()) { + StatCrafting statMine = hodgepodge$createAndRegisterStat("stat.mineBlock", i); + StatList.mineBlockStatArray[itemId] = statMine; + StatList.objectMineStats.add(statMine); + } + StatList.objectUseStats[itemId] = hodgepodge$createAndRegisterStat("stat.useItem", i); + StatList.objectCraftStats[itemId] = hodgepodge$createAndRegisterStat("stat.craftItem", i); + return itemId; + } + + @ModifyExpressionValue( + at = @At( + target = "Lcpw/mods/fml/common/registry/GameData;registerItem(Lnet/minecraft/item/Item;Ljava/lang/String;)I", + value = "INVOKE"), + method = "registerItem(Lnet/minecraft/item/Item;Ljava/lang/String;Ljava/lang/String;)Lnet/minecraft/item/Item;", + remap = false) + private static int hodgepodge$registerItemStats(int itemId, Item item, String name, String modId) { + if (item.isDamageable()) { + StatList.objectBreakStats[itemId] = hodgepodge$createAndRegisterStat("stat.breakItem", item); + } + StatCrafting statCraft = hodgepodge$createAndRegisterStat("stat.useItem", item); + StatList.objectUseStats[itemId] = statCraft; + if (!(item instanceof ItemBlock)) { + StatList.itemStats.add(statCraft); + } + StatList.objectCraftStats[itemId] = hodgepodge$createAndRegisterStat("stat.craftItem", item); + return itemId; + } + + @Unique + private static StatCrafting hodgepodge$createAndRegisterStat(String key, Item item) { + String unlocalizedName; + try { + unlocalizedName = item.getUnlocalizedName(); + } catch (Exception e) { + String registryName = item.delegate.name(); + unlocalizedName = "item." + registryName + ".name"; + Common.log.warn( + "An Exception occured while invoking Item.getUnlocalizedName() after registering the item {} ({})! Using fallback unlocalized name.", + registryName, + item.getClass().getName()); + } + StatCrafting stat = new StatCrafting( + key + ".autogen." + item.delegate.name(), + new ChatComponentTranslation(key, new ChatComponentTranslation(unlocalizedName)), + item); + stat.registerStat(); + return stat; + } +} diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinLanguageRegistry.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinLanguageRegistry.java similarity index 98% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinLanguageRegistry.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinLanguageRegistry.java index cc4a14b6..315f56b4 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinLanguageRegistry.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinLanguageRegistry.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import java.io.File; import java.io.IOException; diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinNetworkDispatcher.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinNetworkDispatcher.java similarity index 97% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinNetworkDispatcher.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinNetworkDispatcher.java index e13df981..e1c163dc 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinNetworkDispatcher.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinNetworkDispatcher.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import java.lang.ref.WeakReference; diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinOpenGuiHandler.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinOpenGuiHandler.java similarity index 96% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinOpenGuiHandler.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinOpenGuiHandler.java index 568be96f..26ecfdeb 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinOpenGuiHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinOpenGuiHandler.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import static org.objectweb.asm.Opcodes.PUTFIELD; @@ -21,7 +21,7 @@ import cpw.mods.fml.common.network.internal.OpenGuiHandler; import io.netty.channel.SimpleChannelInboundHandler; -@Mixin(value = { OpenGuiHandler.class }) +@Mixin(value = OpenGuiHandler.class) public abstract class MixinOpenGuiHandler extends SimpleChannelInboundHandler { /* diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinGuiIngameForge_CrosshairInvertColors.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinGuiIngameForge_CrosshairInvertColors.java index f4c7070b..ccfe0197 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinGuiIngameForge_CrosshairInvertColors.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinGuiIngameForge_CrosshairInvertColors.java @@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import com.llamalad7.mixinextras.injector.WrapWithCondition; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; @Mixin(GuiIngameForge.class) public class MixinGuiIngameForge_CrosshairInvertColors { diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/ic2/MixinLocalization.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/ic2/MixinLocalization.java index 8ac496a6..77ae812f 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/ic2/MixinLocalization.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/ic2/MixinLocalization.java @@ -8,6 +8,9 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; +import com.mitchej123.hodgepodge.mixins.early.fml.MixinLanguageRegistry; +import com.mitchej123.hodgepodge.mixins.hooks.IC2ResourcePack; + import cpw.mods.fml.common.registry.LanguageRegistry; import ic2.core.init.Localization; @@ -17,8 +20,8 @@ public class MixinLocalization { /** * Translations are delegated to vanilla lang system * - * @see com.mitchej123.hodgepodge.mixins.early.forge.MixinLanguageRegistry - * @see com.mitchej123.hodgepodge.mixins.hooks.IC2ResourcePack + * @see MixinLanguageRegistry + * @see IC2ResourcePack */ @Redirect( method = "postInit", @@ -32,8 +35,8 @@ public class MixinLocalization { /** * @author miozune * @reason Translations are delegated to vanilla lang system - * @see com.mitchej123.hodgepodge.mixins.early.forge.MixinLanguageRegistry - * @see com.mitchej123.hodgepodge.mixins.hooks.IC2ResourcePack + * @see MixinLanguageRegistry + * @see IC2ResourcePack */ @Overwrite(remap = false) protected static Map getStringTranslateMap() { diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityLivingBase_HidePotionParticles.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityLivingBase_HidePotionParticles.java index 8e991899..9aab2216 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityLivingBase_HidePotionParticles.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityLivingBase_HidePotionParticles.java @@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import com.llamalad7.mixinextras.injector.WrapWithCondition; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.mitchej123.hodgepodge.config.TweaksConfig; /** diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityPlayerMP.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityPlayerMP.java index 19366271..0684a411 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityPlayerMP.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityPlayerMP.java @@ -36,7 +36,6 @@ public abstract class MixinEntityPlayerMP extends EntityLivingBase { ServersideAttributeMap oldAttributeMap = (ServersideAttributeMap) oldPlayer.getAttributeMap(); // Grab the watched attributes - @SuppressWarnings("unchecked") Collection watchedAttribs = oldAttributeMap.getWatchedAttributes(); if (!watchedAttribs.isEmpty()) { @@ -64,7 +63,6 @@ public abstract class MixinEntityPlayerMP extends EntityLivingBase { } // Helper method based on 1.12 - @SuppressWarnings("unchecked") @Unique private Collection getModifiers(ModifiableAttributeInstance attr) { Set toReturn = Sets.newHashSet(); diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiContainerCreative.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiContainerCreative.java index f8a6dd98..31955b17 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiContainerCreative.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiContainerCreative.java @@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.llamalad7.mixinextras.injector.WrapWithCondition; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; @Mixin(GuiContainerCreative.class) public abstract class MixinGuiContainerCreative extends GuiContainer { diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiNewChat_TransparentChat.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiNewChat_TransparentChat.java index de5d2138..1f32d198 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiNewChat_TransparentChat.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiNewChat_TransparentChat.java @@ -6,7 +6,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import com.llamalad7.mixinextras.injector.WrapWithCondition; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; @Mixin(GuiNewChat.class) public abstract class MixinGuiNewChat_TransparentChat { diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinServerConfigurationManager.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinServerConfigurationManager.java index 26b99610..111a298a 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinServerConfigurationManager.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinServerConfigurationManager.java @@ -29,7 +29,6 @@ public class MixinServerConfigurationManager { private void hodgepodge$sendEntityProperties(EntityPlayerMP player, int dimension, Teleporter teleporter, CallbackInfo ci) { ServersideAttributeMap attributeMap = (ServersideAttributeMap) player.getAttributeMap(); - @SuppressWarnings("unchecked") Collection watchedAttribs = attributeMap.getWatchedAttributes(); if (!watchedAttribs.isEmpty()) { player.playerNetServerHandler diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatList.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatList.java new file mode 100644 index 00000000..0fede5c2 --- /dev/null +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatList.java @@ -0,0 +1,29 @@ +package com.mitchej123.hodgepodge.mixins.early.minecraft; + +import net.minecraft.entity.EntityList.EntityEggInfo; +import net.minecraft.stats.StatList; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.mitchej123.hodgepodge.util.StatHandler; +import com.mitchej123.hodgepodge.util.StatHandler.EntityInfo; + +@Mixin(StatList.class) +public class MixinStatList { + + @ModifyExpressionValue( + at = @At( + target = "Lnet/minecraft/entity/EntityList;getStringFromID(I)Ljava/lang/String;", + value = "INVOKE"), + method = { "func_151182_a", "func_151176_b" }) // these methods create and register the stats for + // killing/being killed by the specified entity + private static String hodgepodge$getEntityName(String original, EntityEggInfo info) { + if (info instanceof EntityInfo) { + return StatHandler.currentEntityName; + } + return original; + } + +} diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsMobsList.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsMobsList.java new file mode 100644 index 00000000..000ce8a0 --- /dev/null +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsMobsList.java @@ -0,0 +1,87 @@ +package com.mitchej123.hodgepodge.mixins.early.minecraft; + +import java.util.Comparator; +import java.util.List; + +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityList.EntityEggInfo; +import net.minecraft.stats.StatFileWriter; +import net.minecraft.util.StatCollector; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; +import com.mitchej123.hodgepodge.config.TweaksConfig; +import com.mitchej123.hodgepodge.util.StatHandler; +import com.mitchej123.hodgepodge.util.StatHandler.EntityInfo; + +import cpw.mods.fml.client.FMLClientHandler; + +@Mixin(targets = "net.minecraft.client.gui.achievement.GuiStats$StatsMobsList") +public class MixinStatsMobsList { + + // This List contains all instances of EntityEggInfo for which the stats should be displayed. The order in which + // they are displayed is determined by the List's order + @Shadow + private @Final List field_148222_l; + + @Inject(at = @At("TAIL"), method = "") + private void hodgepodge$addModdedEntities(CallbackInfo ci) { + StatFileWriter stats = FMLClientHandler.instance().getClientPlayerEntity().getStatFileWriter(); + for (EntityEggInfo info : StatHandler.ADDITIONAL_ENTITY_EGGS.values()) { + // Is either the killed Entity or killed by Entity stat non-zero? + // NOTE: StatFileWriter.writeStat() actually reads the stat (writing is done with + // StatFileWriter.func_150873_a()) + if (stats.writeStat(info.field_151512_d) > 0 || stats.writeStat(info.field_151513_e) > 0) { + this.field_148222_l.add(info); + } + } + if (TweaksConfig.sortEntityStats) { + this.field_148222_l.sort(new Comparator<>() { + + @Override + public int compare(EntityEggInfo o1, EntityEggInfo o2) { + if (o1 == null) { + if (o2 == null) { + return 0; + } + return -1; + } + if (o2 == null) { + return 1; + } + String name1 = "entity." + getName(o1) + ".name"; + String name2 = "entity." + getName(o2) + ".name"; + return StatCollector.translateToLocal(name1) + .compareToIgnoreCase(StatCollector.translateToLocal(name2)); + } + + private static String getName(EntityEggInfo eei) { + if (eei instanceof EntityInfo info) { + return info.name; + } else { + return EntityList.getStringFromID(eei.spawnedID); + } + } + }); + } + } + + @ModifyExpressionValue( + at = @At( + target = "Lnet/minecraft/entity/EntityList;getStringFromID(I)Ljava/lang/String;", + value = "INVOKE"), + method = "drawSlot") + private static String hodgepodge$getEntityName(String original, @Local EntityEggInfo entityegginfo) { + if (entityegginfo instanceof EntityInfo info) { + return info.name; + } + return original; + } +} diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/hooks/IC2ResourcePack.java b/src/main/java/com/mitchej123/hodgepodge/mixins/hooks/IC2ResourcePack.java index 2bfd3574..b796c974 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/hooks/IC2ResourcePack.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/hooks/IC2ResourcePack.java @@ -47,9 +47,8 @@ public boolean resourceExists(ResourceLocation rl) { return zipFile.getEntry(locationToName(rl)) != null || fallbackResourcePack.resourceExists(rl); } - @SuppressWarnings("rawtypes") @Override - public Set getResourceDomains() { + public Set getResourceDomains() { return ImmutableSet.of("ic2", "minecraft"); } diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/late/projecte/MixinObjHandler.java b/src/main/java/com/mitchej123/hodgepodge/mixins/late/projecte/MixinObjHandler.java index e05245c9..636be881 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/late/projecte/MixinObjHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/late/projecte/MixinObjHandler.java @@ -15,7 +15,6 @@ @Mixin(ObjHandler.class) public class MixinObjHandler { - @SuppressWarnings("unchecked") @Redirect( method = "registerPhiloStoneSmelting", at = @At( diff --git a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java new file mode 100644 index 00000000..0c48908a --- /dev/null +++ b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java @@ -0,0 +1,136 @@ +package com.mitchej123.hodgepodge.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityList.EntityEggInfo; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.stats.StatBase; +import net.minecraft.stats.StatList; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.living.LivingDeathEvent; + +import com.google.common.collect.ImmutableList; + +import cpw.mods.fml.common.event.FMLModIdMappingEvent.ModRemapping; +import cpw.mods.fml.common.event.FMLModIdMappingEvent.RemapTarget; +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + +public class StatHandler { + + public static final Map, EntityEggInfo> ADDITIONAL_ENTITY_EGGS = new HashMap<>(); + public static String currentEntityName; + + // stat arrays mapped to the frozen ids + private static final StatBase[] STATS_MINE = new StatBase[StatList.mineBlockStatArray.length]; + private static final StatBase[] STATS_CRAFT = new StatBase[StatList.objectCraftStats.length]; + private static final StatBase[] STATS_USE = new StatBase[StatList.objectUseStats.length]; + private static final StatBase[] STATS_BREAK = new StatBase[StatList.objectBreakStats.length]; + private static boolean initFrozenStats = true; + + public static void remap(ImmutableList remappedIds) { + if (initFrozenStats) { + // init stat arrays mapped to the frozen ids + arraycopy(StatList.mineBlockStatArray, STATS_MINE); + arraycopy(StatList.objectCraftStats, STATS_CRAFT); + arraycopy(StatList.objectUseStats, STATS_USE); + arraycopy(StatList.objectBreakStats, STATS_BREAK); + initFrozenStats = true; + } + if (remappedIds.isEmpty()) { + // we are reverting to frozen ids + arraycopy(STATS_MINE, StatList.mineBlockStatArray); + arraycopy(STATS_CRAFT, StatList.objectCraftStats); + arraycopy(STATS_USE, StatList.objectUseStats); + arraycopy(STATS_BREAK, StatList.objectBreakStats); + return; + } + + final StatBase[] statsMine = StatList.mineBlockStatArray.clone(); + final StatBase[] statsCraft = StatList.objectCraftStats.clone(); + final StatBase[] statsUse = StatList.objectUseStats.clone(); + final StatBase[] statsBreak = StatList.objectBreakStats.clone(); + + // remap the stats with changed id + for (ModRemapping remapping : remappedIds) { + if (remapping.remapTarget == RemapTarget.BLOCK) { + continue; + } + final int newId = remapping.newId; + final int oldId = remapping.oldId; + statsMine[newId] = StatList.mineBlockStatArray[oldId]; + statsCraft[newId] = StatList.objectCraftStats[oldId]; + statsUse[newId] = StatList.objectUseStats[oldId]; + statsBreak[newId] = StatList.objectBreakStats[oldId]; + } + arraycopy(statsMine, StatList.mineBlockStatArray); + arraycopy(statsCraft, StatList.objectCraftStats); + arraycopy(statsUse, StatList.objectUseStats); + arraycopy(statsBreak, StatList.objectBreakStats); + } + + public static void addEntityStats() { + for (Entry, String> e : EntityList.classToStringMapping.entrySet()) { + Class clazz = e.getKey(); + if (!EntityLivingBase.class.isAssignableFrom(clazz)) { + // only entities extending EntityLivingBase can be killed/can kill the player + continue; + } + @SuppressWarnings("unchecked") + Integer id = (Integer) EntityList.classToIDMapping.getOrDefault(clazz, 256); + if (EntityList.entityEggs.containsKey(id)) { + continue; + } + currentEntityName = e.getValue(); + ADDITIONAL_ENTITY_EGGS.put(clazz, new EntityInfo(id, currentEntityName)); + } + currentEntityName = null; + MinecraftForge.EVENT_BUS.register(new StatHandler()); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onLivingDeathEvent(LivingDeathEvent event) { + if (event.entityLiving instanceof EntityPlayerMP player) { + // the player was killed + EntityLivingBase attackingEntity = player.func_94060_bK(); + if (attackingEntity == null) { + return; + } + EntityEggInfo info = ADDITIONAL_ENTITY_EGGS.get(attackingEntity.getClass()); + if (info == null) { + return; + } + player.addStat(info.field_151513_e, 1); // "killed by entity" stat + return; + } + if (event.source.getEntity() instanceof EntityPlayer player) { + // the player made a kill + EntityEggInfo info = ADDITIONAL_ENTITY_EGGS.get(event.entityLiving.getClass()); + if (info == null) { + return; + } + player.addStat(info.field_151512_d, 1); // "kill entity" stat + + } + } + + private static void arraycopy(T[] src, T[] dest) { + System.arraycopy(src, 0, dest, 0, src.length); + } + + public static class EntityInfo extends EntityEggInfo { + + public final String name; + + public EntityInfo(int id, String name) { + super(id, 0, 0); + this.name = name; + } + } +} diff --git a/src/main/resources/META-INF/hodgepodge_at.cfg b/src/main/resources/META-INF/hodgepodge_at.cfg index 26d23123..0da84b3c 100644 --- a/src/main/resources/META-INF/hodgepodge_at.cfg +++ b/src/main/resources/META-INF/hodgepodge_at.cfg @@ -19,3 +19,4 @@ public net.minecraft.client.resources.AbstractResourcePack field_110597_b # reso public net.minecraft.client.resources.FallbackResourceManager field_110540_a # resourcePacks public net.minecraft.client.resources.FileResourcePack field_110600_d # resourcePackZipFile public net.minecraft.client.resources.SimpleReloadableResourceManager field_110548_a # domainResourceManagers +public net.minecraft.entity.EntityList field_75624_e # classToIDMapping