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 config to prevent self morph particles #309

Open
wants to merge 1 commit into
base: 1.12
Choose a base branch
from
Open
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
5 changes: 5 additions & 0 deletions src/main/java/mchorse/metamorph/ClientProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,9 @@ public boolean canEditSelectors()
{
return OpHelper.isPlayerOp() || Metamorph.opEntitySelector.get();
}

public boolean isDedicatedServer()
{
return false;
}
}
14 changes: 12 additions & 2 deletions src/main/java/mchorse/metamorph/CommonProxy.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package mchorse.metamorph;

import java.io.File;

import mchorse.metamorph.api.MorphHandler;
import mchorse.metamorph.api.MorphManager;
import mchorse.metamorph.api.MorphUtils;
Expand All @@ -14,6 +16,7 @@
import mchorse.metamorph.entity.EntityMorph;
import mchorse.metamorph.entity.SoundHandler;
import mchorse.metamorph.network.Dispatcher;
import mchorse.metamorph.world.WorldHandler;
import mchorse.vanilla_pack.MetamorphFactory;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
Expand All @@ -23,8 +26,6 @@
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.registry.EntityRegistry;

import java.io.File;

/**
* Common proxy
*
Expand Down Expand Up @@ -90,6 +91,7 @@ public void load()
/* Event listeners */
MinecraftForge.EVENT_BUS.register(new MorphHandler());
MinecraftForge.EVENT_BUS.register(new SoundHandler());
MinecraftForge.EVENT_BUS.register(new WorldHandler());
MinecraftForge.EVENT_BUS.register(new CapabilityHandler());
MinecraftForge.EVENT_BUS.register(new RegisterHandler());

Expand Down Expand Up @@ -132,4 +134,12 @@ public boolean canEditSelectors()
{
return true;
}

/**
* Changed to false in ClientProxy
*/
public boolean isDedicatedServer()
{
return true;
}
}
2 changes: 2 additions & 0 deletions src/main/java/mchorse/metamorph/Metamorph.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public class Metamorph
public static ValueBoolean disableFirstPersonHand;
public static ValueBoolean morphInTightSpaces;
public static ValueBoolean showMorphIdleSounds;
public static ValueBoolean spawnParticlesFirstPerson;
public static ValueBoolean pauseGUIInSP;
public static ValueBoolean renderBodyPartAxis;
public static ValueInt maxRecentMorphs;
Expand Down Expand Up @@ -107,6 +108,7 @@ public void onConfigRegister(RegisterConfigEvent event)
disableFirstPersonHand.clientSide();
morphInTightSpaces = builder.getBoolean("morph_in_tight_spaces", false);
showMorphIdleSounds = builder.getBoolean("show_morph_idle_sounds", true);
spawnParticlesFirstPerson = builder.getBoolean("spawn_particles_first_person", false);
pauseGUIInSP = builder.getBoolean("pause_gui_in_sp", true);
pauseGUIInSP.clientSide();
renderBodyPartAxis = builder.getBoolean("render_bodypart_axis", true);
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/mchorse/metamorph/api/morphs/EntityMorph.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import mchorse.metamorph.capabilities.morphing.Morphing;
import mchorse.metamorph.entity.SoundHandler;
import mchorse.metamorph.util.InvokeUtil;
import mchorse.metamorph.world.WorldHandler;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
Expand Down Expand Up @@ -782,8 +783,17 @@ protected void updateEntity(EntityLivingBase target)
{
this.entity.setSilent(true);
}

boolean spawnParticles = WorldHandler.shouldSpawnMorphParticles(target);
if (!spawnParticles)
{
// Blaze morphs generate so many particles that it makes it too hard to see in first person
WorldHandler.setEnableWorldParticles(target.world, false);
}
this.entity.onUpdate();
if (!spawnParticles)
{
WorldHandler.setEnableWorldParticles(target.world, true);
}
this.entity.setSilent(false);
}
}
Expand Down
103 changes: 103 additions & 0 deletions src/main/java/mchorse/metamorph/world/WorldEventListenerWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package mchorse.metamorph.world;

import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldEventListener;
import net.minecraft.world.World;

public class WorldEventListenerWrapper implements IWorldEventListener
{
public boolean spawnParticles = true;

protected IWorldEventListener delegate;

public WorldEventListenerWrapper(IWorldEventListener delegate)
{
this.delegate = delegate;
}

@Override
public void notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags)
{
delegate.notifyBlockUpdate(worldIn, pos, oldState, newState, flags);
}

@Override
public void notifyLightSet(BlockPos pos)
{
delegate.notifyLightSet(pos);
}

@Override
public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2)
{
delegate.markBlockRangeForRenderUpdate(x1, y1, z1, x2, y2, z2);
}

@Override
public void playSoundToAllNearExcept(EntityPlayer player, SoundEvent soundIn, SoundCategory category, double x,
double y, double z, float volume, float pitch)
{
delegate.playSoundToAllNearExcept(player, soundIn, category, x, y, z, volume, pitch);
}

@Override
public void playRecord(SoundEvent soundIn, BlockPos pos)
{
delegate.playRecord(soundIn, pos);
}

