Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Woot mixin for proper entity cleanup #552

Merged
merged 4 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
* **Duplication Fixes:** Fixes various duplication exploits
* **Woot**
* **Cleanup Simulated Kills:** Remove any leftover entities spawned on simulated mob's death
1 change: 1 addition & 0 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
Original file line number Diff line number Diff line change
@@ -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<ForgeChunkManager.Ticket> 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();
}
}
Original file line number Diff line number Diff line change
@@ -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<Entity> cir, @Local Entity entity)
{
((EntityLivingBase)entity).recentlyHit = 100;
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
}
}
Original file line number Diff line number Diff line change
@@ -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<Integer, SpawnBox> 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<Entity> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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<Integer> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
1 change: 1 addition & 0 deletions src/main/resources/assets/universaltweaks/lang/en_us.lang
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/main/resources/mixins.mods.woot.json
Original file line number Diff line number Diff line change
@@ -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"]
}