Added trails, a replacement for our custom capes

This commit is contained in:
Adubbz 2014-06-29 20:11:11 +10:00
parent 80889091fd
commit 68cc87d03b
13 changed files with 589 additions and 9 deletions

View File

@ -8,10 +8,11 @@ import net.minecraft.client.model.ModelSlime;
import net.minecraft.client.particle.EntityBreakingFX;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.entity.RenderSnowball;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import biomesoplenty.api.BOPItemHelper;
import biomesoplenty.api.content.BOPCItems;
import biomesoplenty.client.particles.EntityDandelionFX;
import biomesoplenty.client.particles.EntityFlowerScatterFX;
import biomesoplenty.client.particles.EntityMagicTreeFX;
import biomesoplenty.client.particles.EntityPixieTrailFX;
import biomesoplenty.client.particles.EntitySteamFX;
@ -39,9 +40,7 @@ import biomesoplenty.common.entities.EntityRosester;
import biomesoplenty.common.entities.EntityWasp;
import biomesoplenty.common.entities.projectiles.EntityDart;
import biomesoplenty.common.entities.projectiles.EntityMudball;
import net.minecraftforge.common.MinecraftForge;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
public class ClientProxy extends CommonProxy
{
@ -103,7 +102,7 @@ public class ClientProxy extends CommonProxy
}
@Override
public void spawnParticle(String string, double x, double y, double z)
public void spawnParticle(String string, double x, double y, double z, Object... args)
{
EntityFX entityfx = null;
@ -137,6 +136,10 @@ public class ClientProxy extends CommonProxy
{
entityfx = new EntityPixieTrailFX(minecraft.theWorld, x, y, z, MathHelper.getRandomDoubleInRange(rand, -0.03, 0.03), -0.02D, MathHelper.getRandomDoubleInRange(rand, -0.03, 0.03));
}
else if (string == "flowerscatter")
{
entityfx = new EntityFlowerScatterFX(minecraft.theWorld, x, y, z, (IIcon)args[0]);
}
minecraft.effectRenderer.addEffect(entityfx);
}

View File

@ -25,7 +25,7 @@ public class CommonProxy
{
}
public void spawnParticle(String string, double x, double y, double z)
public void spawnParticle(String string, double x, double y, double z, Object... args)
{
}

View File

@ -0,0 +1,78 @@
package biomesoplenty.client.particles;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;
import biomesoplenty.client.utils.ParticleRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class EntityFlowerScatterFX extends EntityFX
{
private int index;
public EntityFlowerScatterFX(World world, double x, double y, double z, IIcon flowerIcon)
{
super(world, x, y, z, 0.0D, 0.0D, 0.0D);
this.setParticleIcon(flowerIcon);
this.motionX = this.motionY = this.motionZ = 0.0D;
this.particleMaxAge = 550;
this.index = this.rand.nextInt(4);
}
@Override
public void onUpdate()
{
if (this.particleAge++ >= this.particleMaxAge)
{
this.setDead();
}
}
@Override
public void renderParticle(Tessellator tessellator, float partialTickTime, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ)
{
float minU = ((float)this.particleTextureIndexX + this.particleTextureJitterX / 4.0F) / 16.0F;
float maxU = minU + 0.015609375F;
float minV = ((float)this.particleTextureIndexY + this.particleTextureJitterY / 4.0F) / 16.0F;
float maxV = minV + 0.015609375F;
if (this.particleIcon != null)
{
minU = particleIcon.getMinU();
maxU = particleIcon.getMaxU();
minV = particleIcon.getMinV();
maxV = particleIcon.getMaxV();
}
float uMod = (particleIcon.getMaxU() - particleIcon.getMinU()) / 2F;
float vMod = (particleIcon.getMaxV() - particleIcon.getMinV()) / 2F;
if (index % 2 == 0) maxU -= uMod;
else minU += uMod;
if (index < 2) maxV -= vMod;
else minV += vMod;
float alpha = 1.0F - Math.min(1.0F, 2.0F * this.particleAge / this.particleMaxAge);
float width = 0.15F;
float x = (float)(prevPosX + (posX - prevPosX) - interpPosX);
float y = (float)(prevPosY + (posY - prevPosY) - interpPosY);
float z = (float)(prevPosZ + (posZ - prevPosZ) - interpPosZ);
tessellator.setColorRGBA_F(this.particleRed, this.particleGreen, this.particleBlue, alpha);
tessellator.addVertexWithUV(x - width, y, z + width, minU, maxV);
tessellator.addVertexWithUV(x + width, y, z + width, minU, minV);
tessellator.addVertexWithUV(x + width, y, z - width, maxU, minV);
tessellator.addVertexWithUV(x - width, y, z - width, maxU, maxV);
}
@Override
public int getFXLayer()
{
return 2;
}
}