@Override
public void spawnParticle(int particleID, boolean ignoreRange, double xCoord, double yCoord, double zCoord,
double xSpeed, double ySpeed, double zSpeed, int... parameters)
{
if (spawnParticles)
{
delegate.spawnParticle(particleID, ignoreRange, xCoord, yCoord, zCoord, xSpeed, ySpeed, zSpeed, parameters);
}
}

@Override
public void spawnParticle(int particleID, boolean ignoreRange, boolean p_190570_3_, double xCoord, double yCoord, double zCoord,
double xSpeed, double ySpeed, double zSpeed, int... parameters)
{
if (spawnParticles)
{
delegate.spawnParticle(particleID, ignoreRange, p_190570_3_, xCoord, yCoord, zCoord, xSpeed, ySpeed, zSpeed, parameters);
}
}

@Override
public void onEntityAdded(Entity entityIn)
{
delegate.onEntityAdded(entityIn);
}

@Override
public void onEntityRemoved(Entity entityIn)
{
delegate.onEntityRemoved(entityIn);
}

@Override
public void broadcastSound(int soundID, BlockPos pos, int data)
{
delegate.broadcastSound(soundID, pos, data);
}

@Override
public void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data)
{
delegate.playEvent(player, type, blockPosIn, data);
}

@Override
public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress)
{
delegate.sendBlockBreakProgress(breakerId, pos, progress);
}
}
102 changes: 102 additions & 0 deletions src/main/java/mchorse/metamorph/world/WorldHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package mchorse.metamorph.world;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;

import mchorse.metamorph.Metamorph;
import mchorse.metamorph.util.ObfuscatedName;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.IWorldEventListener;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

/**
* Adds hook to prevent particles spawning in first person
*/
public class WorldHandler
{
public static final ObfuscatedName EVENT_LISTENERS = new ObfuscatedName("field_73021_x");

protected static boolean spawnClientParticles = true;

protected static WeakHashMap<World, List<WorldEventListenerWrapper>> worldListenersClient = new WeakHashMap<>();
protected static WeakHashMap<World, List<WorldEventListenerWrapper>> worldListenersServer = new WeakHashMap<>();

public static List<WorldEventListenerWrapper> getListenersForWorld(World world)
{
WeakHashMap<World, List<WorldEventListenerWrapper>> listenersPerWorld = world.isRemote ? worldListenersClient : worldListenersServer;
List<WorldEventListenerWrapper> ourListeners = listenersPerWorld.get(world);
if (ourListeners == null)
{
ourListeners = new ArrayList<WorldEventListenerWrapper>();
listenersPerWorld.put(world, ourListeners);
try
{
Field eventListenersField = World.class.getDeclaredField(EVENT_LISTENERS.getName());
eventListenersField.setAccessible(true);
@SuppressWarnings("unchecked")
List<IWorldEventListener> vanillaListeners = (List<IWorldEventListener>)eventListenersField.get(world);
int listenerCount = vanillaListeners.size();
for (int i = 0; i < listenerCount; ++i)
{
WorldEventListenerWrapper wrapper = new WorldEventListenerWrapper(vanillaListeners.get(i));
vanillaListeners.set(i, wrapper);
ourListeners.add(wrapper);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
return ourListeners;
}

public static void setEnableWorldParticles(World world, boolean enable) {
List<WorldEventListenerWrapper> worldListeners = getListenersForWorld(world);
for (WorldEventListenerWrapper listener : worldListeners) {
listener.spawnParticles = enable;
}
}

@SubscribeEvent
public void onUpdateClient(ClientTickEvent event)
{
spawnClientParticles = Metamorph.spawnParticlesFirstPerson.get() || !ClientSide.isFirstPerson();
}

public static boolean shouldSpawnMorphParticles(Entity entity)
{
return spawnClientParticles || Metamorph.proxy.isDedicatedServer() || !ClientSide.isThePlayerByID(entity);
}

@SideOnly(Side.CLIENT)
public static class ClientSide
{
public static boolean isFirstPerson()
{
return Minecraft.getMinecraft().gameSettings.thirdPersonView == 0;
}

public static boolean isThePlayerByID(Entity entity)
{
if (entity == null)
{
return false;
}
EntityPlayer thePlayer = Minecraft.getMinecraft().player;
if (thePlayer == null)
{
return false;
}
return entity.getEntityId() == thePlayer.getEntityId();
}
}
}
2 changes: 2 additions & 0 deletions src/main/resources/assets/metamorph/lang/en_US.lang
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ metamorph.config.morphs.morph_in_tight_spaces=Allow morphing in tight spaces
metamorph.config.comments.morphs.morph_in_tight_spaces=Allows morphing even if it could cause suffocation and allow passing through walls
metamorph.config.morphs.show_morph_idle_sounds=Show morph idle sounds
metamorph.config.comments.morphs.show_morph_idle_sounds=Whether players make entity idle sounds when morphed
metamorph.config.morphs.spawn_particles_first_person=Spawn morph particles in first person
metamorph.config.comments.morphs.spawn_particles_first_person=If false, prevents the player's own morph from spawning particles when using the first-person camera.
metamorph.config.morphs.pause_gui_in_sp=Pause morph GUIs
metamorph.config.comments.morphs.pause_gui_in_sp=Whether creative and survival morph GUIs should be paused in singleplayer
metamorph.config.morphs.max_recent_morphs=Max. recent morphs
Expand Down