diff --git a/README.md b/README.md index 6cbde348..773a5cf0 100644 --- a/README.md +++ b/README.md @@ -430,4 +430,6 @@ All changes are toggleable via config files. * **Projectile Despawning:** Despawns unbreakable projectiles faster to improve framerates * **Tool Customization:** Sets the attack damage cutoff at which diminishing returns start for any Tinkers' tool and sets the rate at which a tool's attack damage incrementally decays depending on its damage cutoff * **Tiny Progressions** - * **Duplication Fixes:** Fixes various duplication exploits \ No newline at end of file + * **Duplication Fixes:** Fixes various duplication exploits +* **Woot** + * **Cleanup Simulated Kills:** Remove any leftover entities spawned on simulated mob's death \ No newline at end of file diff --git a/dependencies.gradle b/dependencies.gradle index 7d824e14..ddf7ef4c 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -139,6 +139,7 @@ final def mod_dependencies = [ 'curse.maven:tinkers_construct-74072:2902483' : [debug_tinkers_construct], 'curse.maven:tinkerscomplement-272671:2843439' : [debug_tinkers_construct], 'curse.maven:tinyprogressions-250850:2721018' : [debug_tiny_progressions], + 'curse.maven:woot-244049:2712670' : [debug_woot], 'maven.modrinth:industrial-foregoing:1.12.13-237' : [debug_industrial_foregoing], 'net.darkhax.bookshelf:Bookshelf-1.12.2:2.3.590' : [debug_stages], 'net.darkhax.gamestages:GameStages-1.12.2:2.0.120' : [debug_stages], diff --git a/gradle.properties b/gradle.properties index 2d9ee663..4c49b0ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -66,6 +66,7 @@ debug_the_spice_of_life = false debug_thermal_expansion = false debug_tinkers_construct = false debug_tiny_progressions = false +debug_woot = false # END MOD DEBUG CONTROL SECTION diff --git a/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java b/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java index dffba1c7..8b41c578 100644 --- a/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java +++ b/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java @@ -263,6 +263,10 @@ public class UTConfigMods @Config.Name("Tiny Progressions") public static final TinyProgressionsCategory TINY_PROGRESSIONS = new TinyProgressionsCategory(); + @Config.LangKey("cfg.universaltweaks.modintegration.woot") + @Config.Name("Woot") + public static final WootCategory WOOT = new WootCategory(); + public static class AbyssalCraftCategory { @Config.RequiresMcRestart @@ -1157,6 +1161,14 @@ public static class TinyProgressionsCategory public boolean utDuplicationFixesToggle = true; } + public static class WootCategory + { + @Config.RequiresMcRestart + @Config.Name("Cleanup Simulated Kills") + @Config.Comment("Remove any leftover entities spawned on simulated mob's death") + public boolean utCleanupSimulatedKillsToggle = true; + } + static { ConfigAnytime.register(UTConfigMods.class); diff --git a/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java b/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java index abc47618..496e397b 100644 --- a/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java +++ b/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java @@ -109,6 +109,7 @@ public class UTMixinLoader implements ILateMixinLoader put("mixins.mods.thermalexpansion.dupes.json", () -> loaded("thermalexpansion") && UTConfigMods.THERMAL_EXPANSION.utDuplicationFixesToggle); put("mixins.mods.thermalexpansion.json", () -> loaded("thermalexpansion")); put("mixins.mods.tinyprogressions.dupes.json", () -> loaded("tp") && UTConfigMods.TINY_PROGRESSIONS.utDuplicationFixesToggle); + put("mixins.mods.woot.json", () -> loaded("woot") && UTConfigMods.WOOT.utCleanupSimulatedKillsToggle); } }); diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/woot/ITartarusCleaner.java b/src/main/java/mod/acgaming/universaltweaks/mods/woot/ITartarusCleaner.java new file mode 100644 index 00000000..117c0623 --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/woot/ITartarusCleaner.java @@ -0,0 +1,10 @@ +package mod.acgaming.universaltweaks.mods.woot; + +import net.minecraft.world.World; + +public interface ITartarusCleaner +{ + void ut$clean(World world, int boxId, boolean removeAll); + void ut$freeBoxes(); + boolean ut$areBoxesInUse(); +} diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/woot/UTWootTicketManager.java b/src/main/java/mod/acgaming/universaltweaks/mods/woot/UTWootTicketManager.java new file mode 100644 index 00000000..3ee1c4e2 --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/woot/UTWootTicketManager.java @@ -0,0 +1,64 @@ +package mod.acgaming.universaltweaks.mods.woot; + +import java.util.List; + +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.common.ForgeChunkManager; + +import ipsis.Woot; +import ipsis.woot.dimension.WootDimensionManager; +import ipsis.woot.util.DebugSetup; +import mod.acgaming.universaltweaks.UniversalTweaks; + +public class UTWootTicketManager +{ + public static final ChunkPos CHUNK = new ChunkPos(WootDimensionManager.CHUNK_X, WootDimensionManager.CHUNK_Z); + public static ForgeChunkManager.Ticket ticket; + + public static void forceChunk(World world, int boxId) + { + WorldServer worldWoot = Woot.wootDimensionManager.getWorldServer(world); + if (ticket == null) + { + Woot.debugSetup.trace(DebugSetup.EnumDebugType.TARTARUS, "UTWootTicketManager:callback", "requesting a ticket"); + ticket = ForgeChunkManager.requestTicket(Woot.instance, worldWoot, ForgeChunkManager.Type.NORMAL); + if (ticket == null) + { + UniversalTweaks.LOGGER.error("UTWootTicketManager ::: Could not get a ticket for Tartarus (Woot)! Please report to Universal Tweaks."); + return; + } + } + Woot.debugSetup.trace(DebugSetup.EnumDebugType.TARTARUS, "UTWootTicketManager:callback", "forcing chunk for boxId " + boxId); + ForgeChunkManager.forceChunk(ticket, CHUNK); + } + + public static void releaseChunk(int boxId) + { + if (ticket == null) return; + Woot.debugSetup.trace(DebugSetup.EnumDebugType.TARTARUS, "UTWootTicketManager:callback", "trying to release chunk for boxId " + boxId); + if (!((ITartarusCleaner) Woot.tartarusManager).ut$areBoxesInUse()) + { + Woot.debugSetup.trace(DebugSetup.EnumDebugType.TARTARUS, "UTWootTicketManager:callback", "releasing ticket"); + ForgeChunkManager.releaseTicket(ticket); + ticket = null; + } + } + + public static void callback(List tickets, World world) + { + int dim = world.provider.getDimension(); + if (dim != Woot.wootDimensionManager.getDimensionId()) return; + // Sanity check + if (tickets.size() > 1) + { + for (ForgeChunkManager.Ticket ticket : tickets) + { + ForgeChunkManager.releaseTicket(ticket); + } + } + UTWootTicketManager.ticket = tickets.get(0); + ((ITartarusCleaner) Woot.tartarusManager).ut$freeBoxes(); + } +} diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTEntitySpawnerMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTEntitySpawnerMixin.java new file mode 100644 index 00000000..c473861b --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTEntitySpawnerMixin.java @@ -0,0 +1,29 @@ +package mod.acgaming.universaltweaks.mods.woot.mixin; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import com.llamalad7.mixinextras.sugar.Local; +import ipsis.woot.spawning.EntitySpawner; +import ipsis.woot.util.WootMobName; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +// Courtesy of jchung01 +@Mixin(value = EntitySpawner.class, remap = false) +public class UTEntitySpawnerMixin +{ + /** + * @reason Set correct entity values BEFORE passing to events. + */ + @Inject(method = "spawnEntity", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/event/ForgeEventFactory;doSpecialSpawn(Lnet/minecraft/entity/EntityLiving;Lnet/minecraft/world/World;FFF)Z")) + private void ut$fixInitSpawn(WootMobName wootMobName, World world, BlockPos pos, CallbackInfoReturnable cir, @Local Entity entity) + { + ((EntityLivingBase)entity).recentlyHit = 100; + entity.setPosition(pos.getX(), pos.getY(), pos.getZ()); + } +} diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTTartarusManagerMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTTartarusManagerMixin.java new file mode 100644 index 00000000..3ac3ca59 --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTTartarusManagerMixin.java @@ -0,0 +1,61 @@ +package mod.acgaming.universaltweaks.mods.woot.mixin; + +import java.util.HashMap; + +import com.google.common.base.Predicate; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import ipsis.Woot; +import ipsis.woot.loot.schools.SpawnBox; +import ipsis.woot.loot.schools.TartarusManager; +import mod.acgaming.universaltweaks.mods.woot.ITartarusCleaner; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +// Courtesy of jchung01 +@Mixin(value = TartarusManager.class, remap = false) +public class UTTartarusManagerMixin implements ITartarusCleaner +{ + @Shadow + private HashMap spawnBoxMap; + + @Override + public void ut$clean(World world, int boxId, boolean removeAll) + { + WorldServer worldWoot = Woot.wootDimensionManager.getWorldServer(world); + if (worldWoot == null) return; + // Some additionally spawned entities are not EntityLiving (like AoA heartstones), so search by exclusion + Predicate condition = entity -> + { + boolean ret = !(entity instanceof EntityPlayer); + return removeAll ? ret : ret && !(entity instanceof EntityItem); + }; + for (Entity entity : worldWoot.getEntitiesWithinAABB(Entity.class, this.spawnBoxMap.get(boxId).getAxisAlignedBB(), condition)) + { + worldWoot.removeEntityDangerously(entity); + } + } + + @Override + public void ut$freeBoxes() + { + for (SpawnBox box : spawnBoxMap.values()) + { + box.clearUsed(); + } + } + + @Override + public boolean ut$areBoxesInUse() + { + for (SpawnBox box: spawnBoxMap.values()) + { + if (box.isUsed()) return true; + } + return false; + } +} diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTTartarusSchoolMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTTartarusSchoolMixin.java new file mode 100644 index 00000000..c485719d --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTTartarusSchoolMixin.java @@ -0,0 +1,45 @@ +package mod.acgaming.universaltweaks.mods.woot.mixin; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import ipsis.Woot; +import ipsis.woot.farming.ITickTracker; +import ipsis.woot.farmstructure.IFarmSetup; +import ipsis.woot.loot.schools.TartarusManager; +import ipsis.woot.loot.schools.TartarusSchool; +import mod.acgaming.universaltweaks.mods.woot.ITartarusCleaner; +import mod.acgaming.universaltweaks.mods.woot.UTWootTicketManager; +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; + +// Courtesy of jchung01 +@Mixin(value = TartarusSchool.class, remap = false) +public class UTTartarusSchoolMixin +{ + @Shadow + private int spawnId; + + @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lipsis/woot/loot/schools/TartarusManager;spawnInBox(Lnet/minecraft/world/World;ILipsis/woot/util/WootMobName;Lipsis/woot/util/EnumEnchantKey;)V", shift = At.Shift.AFTER)) + private void ut$cleanupOnDeath(ITickTracker tickTracker, World world, BlockPos origin, IFarmSetup farmSetup, CallbackInfo ci) + { + if (spawnId == -1) return; + ((ITartarusCleaner) Woot.tartarusManager).ut$clean(world, spawnId, false); + UTWootTicketManager.forceChunk(world, spawnId); + } + + @WrapOperation(method = "tick", at = @At(value = "INVOKE", target = "Lipsis/woot/loot/schools/TartarusManager;freeSpawnBoxId(I)I")) + private int ut$cleanupOnFree(TartarusManager instance, int id, Operation original, ITickTracker tickTracker, World world) + { + int oldSpawnId = spawnId; + ((ITartarusCleaner) Woot.tartarusManager).ut$clean(world, oldSpawnId, true); + spawnId = original.call(instance, oldSpawnId); + UTWootTicketManager.releaseChunk(oldSpawnId); + return spawnId; + } +} diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTWootMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTWootMixin.java new file mode 100644 index 00000000..e01e0d59 --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/woot/mixin/UTWootMixin.java @@ -0,0 +1,21 @@ +package mod.acgaming.universaltweaks.mods.woot.mixin; + +import net.minecraftforge.common.ForgeChunkManager; + +import ipsis.Woot; +import mod.acgaming.universaltweaks.mods.woot.UTWootTicketManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +// Courtesy of jchung01 +@Mixin(value = Woot.class, remap = false) +public class UTWootMixin +{ + @Inject(method = "postInit", at = @At(value = "TAIL")) + private void utRegisterTicketCallback(CallbackInfo ci) + { + ForgeChunkManager.setForcedChunkLoadingCallback(Woot.instance, UTWootTicketManager::callback); + } +} diff --git a/src/main/resources/assets/universaltweaks/lang/en_us.lang b/src/main/resources/assets/universaltweaks/lang/en_us.lang index 363f1c53..eebc1188 100644 --- a/src/main/resources/assets/universaltweaks/lang/en_us.lang +++ b/src/main/resources/assets/universaltweaks/lang/en_us.lang @@ -113,6 +113,7 @@ cfg.universaltweaks.modintegration.thaumicwonders=Thaumic Wonders cfg.universaltweaks.modintegration.thefarlanders=The Farlanders cfg.universaltweaks.modintegration.tinyprogressions=Tiny Progressions cfg.universaltweaks.modintegration.tr=Tech Reborn +cfg.universaltweaks.modintegration.woot=Woot cfg.universaltweaks.modintegration=Mod Integration cfg.universaltweaks.tweaks.blocks.betterplacement=Better Placement diff --git a/src/main/resources/mixins.mods.woot.json b/src/main/resources/mixins.mods.woot.json new file mode 100644 index 00000000..8781edb6 --- /dev/null +++ b/src/main/resources/mixins.mods.woot.json @@ -0,0 +1,7 @@ +{ + "package": "mod.acgaming.universaltweaks.mods.woot.mixin", + "refmap": "universaltweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": ["UTEntitySpawnerMixin", "UTTartarusManagerMixin", "UTTartarusSchoolMixin", "UTWootMixin"] +} \ No newline at end of file