View File

@ -0,0 +1,151 @@
package biomesoplenty.client.utils;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.atomic.AtomicInteger;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.Level;
import biomesoplenty.common.utils.BOPLogger;
import biomesoplenty.common.utils.remote.IVersionChecker;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ExternalTexture extends TextureAtlasSprite
{
private static final AtomicInteger threadDownloadCounter = new AtomicInteger(0);
private final File imageFile;
private final String imageUrl;
private final IVersionChecker versionChecker;
private BufferedImage bufferedImage;
private Thread imageThread;
protected ExternalTexture(File imageFile, String imageUrl, IVersionChecker versionChecker)
{
super("biomesoplenty:" + FilenameUtils.getBaseName(imageUrl));
this.imageFile = imageFile;
this.imageUrl = imageUrl;
this.versionChecker = versionChecker;
if (!imageFile.exists() || versionChecker != null ? !versionChecker.isUpToDate(getBaseName()) : false)
{
this.downloadImage();
}
else
{
try
{
this.bufferedImage = ImageIO.read(this.imageFile);
}
catch (Exception exception)
{
BOPLogger.log(Level.ERROR, "Could not read existing image from: " + imageFile.getAbsolutePath() + ". Attempting redownload.", exception);
this.imageFile.delete();
this.downloadImage();
}
}
}
protected ExternalTexture(File imageFile, String imageUrl)
{
this(imageFile, imageUrl, null);
}
public void setBufferedImage(BufferedImage bufferedImage)
{
this.bufferedImage = bufferedImage;
}
public String getBaseName()
{
return FilenameUtils.getBaseName(this.imageUrl);
}
protected void downloadImage()
{
this.imageThread = new Thread("Texture Downloader #" + threadDownloadCounter.incrementAndGet())
{
public void run()
{
HttpURLConnection httpurlconnection = null;
BOPLogger.log(Level.DEBUG, "Downloading http texture from {} to {}", new Object[] {ExternalTexture.this.imageUrl, ExternalTexture.this.imageFile});
try
{
httpurlconnection = (HttpURLConnection)(new URL(ExternalTexture.this.imageUrl)).openConnection(Minecraft.getMinecraft().getProxy());
httpurlconnection.setDoInput(true);
httpurlconnection.setDoOutput(false);
httpurlconnection.connect();
if (httpurlconnection.getResponseCode() / 100 == 2)
{
BufferedImage bufferedimage;
if (ExternalTexture.this.imageFile != null)
{
FileUtils.copyInputStreamToFile(httpurlconnection.getInputStream(), ExternalTexture.this.imageFile);
bufferedimage = ImageIO.read(ExternalTexture.this.imageFile);
}
else
{
bufferedimage = ImageIO.read(httpurlconnection.getInputStream());
}
ExternalTexture.this.setBufferedImage(bufferedimage);
if (versionChecker != null) versionChecker.markUpToDate(ExternalTexture.this.getBaseName());
return;
}
}
catch (Exception exception)
{
BOPLogger.log(Level.ERROR, "Couldn\'t download http texture", exception);
return;
}
finally
{
if (httpurlconnection != null)
{
httpurlconnection.disconnect();
}
}
}
};
this.imageThread.setDaemon(true);
this.imageThread.start();
}
@Override
public boolean hasCustomLoader(IResourceManager manager, ResourceLocation location)
{
return this.bufferedImage != null;
}
@Override
public boolean load(IResourceManager manager, ResourceLocation location)
{
int mipmapLevels = Minecraft.getMinecraft().gameSettings.mipmapLevels;
BufferedImage[] image = new BufferedImage[1 + mipmapLevels];
image[0] = this.bufferedImage;
this.loadSprite(image, null, (float) Minecraft.getMinecraft().gameSettings.anisotropicFiltering > 1.0F);
//For whatever reason, the call to this is inverted
return false;
}
}

