Skip to content

Commit

Permalink
EntityLivingBase potions mixin
Browse files Browse the repository at this point in the history
  • Loading branch information
xchgeax committed Aug 2, 2022
1 parent 560cbbf commit 071295a
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class LoadingConfig {
public boolean thirstyTankContainer;
public boolean fixWorldServerLeakingUnloadedEntities;
public boolean fixFullscreenResizable;
public boolean fixPotionIterating;

// ASM
public boolean pollutionAsm;
Expand Down Expand Up @@ -111,6 +112,7 @@ public LoadingConfig(File file) {
logHugeChat = config.get("fixes", "logHugeChat", true, "Log oversized chat message to console. WARNING: might create huge log files if this happens very often.").getBoolean();
fixWorldServerLeakingUnloadedEntities = config.get("fixes", "fixWorldServerLeakingUnloadedEntities", true, "Fix WorldServer leaking entities when no players are present in a dimension").getBoolean();
fixFullscreenResizable = config.get("fixes", "fixFullscreenResizable", true, "Fix game window becoming not resizable after toggling fullscrean in any way").getBoolean();
fixPotionIterating = config.get("fixes", "fixPotionIterating", true, "Fix crashes with ConcurrentModificationException because of incorrectly iterating over active potions").getBoolean();

increaseParticleLimit = config.get("tweaks", "increaseParticleLimit", true, "Increase particle limit").getBoolean();
particleLimit = Math.max(Math.min(config.get("tweaks", "particleLimit", 8000, "Particle limit [4000-16000]").getInt(), 16000), 4000);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public enum Mixins {
FIX_WORLD_SERVER_LEAKING_UNLOADED_ENTITIES("minecraft.MixinWorldServerUpdateEntities", () -> Hodgepodge.config.fixWorldServerLeakingUnloadedEntities, TargetedMod.VANILLA),
FIX_ARROW_WRONG_LIGHTING("minecraft.MixinRendererLivingEntity", Side.CLIENT, () -> Hodgepodge.config.fixGlStateBugs, TargetedMod.VANILLA),
FIX_FULLSCREEN_RESIZABLE("minecraft.MixinMinecraft", Side.CLIENT, () -> Hodgepodge.config.fixFullscreenResizable, TargetedMod.VANILLA),
FIX_POTION_ITERATING("minecraft.MixinEntityLivingPotions", Side.BOTH, () -> Hodgepodge.config.fixPotionIterating, TargetedMod.VANILLA),

// Potentially obsolete vanilla fixes
GRASS_GET_BLOCK_FIX("minecraft.MixinBlockGrass", () -> Hodgepodge.config.fixVanillaUnprotectedGetBlock, TargetedMod.VANILLA),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package com.mitchej123.hodgepodge.mixins.minecraft;

import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.potion.PotionHelper;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;


import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator;


@SuppressWarnings("unused")
@Mixin(EntityLivingBase.class)
public abstract class MixinEntityLivingPotions extends Entity {

@Shadow
@Final
private HashMap activePotionsMap;

@Shadow
private boolean potionsNeedUpdate;

public MixinEntityLivingPotions(World p_i1594_1_) {
super(p_i1594_1_);
}

/**
* @author laetansky
* @reason Fix @see java.util.ConcurrentModificationException being thrown
* when modifying active potions inside those forge event handlers which could be fired
* while iterating over active potion effect.
* Fix is back ported from newer versions.
*/
@Overwrite
protected void updatePotionEffects()
{
Iterator iterator = this.activePotionsMap.keySet().iterator();

try {
while (iterator.hasNext()) {
Integer integer = (Integer) iterator.next();
PotionEffect potioneffect = (PotionEffect) this.activePotionsMap.get(integer);

if (!potioneffect.onUpdate(((EntityLivingBase)(Object)this))) {
if (!this.worldObj.isRemote) {
iterator.remove();
this.onFinishedPotionEffect(potioneffect);
}
} else if (potioneffect.getDuration() % 600 == 0) {
this.onChangedPotionEffect(potioneffect, false);
}
}
} catch (ConcurrentModificationException ignored) {}

int i;

if (this.potionsNeedUpdate)
{
if (!this.worldObj.isRemote)
{
if (this.activePotionsMap.isEmpty())
{
this.dataWatcher.updateObject(8, Byte.valueOf((byte)0));
this.dataWatcher.updateObject(7, Integer.valueOf(0));
this.setInvisible(false);
}
else
{
i = PotionHelper.calcPotionLiquidColor(this.activePotionsMap.values());
this.dataWatcher.updateObject(8, Byte.valueOf((byte)(PotionHelper.func_82817_b(this.activePotionsMap.values()) ? 1 : 0)));
this.dataWatcher.updateObject(7, Integer.valueOf(i));
this.setInvisible(this.isPotionActive(Potion.invisibility.id));
}
}

this.potionsNeedUpdate = false;
}

i = this.dataWatcher.getWatchableObjectInt(7);
boolean flag1 = this.dataWatcher.getWatchableObjectByte(8) > 0;

if (i > 0)
{
boolean flag = false;

if (!this.isInvisible())
{
flag = this.rand.nextBoolean();
}
else
{
flag = this.rand.nextInt(15) == 0;
}

if (flag1)
{
flag &= this.rand.nextInt(5) == 0;
}

if (flag && i > 0)
{
double d0 = (double)(i >> 16 & 255) / 255.0D;
double d1 = (double)(i >> 8 & 255) / 255.0D;
double d2 = (double)(i >> 0 & 255) / 255.0D;
this.worldObj.spawnParticle(flag1 ? "mobSpellAmbient" : "mobSpell", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height - (double)this.yOffset, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, d0, d1, d2);
}
}
}

@Shadow
private void onFinishedPotionEffect(PotionEffect p_70688_1_) {}

@Shadow
private void onChangedPotionEffect(PotionEffect p_70695_1_, boolean p_70695_2_) {}

@Shadow
public abstract boolean isPotionActive(int p_82165_1_);
}

0 comments on commit 071295a

Please sign in to comment.