View File

@ -0,0 +1,52 @@
package biomesoplenty.client.utils;
import java.io.File;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureManager;
import org.apache.commons.io.FilenameUtils;
import biomesoplenty.api.BOPObfuscationHelper;
import biomesoplenty.common.utils.remote.IVersionChecker;
import cpw.mods.fml.relauncher.ReflectionHelper;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ExternalTextureManager
{
private static ExternalTextureManager instance;
private final TextureManager textureManager;
private final File bopExternalFiles;
private ExternalTextureManager()
{
this.textureManager = Minecraft.getMinecraft().renderEngine;
this.bopExternalFiles = new File((File)ReflectionHelper.getPrivateValue(Minecraft.class, Minecraft.getMinecraft(), BOPObfuscationHelper.fileAssets), "bopexternal");
}
public ExternalTexture retrieveExternalTexture(String url, String type, IVersionChecker versionChecker)
{
File file1 = new File(this.bopExternalFiles, type);
File file2 = new File(file1, getBaseName(url));
return new ExternalTexture(file2, url, versionChecker);
}
public ExternalTexture retrieveExternalTexture(String url, String type)
{
return this.retrieveExternalTexture(url, type, null);
}
private String getBaseName(String url)
{
return FilenameUtils.getBaseName(url);
}
public static ExternalTextureManager getInstance()
{
return instance == null ? instance = new ExternalTextureManager() : instance;
}
}

View File

@ -0,0 +1,39 @@
package biomesoplenty.client.utils;
import java.util.HashMap;
import biomesoplenty.common.utils.remote.TrailsVersionChecker;
import net.minecraftforge.client.event.TextureStitchEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleRegistry
{
private ExternalTextureManager externalTextureManager;
public static HashMap<String, ExternalTexture> trailMap = new HashMap<String, ExternalTexture>();
public ParticleRegistry()
{
this.externalTextureManager = ExternalTextureManager.getInstance();
TrailsVersionChecker trailsVersionChecker = TrailsVersionChecker.getInstance();
trailMap.put("dev_trail", this.externalTextureManager.retrieveExternalTexture("https://raw.githubusercontent.com/Glitchfiend/BiomesOPlenty/master/trails/dev_trail.png", "trails", trailsVersionChecker));
trailMap.put("donator_trail", this.externalTextureManager.retrieveExternalTexture("https://raw.githubusercontent.com/Glitchfiend/BiomesOPlenty/master/trails/donator_trail.png", "trails", trailsVersionChecker));
trailMap.put("helper_trail", this.externalTextureManager.retrieveExternalTexture("https://raw.githubusercontent.com/Glitchfiend/BiomesOPlenty/master/trails/helper_trail.png", "trails", trailsVersionChecker));
}
@SubscribeEvent
public void onTextureStitch(TextureStitchEvent event)
{
if (event.map.getTextureType() == 1)
{
event.map.setTextureEntry("biomesoplenty:dev_trail", trailMap.get("dev_trail"));
event.map.setTextureEntry("biomesoplenty:donator_trail", trailMap.get("donator_trail"));
event.map.setTextureEntry("biomesoplenty:helper_trail", trailMap.get("helper_trail"));
}
}
}

View File

@ -7,7 +7,6 @@ import net.minecraftforge.common.config.Property;
import org.apache.logging.log4j.Level;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
public class BOPConfigurationMain
@ -15,6 +14,7 @@ public class BOPConfigurationMain
public static Configuration config;
public static boolean debugMode;
public static Property trailsVersion;
public static void init(File configFile)
{
@ -25,6 +25,7 @@ public class BOPConfigurationMain
config.load();
debugMode = config.get("Debug Settings", "Debug Mode", false, "Turn debug mode on/off").getBoolean(false);
trailsVersion = config.get("Versions", "Trail Version", "");
}
catch (Exception e)
{

View File

@ -1,6 +1,8 @@
package biomesoplenty.common.eventhandler;
import net.minecraftforge.common.MinecraftForge;
import biomesoplenty.client.utils.ParticleRegistry;
import biomesoplenty.common.eventhandler.client.FlowerScatterEventHandler;
import biomesoplenty.common.eventhandler.client.gui.MainMenuEventHandler;
import biomesoplenty.common.eventhandler.client.gui.StartupWarningEventHandler;
import biomesoplenty.common.eventhandler.entity.DyeEventHandler;
@ -27,7 +29,7 @@ public class BOPEventHandlers
registerPotionEventHandlers();
registerGUIEventHandlers();
registerMiscEventHandlers();
//registerClientEventHandlers();
registerClientEventHandlers();
}
private static void registerNetworkEventHandlers()
@ -68,9 +70,9 @@ public class BOPEventHandlers
MinecraftForge.EVENT_BUS.register(new BucketEventHandler());
}
/*private static void registerClientEventHandlers()
private static void registerClientEventHandlers()
{
MinecraftForge.EVENT_BUS.register(new ParticleRegistry());
FMLCommonHandler.instance().bus().register(new FlowerScatterEventHandler());
}*/
}
}

View File

@ -0,0 +1,54 @@
package biomesoplenty.common.eventhandler.client;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import biomesoplenty.BiomesOPlenty;
import biomesoplenty.client.utils.ParticleRegistry;
import biomesoplenty.common.utils.remote.FlowerTrailManager;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class FlowerScatterEventHandler
{
private FlowerTrailManager flowerTrailManager;
public FlowerScatterEventHandler()
{
this.flowerTrailManager = FlowerTrailManager.getInstance();
}
@SubscribeEvent
public void playerTick(TickEvent.PlayerTickEvent event)
{
if (event.side == Side.CLIENT && event.phase == Phase.START)
{
EntityPlayer player = event.player;
WorldClient world = Minecraft.getMinecraft().theWorld;
if (flowerTrailManager.hasTrail(player.getUniqueID()))
{
if (player.posX != player.prevPosX || player.posZ != player.prevPosZ)
{
double dx = player.posX + 0.3F - (0.6F * world.rand.nextFloat());
double dy = player.posY - 2;
double dz = player.posZ + 0.3F - (0.6F * world.rand.nextFloat());
int x = MathHelper.floor_double(dx);
int y = MathHelper.floor_double(dy);
int z = MathHelper.floor_double(dz);
if (world.getBlock(x, y, z).isBlockSolid(world, x, y, z, 0))
{
BiomesOPlenty.proxy.spawnParticle("flowerscatter", dx, y + 1.01D, dz, ParticleRegistry.trailMap.get(flowerTrailManager.getTrailType(player.getUniqueID())));
}
}
}
}
}
}

View File

@ -0,0 +1,30 @@
package biomesoplenty.common.utils.remote;
import java.util.UUID;
import com.mojang.util.UUIDTypeAdapter;
public class FlowerTrailManager extends RemoteIdentifierManager
{
private static FlowerTrailManager instance;
protected FlowerTrailManager()
{
super("https://raw.githubusercontent.com/Glitchfiend/BiomesOPlenty/master/trails.txt");
}
public boolean hasTrail(UUID uuid)
{
return this.identifierMap.containsKey(UUIDTypeAdapter.fromUUID(uuid));
}
public String getTrailType(UUID uuid)
{
return this.identifierMap.get(UUIDTypeAdapter.fromUUID(uuid));
}
public static FlowerTrailManager getInstance()
{
return instance == null ? instance = new FlowerTrailManager() : instance;
}
}

View File

@ -0,0 +1,11 @@
package biomesoplenty.common.utils.remote;
public interface IVersionChecker
{
public String getCurrentVersion(Object... args);
public String getVersionString();
public boolean isUpToDate(Object... args);
public void markUpToDate(Object... args);
}

View File

@ -0,0 +1,82 @@
package biomesoplenty.common.utils.remote;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.Level;
import biomesoplenty.common.utils.BOPLogger;
public abstract class RemoteIdentifierManager
{
protected String serverLocation;
protected HashMap<String, String> identifierMap = new HashMap<String, String>();
protected final int timeout = 1000;
protected RemoteIdentifierManager(String serverLocation)
{
this.serverLocation = serverLocation;
retrieve();
}
protected void retrieve()
{
URL url;
try
{
url = new URL(this.serverLocation);
URLConnection connection = url.openConnection();
connection.setConnectTimeout(timeout);
connection.setReadTimeout(timeout);
InputStream io = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(io));
String line;
int linetracker = 1;
while ((line = bufferedReader.readLine()) != null)
{
if (!line.startsWith("//") && !line.isEmpty())
{
if (line.contains(":"))
{
String key = line.substring(0, line.indexOf(":"));
String value = line.substring(line.indexOf(":") + 1);
identifierMap.put(key, value);
}
else
{
BOPLogger.log(Level.WARN, "[" + getFileName() + ".txt] Syntax error on line " + linetracker + ": " + line);
}
}
linetracker++;
}
bufferedReader.close();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public String getFileName()
{
return FilenameUtils.getBaseName(serverLocation);
}
}

View File

@ -0,0 +1,77 @@
package biomesoplenty.common.utils.remote;
import java.util.Map.Entry;
import org.apache.commons.lang3.builder.ToStringBuilder;
import biomesoplenty.common.configuration.BOPConfigurationMain;
public class TrailsVersionChecker extends RemoteIdentifierManager implements IVersionChecker
{
private static TrailsVersionChecker instance;
private TrailsVersionChecker()
{
super("https://raw.githubusercontent.com/Glitchfiend/BiomesOPlenty/master/trails/version.txt");
}
@Override
public String getCurrentVersion(Object... args)
{
String trailsVersion = BOPConfigurationMain.trailsVersion.getString();
if (trailsVersion != null && !trailsVersion.isEmpty())
{
String type = (String)args[0];
String find = trailsVersion.substring(trailsVersion.indexOf(type));
return find.substring(find.indexOf(":") + 1, find.indexOf(";"));
}
return null;
}
@Override
public boolean isUpToDate(Object... args)
{
String key = (String)args[0];
if (this.identifierMap.containsKey(key))
{
String currentVersion = getCurrentVersion(key);
int version = Integer.parseInt(this.identifierMap.get(key));
if (currentVersion != null && Integer.parseInt(currentVersion) == version)
{
return true;
}
}
return false;
}
@Override
public void markUpToDate(Object... args)
{
BOPConfigurationMain.trailsVersion.set(getVersionString());
BOPConfigurationMain.config.save();
}
@Override
public String getVersionString()
{
String versionString = "";
for (Entry<String, String> entry : this.identifierMap.entrySet())
{
versionString += entry.getKey() + ":" + entry.getValue() + ";";
}
return versionString;
}
public static TrailsVersionChecker getInstance()
{
return instance == null ? instance = new TrailsVersionChecker() : instance;
}
}