Merge remote-tracking branch 'forge/master' into objTessellation

This commit is contained in:
MachineMuse 2013-09-03 15:45:45 -06:00
commit 96c045137d
209 changed files with 7308 additions and 2709 deletions

2
.gitignore vendored
View file

@ -5,3 +5,5 @@
/patches-old/
/mcp/
/eclipse/
/target/
/temp/

View file

@ -1,6 +0,0 @@
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.7.0_09-b30 (Oracle Corporation)
Main-Class: net.minecraft.server.MinecraftServer
Class-Path: minecraft_server.jar

View file

@ -24,12 +24,16 @@ class PreemptiveBasicAuthHandler(urllib2.BaseHandler):
def https_request(self,req):
return self.http_request(req)
def getBuildInfo(url, current_version=None):
def read_url(url):
handler = PreemptiveBasicAuthHandler()
handler.add_password(None, 'jenkins.minecraftforge.net:81', 'console_script', 'fd584bffa72fcac12181f37f80001200')
handler.add_password(None, 'ci.jenkins.minecraftforge.net', 'console_script', 'dc6d48ca20a474beeac280a9a16a926e')
file = urllib2.build_opener(handler).open(url)
data = file.read()
file.close()
return data
def getBuildInfo(url, current_version=None):
data = read_url(url)
data = ast.literal_eval(data)['allBuilds']
data = sorted(data, key=lambda key: key['number'], reverse=False)
@ -57,9 +61,29 @@ def getBuildInfo(url, current_version=None):
build.pop('changeSet')
build.pop('actions')
return sorted(output, key=lambda key: key['number'], reverse=True)
def add_latest_build(url, builds, current_version=None):
data = read_url(url)
data = ast.literal_eval(data)
number = data['number']
if builds[0]['number'] == data['number']:
return builds
for item in data['changeSet']['items']:
item['author'] = item['author']['fullName']
build = {
'number' : data['number'],
'result' : 'SUCCESS', #Currently build should always be success... Else things derp after words
'version' : current_version,
'items' : data['changeSet']['items']
}
return [build] + builds
def make_changelog(job_path, target_build, change_file, current_version=None):
builds = getBuildInfo('%s/api/python?tree=allBuilds[result,number,actions[text],changeSet[items[author[fullName],comment]]]&pretty=true' % job_path, current_version)
builds = add_latest_build('%s/lastBuild/api/python?pretty=true&tree=number,changeSet[items[author[fullName],comment]]' % job_path, builds, current_version)
log = [ "Changelog:" ]
@ -86,4 +110,4 @@ def make_changelog(job_path, target_build, change_file, current_version=None):
file.close()
if __name__ == '__main__':
make_changelog("http://jenkins.minecraftforge.net:81/job/minecraftforge/", 70000, 'changelog.txt', 'pinecone')
make_changelog("http://ci.jenkins.minecraftforge.net/job/minecraftforge/", 70000, 'changelog.txt', 'pinecone')

View file

@ -13,62 +13,60 @@ import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.PixelFormat;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.registry.RenderingRegistry;
import net.minecraft.client.Minecraft;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFluid;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.client.texturepacks.ITexturePack;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.ResourceLocation;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.RenderEngine;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraftforge.client.IItemRenderer.ItemRenderType;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.client.event.TextureLoadEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.IArmorTextureProvider;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.RenderBlockFluid;
import static net.minecraftforge.client.IItemRenderer.ItemRenderType.*;
import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.*;
public class ForgeHooksClient
{
static RenderEngine engine()
private static final ResourceLocation ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png");
static TextureManager engine()
{
return FMLClientHandler.instance().getClient().renderEngine;
}
@Deprecated //Deprecated in 1.5.1, move to the more detailed one below.
@SuppressWarnings("deprecation")
public static String getArmorTexture(ItemStack armor, String _default)
@Deprecated
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, int slot, int layer, String type)
{
String result = null;
if (armor.getItem() instanceof IArmorTextureProvider)
{
result = ((IArmorTextureProvider)armor.getItem()).getArmorTextureFile(armor);
}
return getArmorTexture(entity, armor, _default, slot, type);
}
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, int slot, String type)
{
String result = armor.getItem().getArmorTexture(armor, entity, slot, type);
return result != null ? result : _default;
}
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, int slot, int layer)
{
String result = armor.getItem().getArmorTexture(armor, entity, slot, layer);
return result != null ? result : _default;
}
public static boolean renderEntityItem(EntityItem entity, ItemStack item, float bobing, float rotation, Random random, RenderEngine engine, RenderBlocks renderBlocks)
public static boolean renderEntityItem(EntityItem entity, ItemStack item, float bobing, float rotation, Random random, TextureManager engine, RenderBlocks renderBlocks)
{
IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item, ENTITY);
if (customRenderer == null)
@ -86,7 +84,7 @@ public class ForgeHooksClient
}
boolean is3D = customRenderer.shouldUseRenderHelper(ENTITY, item, BLOCK_3D);
engine.bindTexture(item.getItemSpriteNumber() == 0 ? "/terrain.png" : "/gui/items.png");
engine.func_110577_a(item.getItemSpriteNumber() == 0 ? TextureMap.field_110575_b : TextureMap.field_110576_c);
Block block = (item.itemID < Block.blocksList.length ? Block.blocksList[item.itemID] : null);
if (is3D || (block != null && RenderBlocks.renderItemIn3d(block.getRenderType())))
{
@ -101,7 +99,7 @@ public class ForgeHooksClient
}
GL11.glScalef(scale, scale, scale);
int size = item.stackSize;
int count = (size > 40 ? 5 : (size > 20 ? 4 : (size > 5 ? 3 : (size > 1 ? 2 : 1))));
@ -127,7 +125,7 @@ public class ForgeHooksClient
return true;
}
public static boolean renderInventoryItem(RenderBlocks renderBlocks, RenderEngine engine, ItemStack item, boolean inColor, float zLevel, float x, float y)
public static boolean renderInventoryItem(RenderBlocks renderBlocks, TextureManager engine, ItemStack item, boolean inColor, float zLevel, float x, float y)
{
IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item, INVENTORY);
if (customRenderer == null)
@ -135,7 +133,7 @@ public class ForgeHooksClient
return false;
}
engine.bindTexture(item.getItemSpriteNumber() == 0 ? "/terrain.png" : "/gui/items.png");
engine.func_110577_a(item.getItemSpriteNumber() == 0 ? TextureMap.field_110575_b : TextureMap.field_110576_c);
if (customRenderer.shouldUseRenderHelper(INVENTORY, item, INVENTORY_BLOCK))
{
GL11.glPushMatrix();
@ -180,16 +178,15 @@ public class ForgeHooksClient
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_LIGHTING);
}
return true;
}
@Deprecated
public static void renderEquippedItem(IItemRenderer customRenderer, RenderBlocks renderBlocks, EntityLiving entity, ItemStack item)
public static void renderEffectOverlay(TextureManager manager, RenderItem render)
{
renderEquippedItem(ItemRenderType.EQUIPPED, customRenderer, renderBlocks, entity, item);
}
public static void renderEquippedItem(ItemRenderType type, IItemRenderer customRenderer, RenderBlocks renderBlocks, EntityLiving entity, ItemStack item)
public static void renderEquippedItem(ItemRenderType type, IItemRenderer customRenderer, RenderBlocks renderBlocks, EntityLivingBase entity, ItemStack item)
{
if (customRenderer.shouldUseRenderHelper(type, item, EQUIPPED_BLOCK))
{
@ -216,7 +213,7 @@ public class ForgeHooksClient
//Optifine Helper Functions u.u, these are here specifically for Optifine
//Note: When using Optfine, these methods are invoked using reflection, which
//incurs a major performance penalty.
public static void orientBedCamera(Minecraft mc, EntityLiving entity)
public static void orientBedCamera(Minecraft mc, EntityLivingBase entity)
{
int x = MathHelper.floor_double(entity.posX);
int y = MathHelper.floor_double(entity.posY);
@ -240,11 +237,6 @@ public class ForgeHooksClient
MinecraftForge.EVENT_BUS.post(new RenderWorldLastEvent(context, partialTicks));
}
public static void onTextureLoad(String texture, ITexturePack pack)
{
MinecraftForge.EVENT_BUS.post(new TextureLoadEvent(texture, pack));
}
public static void onTextureStitchedPre(TextureMap map)
{
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Pre(map));
@ -253,6 +245,9 @@ public class ForgeHooksClient
public static void onTextureStitchedPost(TextureMap map)
{
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Post(map));
FluidRegistry.WATER.setIcons(BlockFluid.func_94424_b("water_still"), BlockFluid.func_94424_b("water_flow"));
FluidRegistry.LAVA.setIcons(BlockFluid.func_94424_b("lava_still"), BlockFluid.func_94424_b("lava_flow"));
}
/**
@ -285,7 +280,7 @@ public class ForgeHooksClient
renderPass = pass;
}
public static ModelBiped getArmorModel(EntityLiving entityLiving, ItemStack itemStack, int slotID, ModelBiped _default)
public static ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int slotID, ModelBiped _default)
{
ModelBiped modelbiped = itemStack.getItem().getArmorModel(entityLiving, itemStack, slotID);
return modelbiped == null ? _default : modelbiped;
@ -308,4 +303,33 @@ public class ForgeHooksClient
stencilBits = 0;
}
}
//This properly moves the domain, if provided, to the front of the string before concatenating
public static String fixDomain(String base, String complex)
{
int idx = complex.indexOf(':');
if (idx == -1)
{
return base + complex;
}
String name = complex.substring(idx + 1, complex.length());
if (idx > 1)
{
String domain = complex.substring(0, idx);
return domain + ':' + base + name;
}
else
{
return base + name;
}
}
/**
* Initialization of Forge Renderers.
*/
static {
FluidRegistry.renderIdFluid = RenderingRegistry.getNextAvailableRenderId();
RenderingRegistry.registerBlockHandler(RenderBlockFluid.instance);
}
}

View file

@ -9,10 +9,13 @@ import net.minecraft.client.gui.GuiControls;
import net.minecraft.client.gui.GuiSlot;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
public class GuiControlsScrollPanel extends GuiSlot
{
protected static final ResourceLocation WIDGITS = new ResourceLocation("textures/gui/widgets.png");
private GuiControls controls;
private GameSettings options;
private Minecraft mc;
@ -72,7 +75,6 @@ public class GuiControlsScrollPanel extends GuiSlot
{
if (Mouse.next() && Mouse.getEventButtonState())
{
System.out.println(Mouse.getEventButton());
options.setKeyBinding(selected, -100 + Mouse.getEventButton());
selected = -1;
KeyBinding.resetKeyBindingArrayAndHash();
@ -91,7 +93,7 @@ public class GuiControlsScrollPanel extends GuiSlot
boolean flag = _mouseX >= xPosition && _mouseY >= yPosition && _mouseX < xPosition + width && _mouseY < yPosition + height;
int k = (flag ? 2 : 1);
mc.renderEngine.bindTexture("/gui/gui.png");
mc.renderEngine.func_110577_a(WIDGITS);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
controls.drawTexturedModalRect(xPosition, yPosition, 0, 46 + k * 20, width / 2, height);
controls.drawTexturedModalRect(xPosition + width / 2, yPosition, 200 - width / 2, 46 + k * 20, width / 2, height);

View file

@ -1,43 +1,38 @@
package net.minecraftforge.client;
import static net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.*;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import cpw.mods.fml.common.FMLCommonHandler;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiIngame;
import net.minecraft.client.gui.GuiNewChat;
import net.minecraft.client.gui.GuiPlayerInfo;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.multiplayer.NetClientHandler;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.crash.CallableMinecraftVersion;
import net.minecraft.entity.boss.BossStatus;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.AttributeInstance;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Potion;
import net.minecraft.scoreboard.Score;
import net.minecraft.scoreboard.ScoreObjective;
import net.minecraft.scoreboard.ScorePlayerTeam;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.util.Direction;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.FoodStats;
import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraft.util.StringUtils;
import net.minecraft.world.EnumSkyBlock;
@ -46,10 +41,18 @@ import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.MinecraftForge;
import static net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.*;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import cpw.mods.fml.common.FMLCommonHandler;
public class GuiIngameForge extends GuiIngame
{
private static final ResourceLocation VIGNETTE = new ResourceLocation("textures/misc/vignette.png");
private static final ResourceLocation WIDGITS = new ResourceLocation("textures/gui/widgets.png");
private static final ResourceLocation PUMPKIN_BLUR = new ResourceLocation("textures/misc/pumpkinblur.png");
private static final int WHITE = 0xFFFFFF;
//Flags to toggle the rendering of certain aspects of the HUD, valid conditions
@ -63,10 +66,15 @@ public class GuiIngameForge extends GuiIngame
public static boolean renderHealth = true;
public static boolean renderArmor = true;
public static boolean renderFood = true;
public static boolean renderHealthMount = true;
public static boolean renderAir = true;
public static boolean renderExperiance = true;
public static boolean renderJumpBar = true;
public static boolean renderObjective = true;
public static int left_height = 39;
public static int right_height = 39;
private ScaledResolution res = null;
private FontRenderer fontrenderer = null;
private RenderGameOverlayEvent eventParent;
@ -84,6 +92,12 @@ public class GuiIngameForge extends GuiIngame
eventParent = new RenderGameOverlayEvent(partialTicks, res, mouseX, mouseY);
int width = res.getScaledWidth();
int height = res.getScaledHeight();
renderHealthMount = mc.thePlayer.ridingEntity instanceof EntityLivingBase;
renderFood = mc.thePlayer.ridingEntity == null;
renderJumpBar = mc.thePlayer.func_110317_t();
right_height = 39;
left_height = 39;
if (pre(ALL)) return;
@ -112,22 +126,30 @@ public class GuiIngameForge extends GuiIngame
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
zLevel = -90.0F;
rand.setSeed((long)(updateCounter * 312871));
mc.renderEngine.bindTexture("/gui/icons.png");
if (renderCrosshairs) renderCrosshairs(width, height);
if (renderBossHealth) renderBossHealth();
if (this.mc.playerController.shouldDrawHUD())
{
if (renderArmor) renderArmor(width, height);
if (renderHealth) renderHealth(width, height);
if (renderArmor) renderArmor(width, height);
if (renderFood) renderFood(width, height);
if (renderHealthMount) renderHealthMount(width, height);
if (renderAir) renderAir(width, height);
}
if (renderHotbar) renderHotbar(width, height, partialTicks);
}
if (renderExperiance) renderExperience(width, height);
if (renderJumpBar)
{
renderJumpBar(width, height);
}
else if (renderExperiance)
{
renderExperience(width, height);
}
renderSleepFade(width, height);
renderToolHightlight(width, height);
renderHUDText(width, height);
@ -167,7 +189,7 @@ public class GuiIngameForge extends GuiIngame
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.renderEngine.bindTexture("/gui/gui.png");
mc.renderEngine.func_110577_a(WIDGITS);
InventoryPlayer inv = mc.thePlayer.inventory;
drawTexturedModalRect(width / 2 - 91, height - 22, 0, 0, 182, 22);
@ -193,6 +215,7 @@ public class GuiIngameForge extends GuiIngame
protected void renderCrosshairs(int width, int height)
{
if (pre(CROSSHAIRS)) return;
bind(Gui.field_110324_m);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_ONE_MINUS_DST_COLOR, GL11.GL_ONE_MINUS_SRC_COLOR);
drawTexturedModalRect(width / 2 - 7, height / 2 - 7, 0, 0, 16, 16);
@ -237,7 +260,7 @@ public class GuiIngameForge extends GuiIngame
mc.mcProfiler.startSection("armor");
int left = width / 2 - 91;
int top = height - 49;
int top = height - left_height;
int level = ForgeHooks.getTotalArmorValue(mc.thePlayer);
for (int i = 1; level > 0 && i < 20; i += 2)
@ -256,6 +279,7 @@ public class GuiIngameForge extends GuiIngame
}
left += 8;
}
left_height += 10;
mc.mcProfiler.endSection();
post(ARMOR);
@ -269,7 +293,7 @@ public class GuiIngameForge extends GuiIngame
if (f1 > 0.0F)
{
renderPortalOverlay(f1, width, height);
func_130015_b(f1, width, height);
}
post(PORTAL);
@ -280,7 +304,7 @@ public class GuiIngameForge extends GuiIngame
if (pre(AIR)) return;
mc.mcProfiler.startSection("air");
int left = width / 2 + 91;
int top = height - 49;
int top = height - right_height;
if (mc.thePlayer.isInsideOfMaterial(Material.water))
{
@ -292,6 +316,7 @@ public class GuiIngameForge extends GuiIngame
{
drawTexturedModalRect(left - i * 8 - 9, top, (i < full ? 16 : 25), 18, 9, 9);
}
right_height += 10;
}
mc.mcProfiler.endSection();
@ -300,6 +325,7 @@ public class GuiIngameForge extends GuiIngame
public void renderHealth(int width, int height)
{
bind(field_110324_m);
if (pre(HEALTH)) return;
mc.mcProfiler.startSection("health");
@ -310,47 +336,72 @@ public class GuiIngameForge extends GuiIngame
highlight = false;
}
int health = mc.thePlayer.getHealth();
int healthLast = mc.thePlayer.prevHealth;
AttributeInstance attrMaxHealth = this.mc.thePlayer.func_110148_a(SharedMonsterAttributes.field_111267_a);
int health = MathHelper.ceiling_float_int(mc.thePlayer.func_110143_aJ());
int healthLast = MathHelper.ceiling_float_int(mc.thePlayer.prevHealth);
float healthMax = (float)attrMaxHealth.func_111126_e();
float absorb = this.mc.thePlayer.func_110139_bj();
int healthRows = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F / 10.0F);
int rowHeight = Math.max(10 - (healthRows - 2), 3);
this.rand.setSeed((long)(updateCounter * 312871));
int left = width / 2 - 91;
int top = height - 39;
int top = height - left_height;
left_height += (healthRows * rowHeight);
if (rowHeight != 10) left_height += 10 - rowHeight;
int regen = -1;
if (mc.thePlayer.isPotionActive(Potion.regeneration))
{
regen = this.updateCounter % 25;
regen = updateCounter % 25;
}
for (int i = 0; i < 10; ++i)
{
int idx = i * 2 + 1;
int iconX = 16;
if (mc.thePlayer.isPotionActive(Potion.poison)) iconX += 36;
else if (mc.thePlayer.isPotionActive(Potion.wither)) iconX += 72;
final int TOP = 9 * (mc.theWorld.getWorldInfo().isHardcoreModeEnabled() ? 5 : 0);
final int BACKGROUND = (highlight ? 25 : 16);
int MARGIN = 16;
if (mc.thePlayer.isPotionActive(Potion.poison)) MARGIN += 36;
else if (mc.thePlayer.isPotionActive(Potion.wither)) MARGIN += 72;
float absorbRemaining = absorb;
int x = left + i * 8;
int y = top;
if (health <= 4) y = top + rand.nextInt(2);
for (int i = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F) - 1; i >= 0; --i)
{
int b0 = (highlight ? 1 : 0);
int row = MathHelper.ceiling_float_int((float)(i + 1) / 10.0F) - 1;
int x = left + i % 10 * 8;
int y = top - row * rowHeight;
if (health <= 4) y += rand.nextInt(2);
if (i == regen) y -= 2;
byte iconY = 0;
if (mc.theWorld.getWorldInfo().isHardcoreModeEnabled()) iconY = 5;
drawTexturedModalRect(x, y, 16 + (highlight ? 9 : 0), 9 * iconY, 9, 9);
drawTexturedModalRect(x, y, BACKGROUND, TOP, 9, 9);
if (highlight)
{
if (idx < healthLast)
drawTexturedModalRect(x, y, iconX + 54, 9 * iconY, 9, 9);
else if (idx == healthLast)
drawTexturedModalRect(x, y, iconX + 63, 9 * iconY, 9, 9);
if (i * 2 + 1 < healthLast)
drawTexturedModalRect(x, y, MARGIN + 54, TOP, 9, 9); //6
else if (i * 2 + 1 == healthLast)
drawTexturedModalRect(x, y, MARGIN + 63, TOP, 9, 9); //7
}
if (idx < health)
drawTexturedModalRect(x, y, iconX + 36, 9 * iconY, 9, 9);
else if (idx == health)
drawTexturedModalRect(x, y, iconX + 45, 9 * iconY, 9, 9);
if (absorbRemaining > 0.0F)
{
if (absorbRemaining == absorb && absorb % 2.0F == 1.0F)
drawTexturedModalRect(x, y, MARGIN + 153, TOP, 9, 9); //17
else
drawTexturedModalRect(x, y, MARGIN + 144, TOP, 9, 9); //16
absorbRemaining -= 2.0F;
}
else
{
if (i * 2 + 1 < health)
drawTexturedModalRect(x, y, MARGIN + 36, TOP, 9, 9); //4
else if (i * 2 + 1 == health)
drawTexturedModalRect(x, y, MARGIN + 45, TOP, 9, 9); //5
}
}
mc.mcProfiler.endSection();
post(HEALTH);
}
@ -361,7 +412,8 @@ public class GuiIngameForge extends GuiIngame
mc.mcProfiler.startSection("food");
int left = width / 2 + 91;
int top = height - 39;
int top = height - right_height;
right_height += 10;
boolean unused = false;// Unused flag in vanilla, seems to be part of a 'fade out' mechanic
FoodStats stats = mc.thePlayer.getFoodStats();
@ -388,30 +440,20 @@ public class GuiIngameForge extends GuiIngame
y = top + (rand.nextInt(3) - 1);
}
this.drawTexturedModalRect(x, y, 16 + backgound * 9, 27, 9, 9);
drawTexturedModalRect(x, y, 16 + backgound * 9, 27, 9, 9);
if (unused)
{
if (idx < levelLast)
{
drawTexturedModalRect(x, y, icon + 54, 27, 9, 9);
}
if (idx == levelLast)
{
else if (idx == levelLast)
drawTexturedModalRect(x, y, icon + 63, 27, 9, 9);
}
}
if (idx < level)
{
drawTexturedModalRect(x, y, icon + 36, 27, 9, 9);
}
if (idx == level)
{
else if (idx == level)
drawTexturedModalRect(x, y, icon + 45, 27, 9, 9);
}
}
mc.mcProfiler.endSection();
post(FOOD);
@ -442,50 +484,79 @@ public class GuiIngameForge extends GuiIngame
protected void renderExperience(int width, int height)
{
bind(field_110324_m);
if (pre(EXPERIENCE)) return;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
if (mc.playerController.shouldDrawHUD())
if (mc.playerController.func_78763_f())
{
mc.mcProfiler.startSection("expBar");
mc.renderEngine.bindTexture("/gui/icons.png");
int cap = this.mc.thePlayer.xpBarCap();
int left = width / 2 - 91;
if (cap > 0)
{
short short1 = 182;
int l2 = (int)(this.mc.thePlayer.experience * (float)(short1 + 1));
int k2 = height - 32 + 3;
this.drawTexturedModalRect(left, k2, 0, 64, short1, 5);
short barWidth = 182;
int filled = (int)(mc.thePlayer.experience * (float)(barWidth + 1));
int top = height - 32 + 3;
drawTexturedModalRect(left, top, 0, 64, barWidth, 5);
if (l2 > 0)
if (filled > 0)
{
this.drawTexturedModalRect(left, k2, 0, 69, l2, 5);
drawTexturedModalRect(left, top, 0, 69, filled, 5);
}
}
mc.mcProfiler.endSection();
}
if (mc.playerController.func_78763_f() && mc.thePlayer.experienceLevel > 0)
{
mc.mcProfiler.startSection("expLevel");
boolean flag1 = false;
int color = flag1 ? 16777215 : 8453920;
String text = "" + mc.thePlayer.experienceLevel;
int x = (width - fontrenderer.getStringWidth(text)) / 2;
int y = height - 31 - 4;
fontrenderer.drawString(text, x + 1, y, 0);
fontrenderer.drawString(text, x - 1, y, 0);
fontrenderer.drawString(text, x, y + 1, 0);
fontrenderer.drawString(text, x, y - 1, 0);
fontrenderer.drawString(text, x, y, color);
mc.mcProfiler.endSection();
this.mc.mcProfiler.endSection();
if (mc.playerController.func_78763_f() && mc.thePlayer.experienceLevel > 0)
{
mc.mcProfiler.startSection("expLevel");
boolean flag1 = false;
int color = flag1 ? 16777215 : 8453920;
String text = "" + mc.thePlayer.experienceLevel;
int x = (width - fontrenderer.getStringWidth(text)) / 2;
int y = height - 31 - 4;
fontrenderer.drawString(text, x + 1, y, 0);
fontrenderer.drawString(text, x - 1, y, 0);
fontrenderer.drawString(text, x, y + 1, 0);
fontrenderer.drawString(text, x, y - 1, 0);
fontrenderer.drawString(text, x, y, color);
mc.mcProfiler.endSection();
}
}
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
post(EXPERIENCE);
}
protected void renderJumpBar(int width, int height)
{
bind(field_110324_m);
if (pre(JUMPBAR)) return;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.mcProfiler.startSection("jumpBar");
float charge = mc.thePlayer.func_110319_bJ();
final int barWidth = 182;
int x = (width / 2) - (barWidth / 2);
int filled = (int)(charge * (float)(barWidth + 1));
int top = height - 32 + 3;
drawTexturedModalRect(x, top, 0, 84, barWidth, 5);
if (filled > 0)
{
this.drawTexturedModalRect(x, top, 0, 89, filled, 5);
}
mc.mcProfiler.endSection();
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
post(JUMPBAR);
}
protected void renderToolHightlight(int width, int height)
{
if (this.mc.gameSettings.heldItemTooltips)
@ -701,7 +772,7 @@ public class GuiIngameForge extends GuiIngame
{
GuiPlayerInfo player = (GuiPlayerInfo)players.get(i);
ScorePlayerTeam team = mc.theWorld.getScoreboard().getPlayersTeam(player.name);
String displayName = ScorePlayerTeam.func_96667_a(team, player.name);
String displayName = ScorePlayerTeam.formatPlayerName(team, player.name);
fontrenderer.drawStringWithShadow(displayName, xPos, yPos, 16777215);
if (scoreobjective != null)
@ -712,14 +783,14 @@ public class GuiIngameForge extends GuiIngame
if (maxX - endX > 5)
{
Score score = scoreobjective.getScoreboard().func_96529_a(player.name, scoreobjective);
String scoreDisplay = EnumChatFormatting.YELLOW + "" + score.func_96652_c();
String scoreDisplay = EnumChatFormatting.YELLOW + "" + score.getScorePoints();
fontrenderer.drawStringWithShadow(scoreDisplay, maxX - fontrenderer.getStringWidth(scoreDisplay), yPos, 16777215);
}
}
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.renderEngine.bindTexture("/gui/icons.png");
mc.func_110434_K().func_110577_a(Gui.field_110324_m);
int pingIndex = 4;
int ping = player.responseTime;
if (ping < 0) pingIndex = 5;
@ -736,6 +807,54 @@ public class GuiIngameForge extends GuiIngame
}
}
protected void renderHealthMount(int width, int height)
{
Entity tmp = mc.thePlayer.ridingEntity;
if (!(tmp instanceof EntityLivingBase)) return;
bind(field_110324_m);
if (pre(HEALTHMOUNT)) return;
boolean unused = false;
int left_align = width / 2 + 91;
mc.mcProfiler.endStartSection("mountHealth");
EntityLivingBase mount = (EntityLivingBase)tmp;
int health = (int)Math.ceil((double)mount.func_110143_aJ());
float healthMax = mount.func_110138_aP();
int hearts = (int)(healthMax + 0.5F) / 2;
if (hearts > 30) hearts = 30;
final int MARGIN = 52;
final int BACKGROUND = MARGIN + (unused ? 1 : 0);
final int HALF = MARGIN + 45;
final int FULL = MARGIN + 36;
for (int heart = 0; hearts > 0; heart += 20)
{
int top = height - right_height;
int rowCount = Math.min(hearts, 10);
hearts -= rowCount;
for (int i = 0; i < rowCount; ++i)
{
int x = left_align - i * 8 - 9;
drawTexturedModalRect(x, top, BACKGROUND, 9, 9, 9);
if (i * 2 + 1 + heart < health)
drawTexturedModalRect(x, top, FULL, 9, 9, 9);
else if (i * 2 + 1 + heart == health)
drawTexturedModalRect(x, top, HALF, 9, 9, 9);
}
right_height += 10;
}
post(HEALTHMOUNT);
}
//Helper macros
private boolean pre(ElementType type)
{
@ -745,4 +864,8 @@ public class GuiIngameForge extends GuiIngame
{
MinecraftForge.EVENT_BUS.post(new RenderGameOverlayEvent.Post(eventParent, type));
}
private void bind(ResourceLocation res)
{
mc.func_110434_K().func_110577_a(res);
}
}

View file

@ -20,15 +20,6 @@ import net.minecraftforge.common.MinecraftForge;
public class MinecraftForgeClient
{
/**
* NO-OP now. Not needed with new texturing system in MC 1.5
*/
@Deprecated // without replacement
public static void preloadTexture(String texture)
{
// ForgeHooksClient.engine().getTexture(texture);
}
private static IItemRenderer[] customItemRenderers = new IItemRenderer[Item.itemsList.length];
/**

View file

@ -1,278 +0,0 @@
package net.minecraftforge.client;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.logging.Level;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.FMLLog;
import paulscode.sound.SoundSystemConfig;
import paulscode.sound.codecs.CodecIBXM;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.audio.SoundPool;
import net.minecraft.client.audio.SoundPoolEntry;
import net.minecraft.entity.Entity;
import net.minecraft.network.packet.Packet100OpenWindow;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class ModCompatibilityClient
{
/**
* Tries to get the class for the specified name, will also try the
* net.minecraft.src package in case we are in MCP
* Returns null if not found.
*
* @param name The class name
* @return The Class, or null if not found
*/
private static Class getClass(String name)
{
try
{
return Class.forName(name);
}
catch (Exception e)
{
try
{
return Class.forName("net.minecraft.src." + name);
}
catch (Exception e2)
{
return null;
}
}
}
/************************************************************************************************
* Risugami's AudioMod Compatibility
* http://www.minecraftforum.net/topic/75440-
*
* AudioMod adds a few extra codecs, loads audio from /resources/mods/*,
* introduces the concept of 'cave' sounds, which are determined by if
* the player is underneath a solid block.
*
* It also lowers the interval between background music songs to 6000
*/
public static SoundPool audioModSoundPoolCave;
/**
* Populates the sound pools with with sounds from the /resources/mods folder
* And sets the interval between background music to 6000
*
* @param mngr The SoundManager instance
*/
public static void audioModLoad(SoundManager mngr)
{
audioModSoundPoolCave = new SoundPool();
audioModLoadModAudio("resources/mod/sound", mngr.soundPoolSounds);
audioModLoadModAudio("resources/mod/streaming", mngr.soundPoolStreaming);
audioModLoadModAudio("resources/mod/music", mngr.soundPoolMusic);
audioModLoadModAudio("resources/mod/cavemusic", audioModSoundPoolCave);
if (mngr.MUSIC_INTERVAL == 12000)
{
mngr.MUSIC_INTERVAL = 6000;
}
}
/**
* Walks the given path in the Minecraft app directory and adds audio to the SoundPool
*
* @param path The path to walk
* @param pool The pool to add sound to
*/
private static void audioModLoadModAudio(String path, SoundPool pool)
{
File folder = new File(Minecraft.getMinecraftDir(), path);
try
{
audioModWalkFolder(folder, folder, pool);
}
catch (IOException ex)
{
FMLLog.log(Level.FINE, ex, "Loading Mod audio failed for folder: %s", path);
ex.printStackTrace();
}
}
/**
* Walks the folder path recursively and calls pool.addSound on any file it finds.
*
* @param base The base path for the folder, determines the name when calling addSound
* @param folder The current folder
* @param pool The SoundPool to add the sound to
* @throws IOException
*/
private static void audioModWalkFolder(File base, File folder, SoundPool pool) throws IOException
{
if (folder.exists() || folder.mkdirs())
{
for (File file : folder.listFiles())
{
if (!file.getName().startsWith("."))
{
if (file.isDirectory())
{
audioModWalkFolder(base, file, pool);
}
else if (file.isFile())
{
String subpath = file.getPath().substring(base.getPath().length() + 1).replace('\\', '/');
pool.addSound(subpath, file);
}
}
}
}
}
/**
* Adds the IBXM codec and associates it with .xm, .s3m, and .mod
*/
public static void audioModAddCodecs()
{
SoundSystemConfig.setCodec("xm", CodecIBXM.class);
SoundSystemConfig.setCodec("s3m", CodecIBXM.class);
SoundSystemConfig.setCodec("mod", CodecIBXM.class);
}
/**
* If the current player is underground, it picks a random song from the cave sound pool,
* if they are not it returns the passed in entry.
*
* @param soundManager The SoundManager instance
* @param current The currently selected entry
* @return A soundPool entry to be played as the background music
*/
public static SoundPoolEntry audioModPickBackgroundMusic(SoundManager soundManager, SoundPoolEntry current)
{
Minecraft mc = FMLClientHandler.instance().getClient();
if (mc != null && mc.theWorld != null && audioModSoundPoolCave != null)
{
Entity ent = mc.renderViewEntity;
int x = MathHelper.truncateDoubleToInt(ent.posX);
int y = MathHelper.truncateDoubleToInt(ent.posY);
int z = MathHelper.truncateDoubleToInt(ent.posZ);
return (mc.theWorld.canBlockSeeTheSky(x, y, z) ? current : audioModSoundPoolCave.getRandomSound());
}
return current;
}
/***********************************************************************************************************
* SDK's ModLoaderMP
* http://www.minecraftforum.net/topic/86765-
*
* ModLoaderMP was supposed to be a reliable server side version of ModLoader, however it has
* gotten the reputation of being really slow to update. Never having bugfixes, breaking compatibility
* with the client side ModLoader.
*
* So we have replaced it with our own system called FML (Forge ModLoader)
* it is a stand alone mod, that Forge relies on, and that is open source/community driven.
* https://github.com/cpw/FML
*
* However, for compatibilities sake, we provide the ModLoaderMP's hooks so that the end user
* does not need to make a choice between the two on the client side.
**/
private static int isMLMPInstalled = -1;
/**
* Determine if ModLoaderMP is installed by checking for the existence of the BaseModMp class.
* @return True if BaseModMp was installed (indicating the existance of MLMP)
*/
public static boolean isMLMPInstalled()
{
if (isMLMPInstalled == -1)
{
isMLMPInstalled = (getClass("ModLoaderMp") != null ? 1 : 0);
}
return isMLMPInstalled == 1;
}
/**
* Attempts to spawn a vehicle using ModLoaderMP's vehicle spawn registry, if MLMP is not installed
* it returns the passed in currentEntity
*
* @param type The Type ID of the vehicle
* @param world The current world
* @param x The spawn X position
* @param y The spawn Y position
* @param z The spawn Z position
* @param thrower The entity that spawned the vehicle {possibly null}
* @param currentEntity The current value to return if MLMP is not installed
* @return The new spawned entity
* @throws Exception
*/
public static Object mlmpVehicleSpawn(int type, World world, double x, double y, double z, Entity thrower, Object currentEntity) throws Exception
{
Class mlmp = getClass("ModLoaderMp");
if (!isMLMPInstalled() || mlmp == null)
{
return currentEntity;
}
Object entry = mlmp.getDeclaredMethod("handleNetClientHandlerEntities", int.class).invoke(null, type);
if (entry == null)
{
return currentEntity;
}
Class entityClass = (Class)entry.getClass().getDeclaredField("entityClass").get(entry);
Object ret = (Entity)entityClass.getConstructor(World.class, Double.TYPE, Double.TYPE, Double.TYPE).newInstance(world, x, y, z);
if (entry.getClass().getDeclaredField("entityHasOwner").getBoolean(entry))
{
Field owner = entityClass.getField("owner");
if (!Entity.class.isAssignableFrom(owner.getType()))
{
throw new Exception(String.format("Entity\'s owner field must be of type Entity, but it is of type %s.", owner.getType()));
}
if (thrower == null)
{
System.out.println("Received spawn packet for entity with owner, but owner was not found.");
FMLLog.fine("Received spawn packet for entity with owner, but owner was not found.");
}
else
{
if (!owner.getType().isAssignableFrom(thrower.getClass()))
{
throw new Exception(String.format("Tried to assign an entity of type %s to entity owner, which is of type %s.", thrower.getClass(), owner.getType()));
}
owner.set(ret, thrower);
}
}
return ret;
}
/**
* Attempts to invoke ModLoaderMp.handleGUI if ModLoaderMP is installed.
* If not, it does nothing
*
* @param pkt The open window packet
*/
public static void mlmpOpenWindow(Packet100OpenWindow pkt)
{
Class mlmp = getClass("ModLoaderMp");
if (!isMLMPInstalled() || mlmp == null)
{
return;
}
try
{
mlmp.getDeclaredMethod("handleGUI", Packet100OpenWindow.class).invoke(null, pkt);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

View file

@ -22,7 +22,9 @@ public class RenderGameOverlayEvent extends Event
AIR,
HOTBAR,
EXPERIENCE,
TEXT
TEXT,
HEALTHMOUNT,
JUMPBAR
}
public final float partialTicks;

View file

@ -1,35 +1,43 @@
package net.minecraftforge.client.event;
import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.client.renderer.entity.RenderPlayer;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.client.renderer.entity.RendererLivingEntity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
public abstract class RenderLivingEvent extends Event
{
public final EntityLiving entity;
public final RenderLiving renderer;
public final EntityLivingBase entity;
public final RendererLivingEntity renderer;
public RenderLivingEvent(EntityLiving entity, RenderLiving renderer)
public RenderLivingEvent(EntityLivingBase entity, RendererLivingEntity renderer)
{
this.entity = entity;
this.renderer = renderer;
}
@Cancelable
public static class Pre extends RenderLivingEvent
{
public Pre(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
}
public static class Post extends RenderLivingEvent
{
public Post(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
}
public abstract static class Specials extends RenderLivingEvent
{
public Specials(EntityLiving entity, RenderLiving renderer){ super(entity, renderer); }
public Specials(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
@Cancelable
public static class Pre extends Specials
{
public Pre(EntityLiving entity, RenderLiving renderer){ super(entity, renderer); }
public Pre(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
}
public static class Post extends Specials
{
public Post(EntityLiving entity, RenderLiving renderer){ super(entity, renderer); }
public Post(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
}
}
}

View file

@ -1,17 +0,0 @@
package net.minecraftforge.client.event;
import net.minecraft.client.texturepacks.ITexturePack;
import net.minecraftforge.event.Event;
public class TextureLoadEvent extends Event
{
public final String texture;
public final ITexturePack pack;
public TextureLoadEvent(String texture, ITexturePack pack)
{
this.texture = texture;
this.pack = pack;
}
}

View file

@ -6,6 +6,7 @@ import java.util.Collection;
import java.util.Map;
import net.minecraftforge.client.model.obj.ObjModelLoader;
import net.minecraftforge.client.model.techne.TechneModelLoader;
import com.google.common.collect.Maps;
@ -78,5 +79,6 @@ public class AdvancedModelLoader {
static
{
registerModelHandler(new ObjModelLoader());
registerModelHandler(new TechneModelLoader());
}
}

View file

@ -49,20 +49,32 @@ public class WavefrontObject implements IModelCustom
public WavefrontObject(String fileName, URL resource) throws ModelFormatException
{
this.fileName = fileName;
loadObjModel(resource);
try
{
loadObjModel(resource.openStream());
}
catch (IOException e)
{
throw new ModelFormatException("IO Exception reading model format", e);
}
}
public WavefrontObject(String filename, InputStream inputStream) throws ModelFormatException
{
this.fileName = filename;
loadObjModel(inputStream);
}
private void loadObjModel(URL fileURL) throws ModelFormatException
private void loadObjModel(InputStream inputStream) throws ModelFormatException
{
BufferedReader reader = null;
InputStream inputStream = null;
String currentLine = null;
int lineCount = 0;
try
{
inputStream = fileURL.openStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
while ((currentLine = reader.readLine()) != null)

View file

@ -0,0 +1,301 @@
package net.minecraftforge.client.model.techne;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.lwjgl.opengl.GL11;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraftforge.client.model.IModelCustom;
import net.minecraftforge.client.model.ModelFormatException;
/**
* Techne model importer, based on iChun's Hats importer
*/
@SideOnly(Side.CLIENT)
public class TechneModel extends ModelBase implements IModelCustom {
public static final List<String> cubeTypes = Arrays.asList(
"d9e621f7-957f-4b77-b1ae-20dcd0da7751",
"de81aa14-bd60-4228-8d8d-5238bcd3caaa"
);
private String fileName;
private Map<String, byte[]> zipContents = new HashMap<String, byte[]>();
private Map<String, ModelRenderer> parts = new LinkedHashMap<String, ModelRenderer>();
private String texture = null;
private int textureName;
private boolean textureNameSet = false;
public TechneModel(String fileName, URL resource) throws ModelFormatException
{
this.fileName = fileName;
loadTechneModel(resource);
}
private void loadTechneModel(URL fileURL) throws ModelFormatException
{
try
{
ZipInputStream zipInput = new ZipInputStream(fileURL.openStream());
ZipEntry entry;
while ((entry = zipInput.getNextEntry()) != null)
{
byte[] data = new byte[(int) entry.getSize()];
// For some reason, using read(byte[]) makes reading stall upon reaching a 0x1E byte
int i = 0;
while (zipInput.available() > 0 && i < data.length)
{
data[i++] = (byte)zipInput.read();
}
zipContents.put(entry.getName(), data);
}
byte[] modelXml = zipContents.get("model.xml");
if (modelXml == null)
{
throw new ModelFormatException("Model " + fileName + " contains no model.xml file");
}
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(new ByteArrayInputStream(modelXml));
NodeList nodeListTechne = document.getElementsByTagName("Techne");
if (nodeListTechne.getLength() < 1)
{
throw new ModelFormatException("Model " + fileName + " contains no Techne tag");
}
NodeList nodeListModel = document.getElementsByTagName("Model");
if (nodeListModel.getLength() < 1)
{
throw new ModelFormatException("Model " + fileName + " contains no Model tag");
}
NamedNodeMap modelAttributes = nodeListModel.item(0).getAttributes();
if (modelAttributes == null)
{
throw new ModelFormatException("Model " + fileName + " contains a Model tag with no attributes");
}
Node modelTexture = modelAttributes.getNamedItem("texture");
if (modelTexture != null)
{
texture = modelTexture.getTextContent();
}
NodeList shapes = document.getElementsByTagName("Shape");
for (int i = 0; i < shapes.getLength(); i++)
{
Node shape = shapes.item(i);
NamedNodeMap shapeAttributes = shape.getAttributes();
if (shapeAttributes == null)
{
throw new ModelFormatException("Shape #" + (i + 1) + " in " + fileName + " has no attributes");
}
Node name = shapeAttributes.getNamedItem("name");
String shapeName = null;
if (name != null)
{
shapeName = name.getNodeValue();
}
if (shapeName == null)
{
shapeName = "Shape #" + (i + 1);
}
String shapeType = null;
Node type = shapeAttributes.getNamedItem("type");
if (type != null)
{
shapeType = type.getNodeValue();
}
if (shapeType != null && !cubeTypes.contains(shapeType))
{
FMLLog.warning("Model shape [" + shapeName + "] in " + fileName + " is not a cube, ignoring");
continue;
}
try
{
boolean mirrored = false;
String[] offset = new String[3];
String[] position = new String[3];
String[] rotation = new String[3];
String[] size = new String[3];
String[] textureOffset = new String[2];
NodeList shapeChildren = shape.getChildNodes();
for (int j = 0; j < shapeChildren.getLength(); j++)
{
Node shapeChild = shapeChildren.item(j);
String shapeChildName = shapeChild.getNodeName();
String shapeChildValue = shapeChild.getTextContent();
if (shapeChildValue != null)
{
shapeChildValue = shapeChildValue.trim();
if (shapeChildName.equals("IsMirrored"))
{
mirrored = !shapeChildValue.equals("False");
}
else if (shapeChildName.equals("Offset"))
{
offset = shapeChildValue.split(",");
}
else if (shapeChildName.equals("Position"))
{
position = shapeChildValue.split(",");
}
else if (shapeChildName.equals("Rotation"))
{
rotation = shapeChildValue.split(",");
}
else if (shapeChildName.equals("Size"))
{
size = shapeChildValue.split(",");
}
else if (shapeChildName.equals("TextureOffset"))
{
textureOffset = shapeChildValue.split(",");
}
}
}
// That's what the ModelBase subclassing is needed for
ModelRenderer cube = new ModelRenderer(this, Integer.parseInt(textureOffset[0]), Integer.parseInt(textureOffset[1]));
cube.mirror = mirrored;
cube.addBox(Float.parseFloat(offset[0]), Float.parseFloat(offset[1]), Float.parseFloat(offset[2]), Integer.parseInt(size[0]), Integer.parseInt(size[1]), Integer.parseInt(size[2]));
cube.setRotationPoint(Float.parseFloat(position[0]), Float.parseFloat(position[1]) - 23.4F, Float.parseFloat(position[2]));
cube.rotateAngleX = (float)Math.toRadians(Float.parseFloat(rotation[0]));
cube.rotateAngleY = (float)Math.toRadians(Float.parseFloat(rotation[1]));
cube.rotateAngleZ = (float)Math.toRadians(Float.parseFloat(rotation[2]));
parts.put(shapeName, cube);
}
catch (NumberFormatException e)
{
FMLLog.warning("Model shape [" + shapeName + "] in " + fileName + " contains malformed integers within its data, ignoring");
e.printStackTrace();
}
}
}
catch (ZipException e)
{
throw new ModelFormatException("Model " + fileName + " is not a valid zip file");
}
catch (IOException e)
{
throw new ModelFormatException("Model " + fileName + " could not be read", e);
}
catch (ParserConfigurationException e)
{
// hush
}
catch (SAXException e)
{
throw new ModelFormatException("Model " + fileName + " contains invalid XML", e);
}
}
private void bindTexture()
{
/* TODO: Update to 1.6
if (texture != null)
{
if (!textureNameSet)
{
try
{
byte[] textureEntry = zipContents.get(texture);
if (textureEntry == null)
{
throw new ModelFormatException("Model " + fileName + " has no such texture " + texture);
}
BufferedImage image = ImageIO.read(new ByteArrayInputStream(textureEntry));
textureName = Minecraft.getMinecraft().renderEngine.allocateAndSetupTexture(image);
textureNameSet = true;
}
catch (ZipException e)
{
throw new ModelFormatException("Model " + fileName + " is not a valid zip file");
}
catch (IOException e)
{
throw new ModelFormatException("Texture for model " + fileName + " could not be read", e);
}
}
if (textureNameSet)
{
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureName);
Minecraft.getMinecraft().renderEngine.resetBoundTexture();
}
}
*/
}
@Override
public String getType()
{
return "tcn";
}
@Override
public void renderAll()
{
bindTexture();
for (ModelRenderer part : parts.values())
{
part.renderWithRotation(1.0F);
}
}
@Override
public void renderPart(String partName)
{
ModelRenderer part = parts.get(partName);
if (part != null)
{
bindTexture();
part.renderWithRotation(1.0F);
}
}
}

View file

@ -0,0 +1,33 @@
package net.minecraftforge.client.model.techne;
import java.net.URL;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraftforge.client.model.IModelCustom;
import net.minecraftforge.client.model.IModelCustomLoader;
import net.minecraftforge.client.model.ModelFormatException;
public class TechneModelLoader implements IModelCustomLoader {
@Override
public String getType()
{
return "Techne model";
}
private static final String[] types = { "tcn" };
@Override
public String[] getSuffixes()
{
return types;
}
@Override
public IModelCustom loadInstance(String resourceName, URL resource) throws ModelFormatException
{
return new TechneModel(resourceName, resource);
}
}

View file

@ -0,0 +1,5 @@
commands.forge.usage=Use /forge <subcommand>. Subcommands are tps, track
commands.forge.usage.tracking=Use /forge track <type> <duration>. Valid types are te (Tile Entities). Duration is < 60.
commands.forge.tps.summary=%s : Mean tick time: %d ms. Mean TPS: %d
commands.forge.tracking.te.enabled=Tile Entity tracking enabled for %d seconds.

View file

@ -1,158 +1,165 @@
#Main Forge Access Transformer configuration file
# Tessellator
public-f bgd.a #FD:Tessellator/field_78398_a #instance
public bgd.u #FD:Tessellator/field_78409_u #drawMode
public bgd.v #FD:Tessellator/field_78408_v #xOffset
public bgd.w #FD:Tessellator/field_78407_w #yOffset
public bgd.x #FD:Tessellator/field_78417_x #zOffset
public bgd.z #FD:Tessellator/field_78415_z #isDrawing
public-f bfn.a #FD:Tessellator/field_78398_a #instance
public bfn.u #FD:Tessellator/field_78409_u #drawMode
public bfn.v #FD:Tessellator/field_78408_v #xOffset
public bfn.w #FD:Tessellator/field_78407_w #yOffset
public bfn.x #FD:Tessellator/field_78417_x #zOffset
public bfn.z #FD:Tessellator/field_78415_z #isDrawing
# ItemPickaxe
public wu.<init>(ILwl;)V #MD:ItemPickaxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f wu.c #FD:ItemPickaxe/field_77867_c #blocksEffectiveAgainst
public ym.<init>(ILyc;)V #MD:ItemPickaxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f ym.c #FD:ItemPickaxe/field_77867_c #blocksEffectiveAgainst
# ItemAxe
public wi.<init>(ILwl;)V #MD:ItemAxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f wi.c #FD:ItemAxe/field_77868_c #blocksEffectiveAgainst
public xz.<init>(ILyc;)V #MD:ItemAxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f xz.c #FD:ItemAxe/field_77868_c #blocksEffectiveAgainst
# ItemSpade
public xf.<init>(ILwl;)V #MD:ItemSpade/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f xf.c #FD:ItemSpade/field_77866_c #blocksEffectiveAgainst
public yx.<init>(ILyc;)V #MD:ItemSpade/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f yx.c #FD:ItemSpade/field_77866_c #blocksEffectiveAgainst
# ItemTool
public vr.a #FD:ItemTool/field_77864_a #efficiencyOnProperMaterial
public vr.d #FD:ItemTool/field_77865_bY #damageVsEntity
public xi.a #FD:ItemTool/field_77864_a #efficiencyOnProperMaterial
public xi.d #FD:ItemTool/field_77865_bY #damageVsEntity
# EntityEnderman
public rv.d #FD:EntityEnderman/field_70827_d #carriableBlocks
public tf.br #FD:EntityEnderman/field_70827_d #carriableBlocks
# RenderEngine
public bge.f(Ljava/lang/String;)I #MD:RenderEngine/func_78341_b #getTexture
public bge.i #FD:RenderEngine/field_94154_l #terrainTextureMap
public bge.j #FD:RenderEngine/field_94155_m #itemTextureMap
# -- MISSING MAPPING public bge.f(Ljava/lang/String;)I #MD:RenderEngine/func_78341_b #getTexture
# -- MISSING MAPPING public bge.i #FD:RenderEngine/field_94154_l #terrainTextureMap
# -- MISSING MAPPING public bge.j #FD:RenderEngine/field_94155_m #itemTextureMap
# RenderGlobal
public bfy.h #FD:RenderGlobal/field_72769_h #theWorld
public bfy.i #FD:RenderGlobal/field_72770_i #renderEngine
public bfy.q #FD:RenderGlobal/field_72777_q #mc
public bfy.r #FD:RenderGlobal/field_72776_r #globalRenderBlocks
public bfy.E #FD:RenderGlobal/field_72738_E #damagedBlocks
public bfi.k #FD:RenderGlobal/field_72769_h #theWorld
public bfi.l #FD:RenderGlobal/field_72770_i #renderEngine
public bfi.t #FD:RenderGlobal/field_72777_q #mc
public bfi.u #FD:RenderGlobal/field_72776_r #globalRenderBlocks
public bfi.H #FD:RenderGlobal/field_72738_E #damagedBlocks
# SoundManager
public bkc.a #FD:SoundManager/field_77381_a #sndSystem
public bkc.b #FD:SoundManager/field_77379_b #soundPoolSounds
public bkc.c #FD:SoundManager/field_77380_c #soundPoolStreaming
public bkc.d #FD:SoundManager/field_77377_d #soundPoolMusic
public blk.b #FD:SoundManager/field_77381_a #sndSystem
public blk.d #FD:SoundManager/field_77379_b #soundPoolSounds
public blk.e #FD:SoundManager/field_77380_c #soundPoolStreaming
public blk.f #FD:SoundManager/field_77377_d #soundPoolMusic
# EntityMinecart
protected ri.* #FD:EntityMinecart/* # All private -> protected
protected ss.* #FD:EntityMinecart/* # All private -> protected
# -- MISSING MAPPING public py.h()Z #MD:EntityMinecart/func_70490_h #isMinecartPowered
# Block
public apa.<init>(ILaif;)V #MD:Block/<init>(ILnet/minecraft/src/Material;) #Constructor
public apa.<init>(IILaif;)V #MD:Block/<init>(IILnet/minecraft/src/Material;) #Constructor
public apa.cB #FD:Block/field_72029_cc #blockResistance
public apa.cA #FD:Block/field_71989_cb #blockHardness
public aqw.<init>(ILajz;)V #MD:Block/<init>(ILnet/minecraft/src/Material;) #Constructor
public aqw.<init>(IILajz;)V #MD:Block/<init>(IILnet/minecraft/src/Material;) #Constructor
public aqw.cH #FD:Block/field_72029_cc #blockResistance
public aqw.cG #FD:Block/field_71989_cb #blockHardness
public aqw.d(Ljava/lang/String;)Laqw; #MD:Block/func_111022_d #setIconName
# -- MISSING MAPPING public amq.r()Lamq; #MD:Block/func_71912_p #setRequiresSelfNotify
public apa.a(Lape;)Lapa; #MD:Block/func_71884_a #setStepSound
public apa.b(F)Lapa; #MD:Block/func_71894_b #setResistance
public apa.c(F)Lapa; #MD:Block/func_71848_c #setHardness
public apa.k(I)Lapa; #MD:Block/func_71868_h #setLightOpacity
public apa.a(F)Lapa; #MD:Block/func_71900_a #setLightValue
public apa.r()Lapa; #MD:Block/func_71875_q #setBlockUnbreakable
public apa.b(Z)Lapa; #MD:Block/func_71907_b #setTickRandomly
public apa.a(FFFFFF)V #MD:Block/func_71905_a #setBlockBounds
public aqw.a(Lara;)Laqw; #MD:Block/func_71884_a #setStepSound
public aqw.b(F)Laqw; #MD:Block/func_71894_b #setResistance
public aqw.c(F)Laqw; #MD:Block/func_71848_c #setHardness
public aqw.k(I)Laqw; #MD:Block/func_71868_h #setLightOpacity
public aqw.a(F)Laqw; #MD:Block/func_71900_a #setLightValue
public aqw.r()Laqw; #MD:Block/func_71875_q #setBlockUnbreakable
public aqw.b(Z)Laqw; #MD:Block/func_71907_b #setTickRandomly
public aqw.a(FFFFFF)V #MD:Block/func_71905_a #setBlockBounds
# NetServerHandler
public jh.f #FD:NetServerHandler/field_72572_g #playerInAirTime
public jz.f #FD:NetServerHandler/field_72572_g #playerInAirTime
# TileEntity
public aqp.k #FD:TileEntity/field_70331_k #worldObj
public asm.k #FD:TileEntity/field_70331_k #worldObj
# BlockLeavesBase
public api.d #FD:BlockLeavesBase/field_72131_c #graphicsLevel
public are.d #FD:BlockLeavesBase/field_72131_c #graphicsLevel
# Item
public wk.<init>(I)V #MD:Item/<init>(I) #Constructor
public wk.e(I)Lwk; #MD:Item/func_77656_e #setMaxDamage
public-f wk.h(Lwm;)Llx; #MD:Item/func_77650_f #getIconIndex
public wk.c(Ljava/lang/String;)Lwk; #MD:Item/func_77631_c #setPotionEffect
public yb.<init>(I)V #MD:Item/<init>(I) #Constructor
public yb.e(I)Lyb; #MD:Item/func_77656_e #setMaxDamage
public-f yb.h(Lyd;)Lmr; #MD:Item/func_77650_f #getIconIndex
public yb.c(Ljava/lang/String;)Lyb; #MD:Item/func_77631_c #setPotionEffect
public yb.d(Ljava/lang/String;)Lyb; #MD:Item/func_111206_d #setIconName
# RailLogic
public alc #CL:BlockBaseRailLogic
public alc.a()I #MD:BlockBaseRailLogic/func_94505_a #getNAdjacentTiles
public amw #CL:BlockBaseRailLogic
public amw.a()I #MD:BlockBaseRailLogic/func_94505_a #getNAdjacentTiles
# EntityPlayer
public sq.a(Lrh;)V #MD:EntityPlayer/func_71012_a #joinEntityItemWithWorld
public sq.h()V #MD:EntityPlayer/func_71053_j #closeScreen
public sq.b #FD:EntityPlayer/field_71076_b #sleepTimer
public ue.a(Lsr;)V #MD:EntityPlayer/func_71012_a #joinEntityItemWithWorld
public ue.i()V #MD:EntityPlayer/func_71053_j #closeScreen
public ue.b #FD:EntityPlayer/field_71076_b #sleepTimer
# EntityPlayerMP
public bdv.a(Lrh;)V #MD:EntityClientPlayerMP/func_71012_a #joinEntityItemWithWorld
public bdf.a(Lsr;)V #MD:EntityClientPlayerMP/func_71012_a #joinEntityItemWithWorld
# World Gen Chests Related
public lp.* #FD:WeightedRandomChestContent/* #all
public iz.S #FD:WorldServer/field_73069_S #bonusChestContent
public aem.a #FD:StructureMineshaftPieces/field_78818_a #mineshaftChestContents
public afq.i #FD:ComponentScatteredFeatureDesertPyramid/field_74941_i #itemsToGenerateInTemple
public afr.l #FD:ComponentScatteredFeatureJunglePyramid/field_74943_l #junglePyramidsChestContents
public afr.m #FD:ComponentScatteredFeatureJunglePyramid/field_74944_m #junglePyramidsDispenserContents
public agb.a #FD:ComponentStrongholdChestCorridor/field_75003_a #strongholdChestContents
public agf.b #FD:ComponentStrongholdLibrary/field_75007_b #strongholdLibraryChestContents
public agk.c #FD:ComponentStrongholdRoomCrossing/field_75014_c #strongholdCorridorChestContents
public ahl.a #FD:ComponentVillageHouse2/field_74918_a #villageBlacksmithChestContents
public mj.* #FD:WeightedRandomChestContent/* #all
public jr.T #FD:WorldServer/field_73069_S #bonusChestContent
public agg.a #FD:StructureMineshaftPieces/field_78818_a #mineshaftChestContents
public ahk.i #FD:ComponentScatteredFeatureDesertPyramid/field_74941_i #itemsToGenerateInTemple
public ahl.l #FD:ComponentScatteredFeatureJunglePyramid/field_74943_l #junglePyramidsChestContents
public ahl.m #FD:ComponentScatteredFeatureJunglePyramid/field_74944_m #junglePyramidsDispenserContents
public ahv.a #FD:ComponentStrongholdChestCorridor/field_75003_a #strongholdChestContents
public ahz.b #FD:ComponentStrongholdLibrary/field_75007_b #strongholdLibraryChestContents
public aie.c #FD:ComponentStrongholdRoomCrossing/field_75014_c #strongholdCorridorChestContents
public ajf.a #FD:ComponentVillageHouse2/field_74918_a #villageBlacksmithChestContents
public afo.a #FD:WorldGenDungeons/field_111189_a #chestContents
# AnvilChunkLoader.chunkSaveLocation
public acj.d #FD:AnvilChunkLoader/field_75825_d
public aed.d #FD:AnvilChunkLoader/field_75825_d
# ChunkProviderServer.currentChunkLoader
public iy.e #FD:ChunkProviderServer/field_73247_e
public jq.e #FD:ChunkProviderServer/field_73247_e
# PlayerManager
public iw.a(IIZ)Lix; #MD:PlayerManager/func_72690_a #getOrCreateChunkWatcher
public jo.a(IIZ)Ljp; #MD:PlayerManager/func_72690_a #getOrCreateChunkWatcher
# PlayerInstance
public ix #CL:PlayerInstance
public jp #CL:PlayerInstance
# World
public-f aab.A #FD:World/field_72982_D #villageCollectionObj
public aab.G #FD:World/field_72993_I #activeChunkSet
public-f abv.A #FD:World/field_72982_D #villageCollectionObj
public abv.G #FD:World/field_72993_I #activeChunkSet
# EntityLiving
public ng.be #FD:EntityLiving/field_70728_aV #experienceValue
public ng.bt #FD:EntityLiving/field_94063_bt #combatTracker
public ng.bp #FD:EntityLiving/field_70715_bh #targetTasks
public of.b #FD:EntityLiving/field_70728_aV #experienceValue
# -- MISSING MAPPING public ng.bt #FD:EntityLiving/field_94063_bt #combatTracker
public of.d #FD:EntityLiving/field_70715_bh #targetTasks
# GuiFlatPresets
public axm.a(Ljava/lang/String;ILaav;Ljava/util/List;[Laei;)V #MD:GuiFlatPresets/func_82294_a
public axm.a(Ljava/lang/String;ILaav;[Laei;)V #MD:GuiFlatPresets/func_82297_a
public avw.a(Ljava/lang/String;ILacp;Ljava/util/List;[Lagc;)V #MD:GuiFlatPresets/func_82294_a
public avw.a(Ljava/lang/String;ILacp;[Lagc;)V #MD:GuiFlatPresets/func_82297_a
# BiomeGenBase
public aav.*() #MD:BiomeGenBase/* #Everything protected->public
public acp.*() #MD:BiomeGenBase/* #Everything protected->public
# MapGenVillage
public-f agz.e #FD:MapGenVillage/field_75055_e #villageSpawnBiomes
public-f ait.e #FD:MapGenVillage/field_75055_e #villageSpawnBiomes
# ShapedRecipes
public+f yn.d #FD:ShapedRecipes/field_77574_d #recipeItems
public+f yn.b #FD:ShapedRecipes/field_77576_b #recipeWidth
public+f yn.c #FD:ShapedRecipes/field_77577_c #recipeHeight
public+f aah.d #FD:ShapedRecipes/field_77574_d #recipeItems
public+f aah.b #FD:ShapedRecipes/field_77576_b #recipeWidth
public+f aah.c #FD:ShapedRecipes/field_77577_c #recipeHeight
# ShapelessRecipes
public yo.b #FD:ShapelessRecipes/field_77579_b #recipeItems
public aai.b #FD:ShapelessRecipes/field_77579_b #recipeItems
# GuiContainer
protected ayl.a(Lul;)V #MD:GuiContainer/func_74192_a #drawSlotInventory
protected awv.a(Lwd;)V #MD:GuiContainer/func_74192_a #drawSlotInventory
# ContainerPlayer
protected tz.h #FD:ContainerPlayer/field_82862_h #player
protected vu.h #FD:ContainerPlayer/field_82862_h #player
# BlockButton
protected ali.n(Laab;III)V #MD:BlockButton/func_82535_o #checkActivation
protected-f ali.a #FD:BlockButton/field_82537_a #sensible
protected anc.n(Labv;III)V #MD:BlockButton/func_82535_o #checkActivation
protected-f anc.a #FD:BlockButton/field_82537_a #sensible
# BiomeDecorator
public aaz.* #FD:BiomeDecorator/* # All private -> protected
public act.* #FD:BiomeDecorator/* # All private -> protected
# CreativeTabs
public-f ve.a #FD:CreativeTabs/field_78032_a # creativeTabArray non-final
public-f wv.a #FD:CreativeTabs/field_78032_a # creativeTabArray non-final
# Packet
public ei.a(IZZLjava/lang/Class;)V #MD:Packet/func_73285_a #addIdClassMapping
public ex.a(IZZLjava/lang/Class;)V #MD:Packet/func_73285_a #addIdClassMapping
# SaveHandler
public ajt.b()Ljava/io/File; #MD:SaveHandler/func_75765_b
public aln.b()Ljava/io/File; #MD:SaveHandler/func_75765_b
# World stuff
public aab.b(Lmp;)V #MD:World/func_72847_b #releaseEntitySkin
public aab.m #FD:World/field_73003_n #prevRainingStrength
public aab.n #FD:World/field_73004_o #rainingStrength
public aab.p #FD:World/field_73017_q #thunderingStrength
public aab.o #FD:World/field_73018_p #prevThunderingStrength
public abv.b(Lnm;)V #MD:World/func_72847_b #releaseEntitySkin
public abv.m #FD:World/field_73003_n #prevRainingStrength
public abv.n #FD:World/field_73004_o #rainingStrength
public abv.p #FD:World/field_73017_q #thunderingStrength
public abv.o #FD:World/field_73018_p #prevThunderingStrength
#WorldClient
public bds.b(Lmp;)V #MD:WorldClient/func_72847_b #releaseEntitySkin
public bda.b(Lnm;)V #MD:WorldClient/func_72847_b #releaseEntitySkin
#WorldServer
public iz.b(Lmp;)V #MD:WorldServer/func_72847_b #releaseEntitySkin
public iz.N #FD:WorldServer/field_73068_P #allPlayersSleeping
public jr.b(Lnm;)V #MD:WorldServer/func_72847_b #releaseEntitySkin
public jr.N #FD:WorldServer/field_73068_P #allPlayersSleeping
#TextureMap
public bir.a #FD:TextureMap/field_94255_a
public bir.b #FD:TextureMap/field_94253_b
public bir.c #FD:TextureMap/field_94254_c
public bir.d #FD:TextureMap/field_94251_d
public bih.g #FD:TextureMap/field_94255_a
# -- MISSING MAPPING public bir.b #FD:TextureMap/field_94253_b
public bih.h #FD:TextureMap/field_94254_c
# -- MISSING MAPPING public bir.d #FD:TextureMap/field_94251_d
#Potion
public mk.b(II)Lmk; #MD:Potion/func_76399_b #setIconIndex
public nh.b(II)Lnh; #MD:Potion/func_76399_b #setIconIndex
#PotionHelper
public xu.m #FD:PotionHelper/field_77927_l #potionRequirements
public xu.n #FD:PotionHelper/field_77928_m #potionAmplifiers
public zo.m #FD:PotionHelper/field_77927_l #potionRequirements
public zo.n #FD:PotionHelper/field_77928_m #potionAmplifiers
#PotionEffect
public ml.b #FD:PotionEffect/field_76460_b #duration
public ni.b #FD:PotionEffect/field_76460_b #duration
#BlockFluid
protected ane.a #FD:BlockFluid/field_94425_a #theIcon
protected aoz.a #FD:BlockFluid/field_94425_a #theIcon
#GuiIngame
protected aww.* #FD:GuiIngame/* # All private -> protected
protected aww.*() #MD:GuiIngame/* # All private -> protected
protected avg.* #FD:GuiIngame/* # All private -> protected
protected avg.*() #MD:GuiIngame/* # All private -> protected
#ItemStack
default wm.e #FD:ItemStack/field_77991_e # make default access for itemDamage
default yd.f #FD:ItemStack/field_77991_e # make default access for itemDamage
#GuiSlot
protected awd.b(IIII)V #MD:GuiSlot/func_77206_b #overlayBackground
#EntityPlayer
public ue.bu #FD:EntityPlayer/field_71092_bJ #username

View file

@ -1,5 +1,6 @@
package net.minecraftforge.classloading;
import java.io.File;
import java.util.Map;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
@ -7,6 +8,7 @@ import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
public class FMLForgePlugin implements IFMLLoadingPlugin
{
public static boolean RUNTIME_DEOBF = false;
public static File forgeLocation;
@Override
public String[] getLibraryRequestClass()
@ -39,5 +41,6 @@ public class FMLForgePlugin implements IFMLLoadingPlugin
public void injectData(Map<String, Object> data)
{
RUNTIME_DEOBF = (Boolean)data.get("runtimeDeobfuscationEnabled");
forgeLocation = (File)data.get("coremodLocation");
}
}

View file

@ -7,6 +7,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomChestContent;
import net.minecraft.world.WorldServer;
import net.minecraft.world.gen.feature.WorldGenDungeons;
import net.minecraft.world.gen.structure.*;
import net.minecraftforge.oredict.OreDictionary;
@ -49,6 +50,7 @@ public class ChestGenHooks
addInfo(STRONGHOLD_CROSSING, ComponentStrongholdRoomCrossing.strongholdRoomCrossingChestContents, 1, 5);
addInfo(VILLAGE_BLACKSMITH, ComponentVillageHouse2.villageBlacksmithChestContents, 3, 9);
addInfo(BONUS_CHEST, WorldServer.bonusChestContent, 10, 10);
addInfo(DUNGEON_CHEST, WorldGenDungeons.field_111189_a, 8, 8);
ItemStack book = new ItemStack(Item.enchantedBook, 1, 0);
WeightedRandomChestContent tmp = new WeightedRandomChestContent(book, 1, 1, 1);
@ -58,25 +60,7 @@ public class ChestGenHooks
getInfo(STRONGHOLD_CORRIDOR ).addItem(tmp);
getInfo(STRONGHOLD_LIBRARY ).addItem(new WeightedRandomChestContent(book, 1, 5, 2));
getInfo(STRONGHOLD_CROSSING ).addItem(tmp);
//Wish Dungeons would get on the same wave length as other world gen...
ChestGenHooks d = new ChestGenHooks(DUNGEON_CHEST);
d.countMin = 8;
d.countMax = 8;
chestInfo.put(DUNGEON_CHEST, d);
addDungeonLoot(d, new ItemStack(Item.saddle), 100, 1, 1);
addDungeonLoot(d, new ItemStack(Item.ingotIron), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.bread), 100, 1, 1);
addDungeonLoot(d, new ItemStack(Item.wheat), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.gunpowder), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.silk), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.bucketEmpty), 100, 1, 1);
addDungeonLoot(d, new ItemStack(Item.appleGold), 1, 1, 1);
addDungeonLoot(d, new ItemStack(Item.redstone), 50, 1, 4);
addDungeonLoot(d, new ItemStack(Item.record13), 5, 1, 1);
addDungeonLoot(d, new ItemStack(Item.recordCat), 5, 1, 1);
addDungeonLoot(d, new ItemStack(Item.dyePowder, 1, 3), 100, 1, 1);
addDungeonLoot(d, book, 100, 1, 1);
getInfo(DUNGEON_CHEST ).addItem(tmp);
}
static void addDungeonLoot(ChestGenHooks dungeon, ItemStack item, int weight, int min, int max)

View file

@ -46,7 +46,7 @@ public class EnumHelper
{EnumMovingObjectType.class},
{EnumSkyBlock.class, int.class},
{EnumStatus.class},
{EnumToolMaterial.class, int.class, int.class, float.class, int.class, int.class}
{EnumToolMaterial.class, int.class, int.class, float.class, float.class, int.class}
};
public static EnumAction addAction(String name)
@ -102,7 +102,7 @@ public class EnumHelper
{
return addEnum(EnumStatus.class, name);
}
public static EnumToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, int damage, int enchantability)
public static EnumToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability)
{
return addEnum(EnumToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability);
}

View file

@ -1,6 +1,7 @@
package net.minecraftforge.common;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World;
@ -9,8 +10,7 @@ public class FakePlayer extends EntityPlayer
{
public FakePlayer(World world, String name)
{
super(world);
this.username = name;
super(world, name);
}
public void sendChatToPlayer(String s){}
@ -19,4 +19,7 @@ public class FakePlayer extends EntityPlayer
{
return new ChunkCoordinates(0,0,0);
}
@Override
public void sendChatToPlayer(ChatMessageComponent chatmessagecomponent){}
}

View file

@ -22,8 +22,10 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.LinkedHashMultimap;
@ -34,6 +36,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Multiset;
import com.google.common.collect.Multisets;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.TreeMultiset;

View file

@ -10,14 +10,18 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.management.PlayerInstance;
import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.WorldInfo;
import net.minecraftforge.classloading.FMLForgePlugin;
import net.minecraftforge.common.network.ForgeConnectionHandler;
import net.minecraftforge.common.network.ForgeNetworkHandler;
import net.minecraftforge.common.network.ForgePacketHandler;
import net.minecraftforge.common.network.ForgeTinyPacketHandler;
import net.minecraftforge.server.command.ForgeCommand;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.client.FMLFileResourcePack;
import cpw.mods.fml.client.FMLFolderResourcePack;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoadController;
@ -27,6 +31,7 @@ import cpw.mods.fml.common.WorldAccessContainer;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.network.FMLNetworkHandler;
import cpw.mods.fml.common.network.NetworkMod;
@ -41,10 +46,11 @@ import static net.minecraftforge.common.ForgeVersion.*;
public class ForgeDummyContainer extends DummyModContainer implements WorldAccessContainer
{
public static int clumpingThreshold = 64;
public static boolean legacyFurnaceSides = false;
public static boolean removeErroringEntities = false;
public static boolean removeErroringTileEntities = false;
public static boolean disableStitchedFileSaving = false;
public static boolean forceDuplicateFluidBlockCrash = true;
public static boolean fullBoundingBoxLadders = false;
public ForgeDummyContainer()
{
@ -98,17 +104,13 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
prop.set(64);
}
prop = config.get(Configuration.CATEGORY_GENERAL, "legacyFurnaceOutput", false);
prop.comment = "Controls the sides of vanilla furnaces for Forge's ISidedInventroy, Vanilla defines the output as the bottom, but mods/Forge define it as the sides. Settings this to true will restore the old side relations.";
legacyFurnaceSides = prop.getBoolean(false);
prop = config.get(Configuration.CATEGORY_GENERAL, "removeErroringEntities", false);
prop.comment = "Set this to just remove any TileEntity that throws a error in there update method instead of closing the server and reporting a crash log. BE WARNED THIS COULD SCREW UP EVERYTHING USE SPARINGLY WE ARE NOT RESPONSIBLE FOR DAMAGES.";
removeErroringEntities = prop.getBoolean(false);
if (removeErroringEntities)
{
FMLLog.warning("Enableing removal of erroring Entities USE AT YOUR OWN RISK");
FMLLog.warning("Enabling removal of erroring Entities - USE AT YOUR OWN RISK");
}
prop = config.get(Configuration.CATEGORY_GENERAL, "removeErroringTileEntities", false);
@ -117,12 +119,25 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
if (removeErroringTileEntities)
{
FMLLog.warning("Enableing removal of erroring Tile Entities USE AT YOUR OWN RISK");
FMLLog.warning("Enabling removal of erroring Tile Entities - USE AT YOUR OWN RISK");
}
prop = config.get(Configuration.CATEGORY_GENERAL, "disableStitchedFileSaving", true);
prop.comment = "Set this to just disable the texture stitcher from writing the 'debug.stitched_{name}.png file to disc. Just a small performance tweak. Default: true";
disableStitchedFileSaving = prop.getBoolean(true);
//prop = config.get(Configuration.CATEGORY_GENERAL, "disableStitchedFileSaving", true);
//prop.comment = "Set this to just disable the texture stitcher from writing the 'debug.stitched_{name}.png file to disc. Just a small performance tweak. Default: true";
//disableStitchedFileSaving = prop.getBoolean(true);
prop = config.get(Configuration.CATEGORY_GENERAL, "fullBoundingBoxLadders", false);
prop.comment = "Set this to check the entire entity's collision bounding box for ladders instead of just the block they are in. Causes noticable differences in mechanics so default is vanilla behavior. Default: false";
fullBoundingBoxLadders = prop.getBoolean(false);
prop = config.get(Configuration.CATEGORY_GENERAL, "forceDuplicateFluidBlockCrash", true);
prop.comment = "Set this to force a crash if more than one block attempts to link back to the same Fluid. Enabled by default.";
forceDuplicateFluidBlockCrash = prop.getBoolean(true);
if (!forceDuplicateFluidBlockCrash)
{
FMLLog.warning("Disabling forced crashes on duplicate Fluid Blocks - USE AT YOUR OWN RISK");
}
if (config.hasChanged())
{
@ -164,6 +179,11 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
ForgeChunkManager.loadConfiguration();
}
@Subscribe
public void serverStarting(FMLServerStartingEvent evt)
{
evt.registerServerCommand(new ForgeCommand(evt.getServer()));
}
@Override
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
{
@ -181,4 +201,22 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
DimensionManager.loadDimensionDataMap(tag.hasKey("DimensionData") ? tag.getCompoundTag("DimensionData") : null);
}
}
@Override
public File getSource()
{
return FMLForgePlugin.forgeLocation;
}
@Override
public Class<?> getCustomResourcePackClass()
{
if (getSource().isDirectory())
{
return FMLFolderResourcePack.class;
}
else
{
return FMLFileResourcePack.class;
}
}
}

View file

@ -1,16 +1,14 @@
package net.minecraftforge.common;
import java.util.*;
import java.util.Map.Entry;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
@ -19,16 +17,27 @@ import net.minecraft.item.ItemAxe;
import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemSpade;
import net.minecraft.item.ItemStack;
import net.minecraft.network.NetServerHandler;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumMovingObjectType;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomItem;
import net.minecraft.world.World;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent;
import net.minecraftforge.event.entity.living.*;
import net.minecraftforge.event.entity.living.LivingEvent.*;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingDropsEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
public class ForgeHooks
{
@ -307,54 +316,74 @@ public class ForgeHooks
//Optifine Helper Functions u.u, these are here specifically for Optifine
//Note: When using Optfine, these methods are invoked using reflection, which
//incurs a major performance penalty.
public static void onLivingSetAttackTarget(EntityLiving entity, EntityLiving target)
public static void onLivingSetAttackTarget(EntityLivingBase entity, EntityLivingBase target)
{
MinecraftForge.EVENT_BUS.post(new LivingSetAttackTargetEvent(entity, target));
}
public static boolean onLivingUpdate(EntityLiving entity)
public static boolean onLivingUpdate(EntityLivingBase entity)
{
return MinecraftForge.EVENT_BUS.post(new LivingUpdateEvent(entity));
}
public static boolean onLivingAttack(EntityLiving entity, DamageSource src, int amount)
public static boolean onLivingAttack(EntityLivingBase entity, DamageSource src, float amount)
{
return MinecraftForge.EVENT_BUS.post(new LivingAttackEvent(entity, src, amount));
}
public static int onLivingHurt(EntityLiving entity, DamageSource src, int amount)
public static float onLivingHurt(EntityLivingBase entity, DamageSource src, float amount)
{
LivingHurtEvent event = new LivingHurtEvent(entity, src, amount);
return (MinecraftForge.EVENT_BUS.post(event) ? 0 : event.ammount);
}
public static boolean onLivingDeath(EntityLiving entity, DamageSource src)
public static boolean onLivingDeath(EntityLivingBase entity, DamageSource src)
{
return MinecraftForge.EVENT_BUS.post(new LivingDeathEvent(entity, src));
}
public static boolean onLivingDrops(EntityLiving entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue)
public static boolean onLivingDrops(EntityLivingBase entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue)
{
return MinecraftForge.EVENT_BUS.post(new LivingDropsEvent(entity, source, drops, lootingLevel, recentlyHit, specialDropValue));
}
public static float onLivingFall(EntityLiving entity, float distance)
public static float onLivingFall(EntityLivingBase entity, float distance)
{
LivingFallEvent event = new LivingFallEvent(entity, distance);
return (MinecraftForge.EVENT_BUS.post(event) ? 0.0f : event.distance);
}
public static boolean isLivingOnLadder(Block block, World world, int x, int y, int z, EntityLiving entity)
public static boolean isLivingOnLadder(Block block, World world, int x, int y, int z, EntityLivingBase entity)
{
return block != null && block.isLadder(world, x, y, z, entity);
}
@Deprecated //See above
public static boolean isLivingOnLadder(Block block, World world, int x, int y, int z)
{
return block != null && block.isLadder(world, x, y, z);
if (!ForgeDummyContainer.fullBoundingBoxLadders)
{
return block != null && block.isLadder(world, x, y, z, entity);
}
else
{
AxisAlignedBB bb = entity.boundingBox;
int mX = MathHelper.floor_double(bb.minX);
int mY = MathHelper.floor_double(bb.minY);
int mZ = MathHelper.floor_double(bb.minZ);
for (int y2 = mY; y < bb.maxY; y2++)
{
for (int x2 = mX; x2 < bb.maxX; x2++)
{
for (int z2 = mZ; z2 < bb.maxZ; z2++)
{
block = Block.blocksList[world.getBlockId(x2, y2, z2)];
if (block != null && block.isLadder(world, x2, y2, z2, entity))
{
return true;
}
}
}
}
return false;
}
}
public static void onLivingJump(EntityLiving entity)
public static void onLivingJump(EntityLivingBase entity)
{
MinecraftForge.EVENT_BUS.post(new LivingJumpEvent(entity));
}
@ -366,6 +395,11 @@ public class ForgeHooks
player.capturedDrops.clear();
player.captureDrops = false;
if (ret == null)
{
return null;
}
ItemTossEvent event = new ItemTossEvent(ret, player);
if (MinecraftForge.EVENT_BUS.post(event))
{
@ -386,4 +420,14 @@ public class ForgeHooks
Block block = Block.blocksList[world.getBlockId(x, y, z)];
return (block == null ? 0 : block.getEnchantPowerBonus(world, x, y, z));
}
public static ChatMessageComponent onServerChatEvent(NetServerHandler net, String raw, ChatMessageComponent comp)
{
ServerChatEvent event = new ServerChatEvent(net.playerEntity, raw, comp);
if (MinecraftForge.EVENT_BUS.post(event))
{
return null;
}
return event.component;
}
}

View file

@ -8,11 +8,11 @@ package net.minecraftforge.common;
public class ForgeVersion
{
//This number is incremented every time we remove deprecated code/major API changes, never reset
public static final int majorVersion = 7;
public static final int majorVersion = 9;
//This number is incremented every minecraft release, never reset
public static final int minorVersion = 8;
public static final int minorVersion = 10;
//This number is incremented every time a interface changes or new major feature is added, and reset every Minecraft version
public static final int revisionVersion = 1;
public static final int revisionVersion = 0;
//This number is incremented every time Jenkins builds Forge, and never reset. Should always be 0 in the repo code.
public static final int buildVersion = 0;

View file

@ -1,27 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.common;
import net.minecraft.item.ItemStack;
/**
* This interface has to be implemented by an instance of ItemArmor.
* It allows for the application of a custom texture file to the player skin
* when the armor is worn.
*/
@Deprecated //See Item.getArmorTexture
public interface IArmorTextureProvider
{
/**
* This interface has to return the path to a file that is the same
* format as iron_1.png (or any of the other armor files). It will be
* applied to the player skin when the armor is worn.
*/
public String getArmorTextureFile(ItemStack itemstack);
}

View file

@ -1,31 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.common;
import net.minecraft.inventory.IInventory;
/** Inventory ranges mapped by side. This class is implemented by TileEntities
* that provide different inventory slot ranges to different sides.
*/
@Deprecated //A equivalent Interface is now in Minecraft Vanilla will be removed next major MC version
public interface ISidedInventory extends IInventory
{
/**
* Get the start of the side inventory.
* @param side The global side to get the start of range.
*/
@Deprecated
int getStartInventorySide(ForgeDirection side);
/**
* Get the size of the side inventory.
* @param side The global side.
*/
@Deprecated
int getSizeInventorySide(ForgeDirection side);
}

View file

@ -9,7 +9,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import net.minecraft.util.DamageSource;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
@ -39,7 +39,7 @@ public interface ISpecialArmor
* @param slot The armor slot the item is in.
* @return A ArmorProperties instance holding information about how the armor effects damage.
*/
public ArmorProperties getProperties(EntityLiving player, ItemStack armor, DamageSource source, double damage, int slot);
public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot);
/**
* Get the displayed effective armor.
@ -63,7 +63,7 @@ public interface ISpecialArmor
* @param damage The amount of damage being applied to the armor
* @param slot The armor slot the item is in.
*/
public abstract void damageArmor(EntityLiving entity, ItemStack stack, DamageSource source, int damage, int slot);
public abstract void damageArmor(EntityLivingBase entity, ItemStack stack, DamageSource source, int damage, int slot);
public static class ArmorProperties implements Comparable<ArmorProperties>
{
@ -90,7 +90,7 @@ public interface ISpecialArmor
* @param damage The total damage being done
* @return The left over damage that has not been absorbed by the armor
*/
public static int ApplyArmor(EntityLiving entity, ItemStack[] inventory, DamageSource source, double damage)
public static float ApplyArmor(EntityLivingBase entity, ItemStack[] inventory, DamageSource source, double damage)
{
if (DEBUG)
{
@ -167,13 +167,11 @@ public interface ISpecialArmor
}
damage -= (damage * ratio);
}
damage += entity.carryoverDamage;
if (DEBUG)
{
System.out.println("Return: " + (int)(damage / 25D) + " " + damage);
System.out.println("Return: " + (int)(damage / 25.0F) + " " + damage);
}
entity.carryoverDamage = (int)damage % 25;
return (int)(damage / 25D);
return (float)(damage / 25.0F);
}
/**

View file

@ -1,23 +0,0 @@
package net.minecraftforge.common;
import net.minecraft.entity.Entity;
/**
* This interface should be implemented by an Entity that can be 'thrown', like snowballs.
* This was created to mimic ModLoaderMP's 'owner' functionality.
*/
@Deprecated //Moved to FML cpw.mods.fml.common.registry.IThrowableEntity
public interface IThrowableEntity
{
/**
* Gets the entity that threw/created this entity.
* @return The owner instance, Null if none.
*/
public Entity getThrower();
/**
* Sets the entity that threw/created this entity.
* @param entity The new thrower/creator.
*/
public void setThrower(Entity entity);
}

View file

@ -187,7 +187,9 @@ public class MinecraftForge
Block filler = new Block(0, Material.air)
{
@SideOnly(Side.CLIENT) public void func_94332_a(IconRegister register){}
@SideOnly(Side.CLIENT)
@Override
public void registerIcons(IconRegister register){}
};
Block.blocksList[0] = null;
Block.opaqueCubeLookup[0] = false;

View file

@ -1,19 +1,82 @@
package net.minecraftforge.common;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import net.minecraft.block.Block;
import net.minecraft.block.BlockAnvil;
import net.minecraft.block.BlockBed;
import net.minecraft.block.BlockButton;
import net.minecraft.block.BlockChest;
import net.minecraft.block.BlockCocoa;
import net.minecraft.block.BlockComparator;
import net.minecraft.block.BlockDetectorRail;
import net.minecraft.block.BlockDispenser;
import net.minecraft.block.BlockDropper;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.BlockEndPortalFrame;
import net.minecraft.block.BlockEnderChest;
import net.minecraft.block.BlockFenceGate;
import net.minecraft.block.BlockFurnace;
import net.minecraft.block.BlockHopper;
import net.minecraft.block.BlockLadder;
import net.minecraft.block.BlockLever;
import net.minecraft.block.BlockLog;
import net.minecraft.block.BlockMushroomCap;
import net.minecraft.block.BlockPistonBase;
import net.minecraft.block.BlockPistonExtension;
import net.minecraft.block.BlockPumpkin;
import net.minecraft.block.BlockRail;
import net.minecraft.block.BlockRailPowered;
import net.minecraft.block.BlockRedstoneRepeater;
import net.minecraft.block.BlockSkull;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.BlockTorch;
import net.minecraft.block.BlockTrapDoor;
import net.minecraft.block.BlockTripWireSource;
import net.minecraft.block.BlockVine;
import net.minecraft.world.World;
import java.util.HashMap;
import java.util.Map;
import static net.minecraftforge.common.ForgeDirection.*;
public class RotationHelper {
/**
* Some blocks have the same rotation.
* The first of these blocks (sorted by itemID) should be listed as a type.
* Some of the types aren't actual blocks (helper types).
*/
private static enum BlockType {
LOG,
DISPENSER,
BED,
RAIL,
RAIL_POWERED,
RAIL_ASCENDING,
RAIL_CORNER,
TORCH,
STAIR,
CHEST,
SIGNPOST,
DOOR,
LEVER,
BUTTON,
REDSTONE_REPEATER,
TRAPDOOR,
MUSHROOM_CAP,
MUSHROOM_CAP_CORNER,
MUSHROOM_CAP_SIDE,
VINE,
SKULL,
ANVIL
}
private static final ForgeDirection[] UP_DOWN_AXES = new ForgeDirection[] { UP, DOWN };
private static final Map<BlockType, BiMap<Integer, ForgeDirection>> MAPPINGS = new HashMap<BlockType, BiMap<Integer, ForgeDirection>>();
public static ForgeDirection[] getValidVanillaBlockRotations(Block block)
{
return block instanceof BlockChest ? UP_DOWN_AXES : VALID_DIRECTIONS;
return (block instanceof BlockBed || block instanceof BlockPumpkin || block instanceof BlockFenceGate || block instanceof BlockEndPortalFrame || block instanceof BlockTripWireSource || block instanceof BlockCocoa || block instanceof BlockRailPowered || block instanceof BlockDetectorRail || block instanceof BlockStairs || block instanceof BlockChest || block instanceof BlockEnderChest || block instanceof BlockFurnace || block instanceof BlockLadder || block.blockID == Block.signWall.blockID || block.blockID == Block.signPost.blockID || block instanceof BlockDoor || block instanceof BlockRail || block instanceof BlockButton || block instanceof BlockRedstoneRepeater || block instanceof BlockComparator || block instanceof BlockTrapDoor || block instanceof BlockMushroomCap || block instanceof BlockVine || block instanceof BlockSkull || block instanceof BlockAnvil) ? UP_DOWN_AXES : VALID_DIRECTIONS;
}
public static boolean rotateVanillaBlock(Block block, World worldObj, int x, int y, int z, ForgeDirection axis)
@ -23,25 +86,323 @@ public class RotationHelper {
return false;
}
if (block instanceof BlockChest && (axis == UP || axis == DOWN))
if (axis == UP || axis == DOWN)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7);
if (block instanceof BlockBed || block instanceof BlockPumpkin || block instanceof BlockFenceGate || block instanceof BlockEndPortalFrame || block instanceof BlockTripWireSource || block instanceof BlockCocoa)
{
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.BED);
}
if (block instanceof BlockRail)
{
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.RAIL);
}
if (block instanceof BlockRailPowered || block instanceof BlockDetectorRail)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.RAIL_POWERED);
}
if (block instanceof BlockStairs)
{
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.STAIR);
}
if (block instanceof BlockChest || block instanceof BlockEnderChest || block instanceof BlockFurnace || block instanceof BlockLadder || block.blockID == Block.signWall.blockID)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.CHEST);
}
if (block.blockID == Block.signPost.blockID)
{
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.SIGNPOST);
}
if (block instanceof BlockDoor)
{
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.DOOR);
}
if (block instanceof BlockButton)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.BUTTON);
}
if (block instanceof BlockRedstoneRepeater || block instanceof BlockComparator)
{
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.REDSTONE_REPEATER);
}
if (block instanceof BlockTrapDoor)
{
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.TRAPDOOR);
}
if (block instanceof BlockMushroomCap)
{
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.MUSHROOM_CAP);
}
if (block instanceof BlockVine)
{
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.VINE);
}
if (block instanceof BlockSkull)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.SKULL);
}
if (block instanceof BlockAnvil)
{
return rotateBlock(worldObj, x, y, z, axis, 0x1, BlockType.ANVIL);
}
}
if (block instanceof BlockPistonBase || block instanceof BlockDropper || block instanceof BlockDispenser)
if (block instanceof BlockLog)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7);
return rotateBlock(worldObj, x, y, z, axis, 0xC, BlockType.LOG);
}
if (block instanceof BlockDispenser || block instanceof BlockPistonBase || block instanceof BlockPistonExtension || block instanceof BlockHopper)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.DISPENSER);
}
if (block instanceof BlockTorch)
{
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.TORCH);
}
if (block instanceof BlockLever)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.LEVER);
}
return false;
}
private static boolean rotateBlock(World worldObj, int x, int y, int z, ForgeDirection axis, int mask)
private static boolean rotateBlock(World worldObj, int x, int y, int z, ForgeDirection axis, int mask, BlockType blockType)
{
int rotMeta = worldObj.getBlockMetadata(x, y, z);
if (blockType == BlockType.DOOR && (rotMeta & 0x8) == 0x8)
{
return false;
}
int masked = rotMeta & ~mask;
ForgeDirection orientation = ForgeDirection.getOrientation(rotMeta & mask);
ForgeDirection rotated = orientation.getRotation(axis);
worldObj.setBlockMetadataWithNotify(x,y,z,rotated.ordinal() & mask | masked,3);
int meta = rotateMetadata(axis, blockType, rotMeta & mask);
if (meta == -1)
{
return false;
}
worldObj.setBlockMetadataWithNotify(x, y, z, meta & mask | masked, 3);
return true;
}
private static int rotateMetadata(ForgeDirection axis, BlockType blockType, int meta)
{
if (blockType == BlockType.RAIL || blockType == BlockType.RAIL_POWERED)
{
if (meta == 0x0 || meta == 0x1)
{
return ~meta & 0x1;
}
if (meta >= 0x2 && meta <= 0x5)
{
blockType = BlockType.RAIL_ASCENDING;
}
if (meta >= 0x6 && meta <= 0x9 && blockType == BlockType.RAIL)
{
blockType = BlockType.RAIL_CORNER;
}
}
if (blockType == BlockType.SIGNPOST)
{
return (axis == UP) ? (meta + 0x4) % 0x10 : (meta + 0xC) % 0x10;
}
if (blockType == BlockType.LEVER && (axis == UP || axis == DOWN))
{
switch (meta)
{
case 0x5:
return 0x6;
case 0x6:
return 0x5;
case 0x7:
return 0x0;
case 0x0:
return 0x7;
}
}
if (blockType == BlockType.MUSHROOM_CAP)
{
if (meta % 0x2 == 0)
{
blockType = BlockType.MUSHROOM_CAP_SIDE;
}
else
{
blockType = BlockType.MUSHROOM_CAP_CORNER;
}
}
if (blockType == BlockType.VINE)
{
return ((meta << 1) | ((meta & 0x8) >> 3));
}
ForgeDirection orientation = metadataToDirection(blockType, meta);
ForgeDirection rotated = orientation.getRotation(axis);
return directionToMetadata(blockType, rotated);
}
private static ForgeDirection metadataToDirection(BlockType blockType, int meta)
{
if (blockType == BlockType.LEVER)
{
if (meta == 0x6)
{
meta = 0x5;
}
else if (meta == 0x0)
{
meta = 0x7;
}
}
if (MAPPINGS.containsKey(blockType))
{
BiMap<Integer, ForgeDirection> biMap = MAPPINGS.get(blockType);
if (biMap.containsKey(meta))
{
return biMap.get(meta);
}
}
if (blockType == BlockType.TORCH)
{
return ForgeDirection.getOrientation(6 - meta);
}
if (blockType == BlockType.STAIR)
{
return ForgeDirection.getOrientation(5 - meta);
}
if (blockType == BlockType.CHEST || blockType == BlockType.DISPENSER || blockType == BlockType.SKULL)
{
return ForgeDirection.getOrientation(meta);
}
if (blockType == BlockType.BUTTON)
{
return ForgeDirection.getOrientation(6 - meta);
}
if (blockType == BlockType.TRAPDOOR)
{
return ForgeDirection.getOrientation(meta + 2).getOpposite();
}
return ForgeDirection.UNKNOWN;
}
private static int directionToMetadata(BlockType blockType, ForgeDirection direction)
{
if ((blockType == BlockType.LOG || blockType == BlockType.ANVIL) && (direction.offsetX + direction.offsetY + direction.offsetZ) < 0)
{
direction = direction.getOpposite();
}
if (MAPPINGS.containsKey(blockType))
{
BiMap<ForgeDirection, Integer> biMap = MAPPINGS.get(blockType).inverse();
if (biMap.containsKey(direction))
{
return biMap.get(direction);
}
}
if (blockType == BlockType.TORCH)
{
if (direction.ordinal() >= 1)
{
return 6 - direction.ordinal();
}
}
if (blockType == BlockType.STAIR)
{
return 5 - direction.ordinal();
}
if (blockType == BlockType.CHEST || blockType == BlockType.DISPENSER || blockType == BlockType.SKULL)
{
return direction.ordinal();
}
if (blockType == BlockType.BUTTON)
{
if (direction.ordinal() >= 2)
{
return 6 - direction.ordinal();
}
}
if (blockType == BlockType.TRAPDOOR)
{
return direction.getOpposite().ordinal() - 2;
}
return -1;
}
static
{
BiMap<Integer, ForgeDirection> biMap;
biMap = HashBiMap.create(3);
biMap.put(0x0, UP);
biMap.put(0x4, EAST);
biMap.put(0x8, SOUTH);
MAPPINGS.put(BlockType.LOG, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x0, SOUTH);
biMap.put(0x1, WEST);
biMap.put(0x2, NORTH);
biMap.put(0x3, EAST);
MAPPINGS.put(BlockType.BED, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x2, EAST);
biMap.put(0x3, WEST);
biMap.put(0x4, NORTH);
biMap.put(0x5, SOUTH);
MAPPINGS.put(BlockType.RAIL_ASCENDING, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x6, WEST);
biMap.put(0x7, NORTH);
biMap.put(0x8, EAST);
biMap.put(0x9, SOUTH);
MAPPINGS.put(BlockType.RAIL_CORNER, biMap);
biMap = HashBiMap.create(6);
biMap.put(0x1, EAST);
biMap.put(0x2, WEST);
biMap.put(0x3, SOUTH);
biMap.put(0x4, NORTH);
biMap.put(0x5, UP);
biMap.put(0x7, DOWN);
MAPPINGS.put(BlockType.LEVER, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x0, WEST);
biMap.put(0x1, NORTH);
biMap.put(0x2, EAST);
biMap.put(0x3, SOUTH);
MAPPINGS.put(BlockType.DOOR, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x0, NORTH);
biMap.put(0x1, EAST);
biMap.put(0x2, SOUTH);
biMap.put(0x3, WEST);
MAPPINGS.put(BlockType.REDSTONE_REPEATER, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x1, EAST);
biMap.put(0x3, SOUTH);
biMap.put(0x7, NORTH);
biMap.put(0x9, WEST);
MAPPINGS.put(BlockType.MUSHROOM_CAP_CORNER, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x2, NORTH);
biMap.put(0x4, WEST);
biMap.put(0x6, EAST);
biMap.put(0x8, SOUTH);
MAPPINGS.put(BlockType.MUSHROOM_CAP_SIDE, biMap);
biMap = HashBiMap.create(2);
biMap.put(0x0, SOUTH);
biMap.put(0x1, EAST);
MAPPINGS.put(BlockType.ANVIL, biMap);
}
}

View file

@ -4,8 +4,11 @@ import net.minecraft.network.INetworkManager;
import net.minecraft.network.NetLoginHandler;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet1Login;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.fluids.FluidIdMapPacket;
import cpw.mods.fml.common.network.IConnectionHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
public class ForgeConnectionHandler implements IConnectionHandler {
@ -13,7 +16,10 @@ public class ForgeConnectionHandler implements IConnectionHandler {
@Override
public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager)
{
Packet250CustomPayload[] fluidPackets = ForgePacket.makePacketSet(new FluidIdMapPacket());
for (int i = 0; i < fluidPackets.length; i++) {
PacketDispatcher.sendPacketToPlayer(fluidPackets[i], player);
}
}
@Override

View file

@ -9,6 +9,7 @@ import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraftforge.common.network.packet.DimensionRegisterPacket;
import net.minecraftforge.fluids.FluidIdMapPacket;
import com.google.common.base.Throwables;
import com.google.common.collect.MapMaker;
@ -29,7 +30,11 @@ public abstract class ForgePacket
/**
* Registers a dimension for a provider on client
*/
REGISTERDIMENSION(DimensionRegisterPacket.class);
REGISTERDIMENSION(DimensionRegisterPacket.class),
/**
* The Fluid ID map to send to the client
*/
FLUID_IDMAP(FluidIdMapPacket.class);
private Class<? extends ForgePacket> packetType;
private ConcurrentMap<INetworkManager, ForgePacket> partTracker;

View file

@ -1,19 +1,20 @@
package net.minecraftforge.event;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.ChatMessageComponent;
@Cancelable
public class ServerChatEvent extends Event
{
public final String message, username;
public final EntityPlayerMP player;
public String line;
public ServerChatEvent(EntityPlayerMP player, String message, String line)
public ChatMessageComponent component;
public ServerChatEvent(EntityPlayerMP player, String message, ChatMessageComponent component)
{
super();
this.message = message;
this.player = player;
this.username = player.username;
this.line = line;
this.component = component;
}
}

View file

@ -1,6 +1,7 @@
package net.minecraftforge.event.entity.living;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
@ -16,9 +17,9 @@ public class EnderTeleportEvent extends LivingEvent
public double targetX;
public double targetY;
public double targetZ;
public int attackDamage;
public float attackDamage;
public EnderTeleportEvent(EntityLiving entity, double targetX, double targetY, double targetZ, int attackDamage)
public EnderTeleportEvent(EntityLivingBase entity, double targetX, double targetY, double targetZ, float attackDamage)
{
super(entity);
this.targetX = targetX;

View file

@ -1,15 +1,15 @@
package net.minecraftforge.event.entity.living;
import net.minecraft.util.DamageSource;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraftforge.event.Cancelable;
@Cancelable
public class LivingAttackEvent extends LivingEvent
{
public final DamageSource source;
public final int ammount;
public LivingAttackEvent(EntityLiving entity, DamageSource source, int ammount)
public final float ammount;
public LivingAttackEvent(EntityLivingBase entity, DamageSource source, float ammount)
{
super(entity);
this.source = source;

View file

@ -1,14 +1,14 @@
package net.minecraftforge.event.entity.living;
import net.minecraft.util.DamageSource;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraftforge.event.Cancelable;
@Cancelable
public class LivingDeathEvent extends LivingEvent
{
public final DamageSource source;
public LivingDeathEvent(EntityLiving entity, DamageSource source)
public LivingDeathEvent(EntityLivingBase entity, DamageSource source)
{
super(entity);
this.source = source;

View file

@ -4,7 +4,7 @@ import java.util.ArrayList;
import net.minecraft.util.DamageSource;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraftforge.event.Cancelable;
@Cancelable
@ -16,7 +16,7 @@ public class LivingDropsEvent extends LivingEvent
public final boolean recentlyHit;
public final int specialDropValue;
public LivingDropsEvent(EntityLiving entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue)
public LivingDropsEvent(EntityLivingBase entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue)
{
super(entity);
this.source = source;

View file

@ -1,13 +1,13 @@
package net.minecraftforge.event.entity.living;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.entity.EntityEvent;
public class LivingEvent extends EntityEvent
{
public final EntityLiving entityLiving;
public LivingEvent(EntityLiving entity)
public final EntityLivingBase entityLiving;
public LivingEvent(EntityLivingBase entity)
{
super(entity);
entityLiving = entity;
@ -16,11 +16,11 @@ public class LivingEvent extends EntityEvent
@Cancelable
public static class LivingUpdateEvent extends LivingEvent
{
public LivingUpdateEvent(EntityLiving e){ super(e); }
public LivingUpdateEvent(EntityLivingBase e){ super(e); }
}
public static class LivingJumpEvent extends LivingEvent
{
public LivingJumpEvent(EntityLiving e){ super(e); }
public LivingJumpEvent(EntityLivingBase e){ super(e); }
}
}

View file

@ -1,13 +1,13 @@
package net.minecraftforge.event.entity.living;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraftforge.event.Cancelable;
@Cancelable
public class LivingFallEvent extends LivingEvent
{
public float distance;
public LivingFallEvent(EntityLiving entity, float distance)
public LivingFallEvent(EntityLivingBase entity, float distance)
{
super(entity);
this.distance = distance;

View file

@ -1,15 +1,15 @@
package net.minecraftforge.event.entity.living;
import net.minecraft.util.DamageSource;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraftforge.event.Cancelable;
@Cancelable
public class LivingHurtEvent extends LivingEvent
{
public final DamageSource source;
public int ammount;
public LivingHurtEvent(EntityLiving entity, DamageSource source, int ammount)
public float ammount;
public LivingHurtEvent(EntityLivingBase entity, DamageSource source, float ammount)
{
super(entity);
this.source = source;

View file

@ -1,12 +1,12 @@
package net.minecraftforge.event.entity.living;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
public class LivingSetAttackTargetEvent extends LivingEvent
{
public final EntityLiving target;
public LivingSetAttackTargetEvent(EntityLiving entity, EntityLiving target)
public final EntityLivingBase target;
public LivingSetAttackTargetEvent(EntityLivingBase entity, EntityLivingBase target)
{
super(entity);
this.target = target;

View file

@ -0,0 +1,463 @@
package net.minecraftforge.fluids;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.Vec3;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
/**
* This is a base implementation for Fluid blocks.
*
* It is highly recommended that you extend this class or one of the Forge-provided child classes.
*
* @author King Lemming, OvermindDL1
*
*/
public abstract class BlockFluidBase extends Block implements IFluidBlock
{
protected final static Map<Integer, Boolean> defaultDisplacementIds = new HashMap<Integer, Boolean>();
static
{
defaultDisplacementIds.put(Block.doorWood.blockID, false);
defaultDisplacementIds.put(Block.doorIron.blockID, false);
defaultDisplacementIds.put(Block.signPost.blockID, false);
defaultDisplacementIds.put(Block.signWall.blockID, false);
defaultDisplacementIds.put(Block.reed.blockID, false);
}
protected Map<Integer, Boolean> displacementIds = new HashMap<Integer, Boolean>();
protected int quantaPerBlock = 8;
protected float quantaPerBlockFloat = 8F;
protected int density = 1;
protected int densityDir = -1;
protected int temperature = 295;
protected int tickRate = 20;
protected int renderPass = 1;
protected int maxScaledLight = 0;
protected final String fluidName;
public BlockFluidBase(int id, Fluid fluid, Material material)
{
super(id, material);
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
this.setTickRandomly(true);
this.disableStats();
this.fluidName = fluid.getName();
this.density = fluid.density;
this.temperature = fluid.temperature;
this.maxScaledLight = fluid.luminosity;
this.tickRate = fluid.viscosity / 200;
fluid.setBlockID(id);
displacementIds.putAll(defaultDisplacementIds);
}
public BlockFluidBase setQuantaPerBlock(int quantaPerBlock)
{
if (quantaPerBlock > 16 || quantaPerBlock < 1) quantaPerBlock = 8;
this.quantaPerBlock = quantaPerBlock;
this.quantaPerBlockFloat = quantaPerBlock;
return this;
}
public BlockFluidBase setDensity(int density)
{
if (density == 0) density = 1;
this.density = density;
this.densityDir = density > 0 ? -1 : 1;
return this;
}
public BlockFluidBase setTemperature(int temperature)
{
this.temperature = temperature;
return this;
}
public BlockFluidBase setTickRate(int tickRate)
{
if (tickRate <= 0) tickRate = 20;
this.tickRate = tickRate;
return this;
}
public BlockFluidBase setRenderPass(int renderPass)
{
this.renderPass = renderPass;
return this;
}
public BlockFluidBase setMaxScaledLight(int maxScaledLight)
{
this.maxScaledLight = maxScaledLight;
return this;
}
/**
* Returns true if the block at (x, y, z) is displaceable. Does not displace the block.
*/
public boolean canDisplace(IBlockAccess world, int x, int y, int z)
{
if (world.isAirBlock(x, y, z)) return true;
int bId = world.getBlockId(x, y, z);
if (bId == blockID)
{
return false;
}
if (displacementIds.containsKey(bId))
{
return displacementIds.get(bId);
}
Material material = Block.blocksList[bId].blockMaterial;
if (material.blocksMovement() || material == Material.portal)
{
return false;
}
int density = getDensity(world, x, y, z);
if (density == Integer.MAX_VALUE)
{
return true;
}
if (this.density > density)
{
return true;
}
else
{
return false;
}
}
/**
* Attempt to displace the block at (x, y, z), return true if it was displaced.
*/
public boolean displaceIfPossible(World world, int x, int y, int z)
{
if (world.isAirBlock(x, y, z))
{
return true;
}
int bId = world.getBlockId(x, y, z);
if (bId == blockID)
{
return false;
}
if (displacementIds.containsKey(bId))
{
if (displacementIds.get(bId))
{
Block.blocksList[bId].dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
return true;
}
return false;
}
Material material = Block.blocksList[bId].blockMaterial;
if (material.blocksMovement() || material == Material.portal)
{
return false;
}
int density = getDensity(world, x, y, z);
if (density == Integer.MAX_VALUE)
{
Block.blocksList[bId].dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
return true;
}
if (this.density > density)
{
return true;
}
else
{
return false;
}
}
public abstract int getQuantaValue(IBlockAccess world, int x, int y, int z);
@Override
public abstract boolean canCollideCheck(int meta, boolean fullHit);
public abstract int getMaxRenderHeightMeta();
/* BLOCK FUNCTIONS */
@Override
public void onBlockAdded(World world, int x, int y, int z)
{
world.scheduleBlockUpdate(x, y, z, blockID, tickRate);
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int blockId)
{
world.scheduleBlockUpdate(x, y, z, blockID, tickRate);
}
// Used to prevent updates on chunk generation
@Override
public boolean func_82506_l()
{
return false;
}
@Override
public boolean getBlocksMovement(IBlockAccess world, int x, int y, int z)
{
return true;
}
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z)
{
return null;
}
@Override
public int idDropped(int par1, Random par2Random, int par3)
{
return 0;
}
@Override
public int quantityDropped(Random par1Random)
{
return 0;
}
@Override
public int tickRate(World world)
{
return tickRate;
}
@Override
public void velocityToAddToEntity(World world, int x, int y, int z, Entity entity, Vec3 vec)
{
if (densityDir > 0) return;
Vec3 vec_flow = this.getFlowVector(world, x, y, z);
vec.xCoord += vec_flow.xCoord * (quantaPerBlock * 4);
vec.yCoord += vec_flow.yCoord * (quantaPerBlock * 4);
vec.zCoord += vec_flow.zCoord * (quantaPerBlock * 4);
}
@Override
public int getLightValue(IBlockAccess world, int x, int y, int z)
{
if (maxScaledLight == 0)
{
return super.getLightValue(world, x, y, z);
}
int data = world.getBlockMetadata(x, y, z);
return (int) (data / quantaPerBlockFloat * maxScaledLight);
}
@Override
public int getRenderType()
{
return FluidRegistry.renderIdFluid;
}
@Override
public boolean isOpaqueCube()
{
return false;
}
@Override
public boolean renderAsNormalBlock()
{
return false;
}
@Override
public float getBlockBrightness(IBlockAccess world, int x, int y, int z)
{
float lightThis = world.getLightBrightness(x, y, z);
float lightUp = world.getLightBrightness(x, y + 1, z);
return lightThis > lightUp ? lightThis : lightUp;
}
@Override
public int getMixedBrightnessForBlock(IBlockAccess world, int x, int y, int z)
{
int lightThis = world.getLightBrightnessForSkyBlocks(x, y, z, 0);
int lightUp = world.getLightBrightnessForSkyBlocks(x, y + 1, z, 0);
int lightThisBase = lightThis & 255;
int lightUpBase = lightUp & 255;
int lightThisExt = lightThis >> 16 & 255;
int lightUpExt = lightUp >> 16 & 255;
return (lightThisBase > lightUpBase ? lightThisBase : lightUpBase) |
((lightThisExt > lightUpExt ? lightThisExt : lightUpExt) << 16);
}
@Override
public int getRenderBlockPass()
{
return renderPass;
}
@Override
public boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int side)
{
if (world.getBlockId(x, y, z) != blockID)
{
return !world.isBlockOpaqueCube(x, y, z);
}
Material mat = world.getBlockMaterial(x, y, z);
return mat == this.blockMaterial ? false : super.shouldSideBeRendered(world, x, y, z, side);
}
/* FLUID FUNCTIONS */
public static final int getDensity(IBlockAccess world, int x, int y, int z)
{
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if (!(block instanceof BlockFluidBase))
{
return Integer.MAX_VALUE;
}
return ((BlockFluidBase)block).density;
}
public static final int getTemperature(IBlockAccess world, int x, int y, int z)
{
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if (!(block instanceof BlockFluidBase))
{
return Integer.MAX_VALUE;
}
return ((BlockFluidBase)block).temperature;
}
public static double getFlowDirection(IBlockAccess world, int x, int y, int z)
{
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if (!world.getBlockMaterial(x, y, z).isLiquid())
{
return -1000.0;
}
Vec3 vec = ((BlockFluidBase) block).getFlowVector(world, x, y, z);
return vec.xCoord == 0.0D && vec.zCoord == 0.0D ? -1000.0D : Math.atan2(vec.zCoord, vec.xCoord) - Math.PI / 2D;
}
public final int getQuantaValueBelow(IBlockAccess world, int x, int y, int z, int belowThis)
{
int quantaRemaining = getQuantaValue(world, x, y, z);
if (quantaRemaining >= belowThis)
{
return -1;
}
return quantaRemaining;
}
public final int getQuantaValueAbove(IBlockAccess world, int x, int y, int z, int aboveThis)
{
int quantaRemaining = getQuantaValue(world, x, y, z);
if (quantaRemaining <= aboveThis)
{
return -1;
}
return quantaRemaining;
}
public final float getQuantaPercentage(IBlockAccess world, int x, int y, int z)
{
int quantaRemaining = getQuantaValue(world, x, y, z);
return quantaRemaining / quantaPerBlockFloat;
}
public Vec3 getFlowVector(IBlockAccess world, int x, int y, int z)
{
Vec3 vec = world.getWorldVec3Pool().getVecFromPool(0.0D, 0.0D, 0.0D);
int decay = quantaPerBlock - getQuantaValue(world, x, y, z);
for (int side = 0; side < 4; ++side)
{
int x2 = x;
int z2 = z;
switch (side)
{
case 0: --x2; break;
case 1: --z2; break;
case 2: ++x2; break;
case 3: ++z2; break;
}
int otherDecay = quantaPerBlock - getQuantaValue(world, x2, y, z2);
if (otherDecay >= quantaPerBlock)
{
if (!world.getBlockMaterial(x2, y, z2).blocksMovement())
{
otherDecay = quantaPerBlock - getQuantaValue(world, x2, y - 1, z2);
if (otherDecay >= 0)
{
int power = otherDecay - (decay - quantaPerBlock);
vec = vec.addVector((x2 - x) * power, (y - y) * power, (z2 - z) * power);
}
}
}
else if (otherDecay >= 0)
{
int power = otherDecay - decay;
vec = vec.addVector((x2 - x) * power, (y - y) * power, (z2 - z) * power);
}
}
if (world.getBlockId(x, y + 1, z) == blockID)
{
boolean flag =
isBlockSolid(world, x, y, z - 1, 2) ||
isBlockSolid(world, x, y, z + 1, 3) ||
isBlockSolid(world, x - 1, y, z, 4) ||
isBlockSolid(world, x + 1, y, z, 5) ||
isBlockSolid(world, x, y + 1, z - 1, 2) ||
isBlockSolid(world, x, y + 1, z + 1, 3) ||
isBlockSolid(world, x - 1, y + 1, z, 4) ||
isBlockSolid(world, x + 1, y + 1, z, 5);
if (flag)
{
vec = vec.normalize().addVector(0.0D, -6.0D, 0.0D);
}
}
vec = vec.normalize();
return vec;
}
/* IFluidBlock */
@Override
public Fluid getFluid()
{
return FluidRegistry.getFluid(fluidName);
}
@Override
public float getFilledPercentage(World world, int x, int y, int z)
{
int quantaRemaining = getQuantaValue(world, x, y, z) + 1;
float remaining = quantaRemaining / quantaPerBlockFloat;
if (remaining > 1) remaining = 1.0f;
return remaining * (density > 0 ? 1 : -1);
}
}

View file

@ -0,0 +1,354 @@
package net.minecraftforge.fluids;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
/**
* This is a fluid block implementation which emulates vanilla Minecraft fluid behavior.
*
* It is highly recommended that you use/extend this class for "classic" fluid blocks.
*
* @author King Lemming
*
*/
public class BlockFluidClassic extends BlockFluidBase
{
protected boolean[] isOptimalFlowDirection = new boolean[4];
protected int[] flowCost = new int[4];
protected FluidStack stack;
public BlockFluidClassic(int id, Fluid fluid, Material material)
{
super(id, fluid, material);
stack = new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME);
}
public BlockFluidClassic setFluidStack(FluidStack stack)
{
this.stack = stack;
return this;
}
public BlockFluidClassic setFluidStackAmount(int amount)
{
this.stack.amount = amount;
return this;
}
@Override
public int getQuantaValue(IBlockAccess world, int x, int y, int z)
{
if (world.getBlockId(x, y, z) == 0)
{
return 0;
}
if (world.getBlockId(x, y, z) != blockID)
{
return -1;
}
int quantaRemaining = quantaPerBlock - world.getBlockMetadata(x, y, z);
return quantaRemaining;
}
@Override
public boolean canCollideCheck(int meta, boolean fullHit)
{
return fullHit && meta == 0;
}
@Override
public int getMaxRenderHeightMeta()
{
return 0;
}
@Override
public int getLightValue(IBlockAccess world, int x, int y, int z)
{
if (maxScaledLight == 0)
{
return super.getLightValue(world, x, y, z);
}
int data = quantaPerBlock - world.getBlockMetadata(x, y, z) - 1;
return (int) (data / quantaPerBlockFloat * maxScaledLight);
}
@Override
public void updateTick(World world, int x, int y, int z, Random rand)
{
int quantaRemaining = quantaPerBlock - world.getBlockMetadata(x, y, z);
int expQuanta = -101;
// check adjacent block levels if non-source
if (quantaRemaining < quantaPerBlock)
{
int y2 = y - densityDir;
if (world.getBlockId(x, y2, z ) == blockID ||
world.getBlockId(x - 1, y2, z ) == blockID ||
world.getBlockId(x + 1, y2, z ) == blockID ||
world.getBlockId(x, y2, z - 1) == blockID ||
world.getBlockId(x, y2, z + 1) == blockID)
{
expQuanta = quantaPerBlock - 1;
}
else
{
int maxQuanta = -100;
maxQuanta = getLargerQuanta(world, x - 1, y, z, maxQuanta);
maxQuanta = getLargerQuanta(world, x + 1, y, z, maxQuanta);
maxQuanta = getLargerQuanta(world, x, y, z - 1, maxQuanta);
maxQuanta = getLargerQuanta(world, x, y, z + 1, maxQuanta);
expQuanta = maxQuanta - 1;
}
// decay calculation
if (expQuanta != quantaRemaining)
{
quantaRemaining = expQuanta;
if (expQuanta <= 0)
{
world.setBlockToAir(x, y, z);
}
else
{
world.setBlockMetadataWithNotify(x, y, z, quantaPerBlock - expQuanta, 3);
world.scheduleBlockUpdate(x, y, z, blockID, tickRate);
world.notifyBlocksOfNeighborChange(x, y, z, blockID);
}
}
}
// This is a "source" block, set meta to zero, and send a server only update
else if (quantaRemaining >= quantaPerBlock)
{
world.setBlockMetadataWithNotify(x, y, z, 0, 2);
}
// Flow vertically if possible
if (canDisplace(world, x, y + densityDir, z))
{
flowIntoBlock(world, x, y + densityDir, z, 1);
return;
}
// Flow outward if possible
int flowMeta = quantaPerBlock - quantaRemaining + 1;
if (flowMeta >= quantaPerBlock)
{
return;
}
if (isSourceBlock(world, x, y, z) || !isFlowingVertically(world, x, y, z))
{
if (world.getBlockId(x, y - densityDir, z) == blockID)
{
flowMeta = 1;
}
boolean flowTo[] = getOptimalFlowDirections(world, x, y, z);
if (flowTo[0]) flowIntoBlock(world, x - 1, y, z, flowMeta);
if (flowTo[1]) flowIntoBlock(world, x + 1, y, z, flowMeta);
if (flowTo[2]) flowIntoBlock(world, x, y, z - 1, flowMeta);
if (flowTo[3]) flowIntoBlock(world, x, y, z + 1, flowMeta);
}
}
public boolean isFlowingVertically(IBlockAccess world, int x, int y, int z)
{
return world.getBlockId(x, y + densityDir, z) == blockID ||
(world.getBlockId(x, y, z) == blockID && canFlowInto(world, x, y + densityDir, z));
}
public boolean isSourceBlock(IBlockAccess world, int x, int y, int z)
{
return world.getBlockId(x, y, z) == blockID && world.getBlockMetadata(x, y, z) == 0;
}
protected boolean[] getOptimalFlowDirections(World world, int x, int y, int z)
{
for (int side = 0; side < 4; side++)
{
flowCost[side] = 1000;
int x2 = x;
int y2 = y;
int z2 = z;
switch (side)
{
case 0: --x2; break;
case 1: ++x2; break;
case 2: --z2; break;
case 3: ++z2; break;
}
if (!canFlowInto(world, x2, y2, z2) || isSourceBlock(world, x2, y2, z2))
{
continue;
}
if (canFlowInto(world, x2, y2 + densityDir, z2))
{
flowCost[side] = 0;
}
else
{
flowCost[side] = calculateFlowCost(world, x2, y2, z2, 1, side);
}
}
int min = flowCost[0];
for (int side = 1; side < 4; side++)
{
if (flowCost[side] < min)
{
min = flowCost[side];
}
}
for (int side = 0; side < 4; side++)
{
isOptimalFlowDirection[side] = flowCost[side] == min;
}
return isOptimalFlowDirection;
}
protected int calculateFlowCost(World world, int x, int y, int z, int recurseDepth, int side)
{
int cost = 1000;
for (int adjSide = 0; adjSide < 4; adjSide++)
{
if ((adjSide == 0 && side == 1) ||
(adjSide == 1 && side == 0) ||
(adjSide == 2 && side == 3) ||
(adjSide == 3 && side == 2))
{
continue;
}
int x2 = x;
int y2 = y;
int z2 = z;
switch (adjSide)
{
case 0: --x2; break;
case 1: ++x2; break;
case 2: --z2; break;
case 3: ++z2; break;
}
if (!canFlowInto(world, x2, y2, z2) || isSourceBlock(world, x2, y2, z2))
{
continue;
}
if (canFlowInto(world, x2, y2 + densityDir, z2))
{
return recurseDepth;
}
if (recurseDepth >= 4)
{
continue;
}
int min = calculateFlowCost(world, x2, y2, z2, recurseDepth + 1, adjSide);
if (min < cost)
{
cost = min;
}
}
return cost;
}
protected void flowIntoBlock(World world, int x, int y, int z, int meta)
{
if (meta < 0) return;
if (displaceIfPossible(world, x, y, z))
{
world.setBlock(x, y, z, this.blockID, meta, 3);
}
}
protected boolean canFlowInto(IBlockAccess world, int x, int y, int z)
{
if (world.isAirBlock(x, y, z)) return true;
int bId = world.getBlockId(x, y, z);
if (bId == blockID)
{
return true;
}
if (displacementIds.containsKey(bId))
{
return displacementIds.get(bId);
}
Material material = Block.blocksList[bId].blockMaterial;
if (material.blocksMovement() ||
material == Material.water ||
material == Material.lava ||
material == Material.portal)
{
return false;
}
int density = getDensity(world, x, y, z);
if (density == Integer.MAX_VALUE)
{
return true;
}
if (this.density > density)
{
return true;
}
else
{
return false;
}
}
protected int getLargerQuanta(IBlockAccess world, int x, int y, int z, int compare)
{
int quantaRemaining = getQuantaValue(world, x, y, z);
if (quantaRemaining <= 0)
{
return compare;
}
return quantaRemaining >= compare ? quantaRemaining : compare;
}
/* IFluidBlock */
@Override
public FluidStack drain(World world, int x, int y, int z, boolean doDrain)
{
if (!isSourceBlock(world, x, y, z))
{
return null;
}
if (doDrain)
{
world.setBlockToAir(x, y, z);
}
return stack.copy();
}
@Override
public boolean canDrain(World world, int x, int y, int z)
{
return isSourceBlock(world, x, y, z);
}
}

View file

@ -0,0 +1,317 @@
package net.minecraftforge.fluids;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
/**
* This is a cellular-automata based finite fluid block implementation.
*
* It is highly recommended that you use/extend this class for finite fluid blocks.
*
* @author OvermindDL1, KingLemming
*
*/
public class BlockFluidFinite extends BlockFluidBase
{
public BlockFluidFinite(int id, Fluid fluid, Material material)
{
super(id, fluid, material);
}
@Override
public int getQuantaValue(IBlockAccess world, int x, int y, int z)
{
if (world.isAirBlock(x, y, z))
{
return 0;
}
if (world.getBlockId(x, y, z) != blockID) {
return -1;
}
int quantaRemaining = world.getBlockMetadata(x, y, z) + 1;
return quantaRemaining;
}
@Override
public boolean canCollideCheck(int meta, boolean fullHit)
{
return fullHit && meta == quantaPerBlock - 1;
}
@Override
public int getMaxRenderHeightMeta()
{
return quantaPerBlock - 1;
}
@Override
public void updateTick(World world, int x, int y, int z, Random rand)
{
boolean changed = false;
int quantaRemaining = world.getBlockMetadata(x, y, z) + 1;
// Flow vertically if possible
int prevRemaining = quantaRemaining;
quantaRemaining = tryToFlowVerticallyInto(world, x, y, z, quantaRemaining);
if (quantaRemaining < 1)
{
return;
}
else if (quantaRemaining != prevRemaining)
{
changed = true;
if (quantaRemaining == 1)
{
world.setBlockMetadataWithNotify(x, y, z, quantaRemaining - 1, 2);
return;
}
}
else if (quantaRemaining == 1)
{
return;
}
// Flow out if possible
int lowerthan = quantaRemaining - 1;
if (displaceIfPossible(world, x, y, z - 1)) world.setBlock(x, y, z - 1, 0);
if (displaceIfPossible(world, x, y, z + 1)) world.setBlock(x, y, z + 1, 0);
if (displaceIfPossible(world, x - 1, y, z )) world.setBlock(x - 1, y, z, 0);
if (displaceIfPossible(world, x + 1, y, z )) world.setBlock(x + 1, y, z, 0);
int north = getQuantaValueBelow(world, x, y, z - 1, lowerthan);
int south = getQuantaValueBelow(world, x, y, z + 1, lowerthan);
int west = getQuantaValueBelow(world, x - 1, y, z, lowerthan);
int east = getQuantaValueBelow(world, x + 1, y, z, lowerthan);
int total = quantaRemaining;
int count = 1;
if (north >= 0)
{
count++;
total += north;
}
if (south >= 0)
{
count++;
total += south;
}
if (west >= 0)
{
count++;
total += west;
}
if (east >= 0) {
++count;
total += east;
}
if (count == 1)
{
if (changed)
{
world.setBlockMetadataWithNotify(x, y, z, quantaRemaining - 1, 2);
}
return;
}
int each = total / count;
int rem = total % count;
if (north >= 0)
{
int newnorth = each;
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
{
++newnorth;
--rem;
}
if (newnorth != north)
{
if (newnorth == 0)
{
world.setBlock(x, y, z - 1, 0);
}
else
{
world.setBlock(x, y, z - 1, blockID, newnorth - 1, 2);
}
world.scheduleBlockUpdate(x, y, z - 1, blockID, tickRate);
}
--count;
}
if (south >= 0)
{
int newsouth = each;
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
{
++newsouth;
--rem;
}
if (newsouth != south)
{
if (newsouth == 0)
{
world.setBlock(x, y, z + 1, 0);
}
else
{
world.setBlock(x, y, z + 1, blockID, newsouth - 1, 2);
}
world.scheduleBlockUpdate(x, y, z + 1, blockID, tickRate);
}
--count;
}
if (west >= 0)
{
int newwest = each;
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
{
++newwest;
--rem;
}
if (newwest != west) {
if (newwest == 0) {
world.setBlock(x - 1, y, z, 0);
} else {
world.setBlock(x - 1, y, z, blockID, newwest - 1, 2);
}
world.scheduleBlockUpdate(x - 1, y, z, blockID, tickRate);
}
--count;
}
if (east >= 0)
{
int neweast = each;
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
{
++neweast;
--rem;
}
if (neweast != east)
{
if (neweast == 0)
{
world.setBlock(x + 1, y, z, 0);
}
else
{
world.setBlock(x + 1, y, z, blockID, neweast - 1, 2);
}
world.scheduleBlockUpdate(x + 1, y, z, blockID, tickRate);
}
--count;
}
if (rem > 0)
{
++each;
}
world.setBlockMetadataWithNotify(x, y, z, each - 1, 2);
}
public int tryToFlowVerticallyInto(World world, int x, int y, int z, int amtToInput)
{
int otherY = y + densityDir;
if (otherY < 0 || otherY >= world.getHeight())
{
world.setBlockToAir(x, y, z);
return 0;
}
int amt = getQuantaValueBelow(world, x, otherY, z, quantaPerBlock);
if (amt >= 0)
{
amt += amtToInput;
if (amt > quantaPerBlock)
{
world.setBlock(x, otherY, z, blockID, quantaPerBlock - 1, 3);
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
return amt - quantaPerBlock;
}
else if (amt > 0)
{
world.setBlock(x, otherY, z, blockID, amt - 1, 3);
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
world.setBlockToAir(x, y, z);
return 0;
}
return amtToInput;
}
else
{
int density_other = getDensity(world, x, otherY, z);
if (density_other == Integer.MAX_VALUE)
{
if (displaceIfPossible(world, x, otherY, z))
{
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
world.setBlockToAir(x, y, z);
return 0;
}
else
{
return amtToInput;
}
}
if (densityDir < 0)
{
if (density_other < density) // then swap
{
int bId = world.getBlockId(x, otherY, z);
BlockFluidBase block = (BlockFluidBase) Block.blocksList[bId];
int otherData = world.getBlockMetadata(x, otherY, z);
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
world.setBlock(x, y, z, bId, otherData, 3);
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
world.scheduleBlockUpdate(x, y, z, bId, block.tickRate(world));
return 0;
}
}
else
{
if (density_other > density)
{
int bId = world.getBlockId(x, otherY, z);
BlockFluidBase block = (BlockFluidBase) Block.blocksList[bId];
int otherData = world.getBlockMetadata(x, otherY, z);
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
world.setBlock(x, y, z, bId, otherData, 3);
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
world.scheduleBlockUpdate(x, y, z, bId, block.tickRate(world));
return 0;
}
}
return amtToInput;
}
}
/* IFluidBlock */
@Override
public FluidStack drain(World world, int x, int y, int z, boolean doDrain)
{
return null;
}
@Override
public boolean canDrain(World world, int x, int y, int z)
{
return false;
}
}

View file

@ -0,0 +1,306 @@
package net.minecraftforge.fluids;
import java.util.Locale;
import java.util.Map;
import com.google.common.collect.Maps;
import net.minecraft.block.Block;
import net.minecraft.util.Icon;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDummyContainer;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoaderException;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* Minecraft Forge Fluid Implementation
*
* This class is a fluid (liquid or gas) equivalent to "Item." It describes the nature of a fluid
* and contains its general properties.
*
* These properties do not have inherent gameplay mechanics - they are provided so that mods may
* choose to take advantage of them.
*
* Fluid implementations are not required to actively use these properties, nor are objects
* interfacing with fluids required to make use of them, but it is encouraged.
*
* The default values can be used as a reference point for mods adding fluids such as oil or heavy
* water.
*
* @author King Lemming
*
*/
public class Fluid
{
/** The unique identification name for this fluid. */
protected final String fluidName;
/** The unlocalized name of this fluid. */
protected String unlocalizedName;
/** The Icons for this fluid. */
protected Icon stillIcon;
protected Icon flowingIcon;
/**
* The light level emitted by this fluid.
*
* Default value is 0, as most fluids do not actively emit light.
*/
protected int luminosity = 0;
/**
* Density of the fluid - completely arbitrary; negative density indicates that the fluid is
* lighter than air.
*
* Default value is approximately the real-life density of water in kg/m^3.
*/
protected int density = 1000;
/**
* Temperature of the fluid - completely arbitrary; higher temperature indicates that the fluid is
* hotter than air.
*
* Default value is approximately the real-life room temperature of water in degrees Kelvin.
*/
protected int temperature = 295;
/**
* Viscosity ("thickness") of the fluid - completely arbitrary; negative values are not
* permissible.
*
* Default value is approximately the real-life density of water in m/s^2 (x10^-3).
*/
protected int viscosity = 1000;
/**
* This indicates if the fluid is gaseous.
*
* Useful for rendering the fluid in containers and the world.
*
* Generally this is associated with negative density fluids.
*/
protected boolean isGaseous;
/**
* If there is a Block implementation of the Fluid, the BlockID is linked here.
*
* The default value of -1 should remain for any Fluid without a Block implementation.
*/
protected int blockID = -1;
public Fluid(String fluidName)
{
this.fluidName = fluidName.toLowerCase(Locale.ENGLISH);
this.unlocalizedName = fluidName;
}
public Fluid setUnlocalizedName(String unlocalizedName)
{
this.unlocalizedName = unlocalizedName;
return this;
}
public Fluid setBlockID(int blockID)
{
if (this.blockID == -1 || this.blockID == blockID)
{
this.blockID = blockID;
}
else if (!ForgeDummyContainer.forceDuplicateFluidBlockCrash)
{
FMLLog.warning("A mod has attempted to assign BlockID " + blockID + " to the Fluid '" + fluidName + "' but this Fluid has already been linked to BlockID "
+ this.blockID + ". Configure your mods to prevent this from happening.");
}
else
{
FMLLog.severe("A mod has attempted to assign BlockID " + blockID + " to the Fluid '" + fluidName + "' but this Fluid has already been linked to BlockID "
+ this.blockID + ". Configure your mods to prevent this from happening.");
throw new LoaderException(new RuntimeException("A mod has attempted to assign BlockID " + blockID + " to the Fluid '" + fluidName
+ "' but this Fluid has already been linked to BlockID " + this.blockID + ". Configure your mods to prevent this from happening."));
}
return this;
}
public Fluid setBlockID(Block block)
{
return setBlockID(block.blockID);
}
public Fluid setLuminosity(int luminosity)
{
this.luminosity = luminosity;
return this;
}
public Fluid setDensity(int density)
{
this.density = density;
return this;
}
public Fluid setTemperature(int temperature)
{
this.temperature = temperature;
return this;
}
public Fluid setViscosity(int viscosity)
{
this.viscosity = viscosity;
return this;
}
public Fluid setGaseous(boolean isGaseous)
{
this.isGaseous = isGaseous;
return this;
}
public final String getName()
{
return this.fluidName;
}
public final int getID()
{
return FluidRegistry.getFluidID(this.fluidName);
}
public final int getBlockID()
{
return blockID;
}
public final boolean canBePlacedInWorld()
{
return blockID != -1;
}
/**
* Returns the localized name of this fluid.
*/
public String getLocalizedName()
{
String s = this.getUnlocalizedName();
return s == null ? "" : StatCollector.translateToLocal(s);
}
/**
* Returns the unlocalized name of this fluid.
*/
public String getUnlocalizedName()
{
return "fluid." + this.unlocalizedName;
}
/**
* Returns 0 for "/terrain.png". ALL FLUID TEXTURES MUST BE ON THIS SHEET.
*/
public final int getSpriteNumber()
{
return 0;
}
/* Default Accessors */
public final int getLuminosity()
{
return this.luminosity;
}
public final int getDensity()
{
return this.density;
}
public final int getTemperature()
{
return this.temperature;
}
public final int getViscosity()
{
return this.viscosity;
}
public final boolean isGaseous()
{
return this.isGaseous;
}
public int getColor()
{
return 0xFFFFFF;
}
public final Fluid setStillIcon(Icon stillIcon)
{
this.stillIcon = stillIcon;
return this;
}
public final Fluid setFlowingIcon(Icon flowingIcon)
{
this.flowingIcon = flowingIcon;
return this;
}
public final Fluid setIcons(Icon stillIcon, Icon flowingIcon)
{
return this.setStillIcon(stillIcon).setFlowingIcon(flowingIcon);
}
public final Fluid setIcons(Icon commonIcon)
{
return this.setStillIcon(commonIcon).setFlowingIcon(commonIcon);
}
public Icon getIcon(){ return getStillIcon(); }
public Icon getStillIcon()
{
return this.stillIcon;
}
public Icon getFlowingIcon()
{
return this.flowingIcon;
}
/* Stack-based Accessors */
public int getLuminosity(FluidStack stack){ return getLuminosity(); }
public int getDensity(FluidStack stack){ return getDensity(); }
public int getTemperature(FluidStack stack){ return getTemperature(); }
public int getViscosity(FluidStack stack){ return getViscosity(); }
public boolean isGaseous(FluidStack stack){ return isGaseous(); }
public int getColor(FluidStack stack){ return getColor(); }
public Icon getIcon(FluidStack stack){ return getIcon(); }
/* World-based Accessors */
public int getLuminosity(World world, int x, int y, int z){ return getLuminosity(); }
public int getDensity(World world, int x, int y, int z){ return getDensity(); }
public int getTemperature(World world, int x, int y, int z){ return getTemperature(); }
public int getViscosity(World world, int x, int y, int z){ return getViscosity(); }
public boolean isGaseous(World world, int x, int y, int z){ return isGaseous(); }
public int getColor(World world, int x, int y, int z){ return getColor(); }
public Icon getIcon(World world, int x, int y, int z){ return getIcon(); }
private static Map<String, String> legacyNames = Maps.newHashMap();
static String convertLegacyName(String fluidName)
{
return fluidName != null && legacyNames.containsKey(fluidName) ? legacyNames.get(fluidName) : fluidName;
}
/**
* Register a legacy liquid name with the Fluids system
* @param legacyName The legacy name to recognize
* @param canonicalName The canonical fluid name it will become
*/
public static void registerLegacyName(String legacyName, String canonicalName)
{
legacyNames.put(legacyName.toLowerCase(Locale.ENGLISH), canonicalName);
}
}

View file

@ -0,0 +1,278 @@
package net.minecraftforge.fluids;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Event;
/**
* Register simple items that contain fluids here. Useful for buckets, bottles, and things that have
* ID/metadata mappings.
*
* For more complex items, use {@link IFluidContainerItem} instead.
*
* @author King Lemming
*
*/
public abstract class FluidContainerRegistry
{
private static Map<List, FluidContainerData> containerFluidMap = new HashMap();
private static Map<List, FluidContainerData> filledContainerMap = new HashMap();
private static Set<List> emptyContainers = new HashSet();
public static final int BUCKET_VOLUME = 1000;
public static final ItemStack EMPTY_BUCKET = new ItemStack(Item.bucketEmpty);
public static final ItemStack EMPTY_BOTTLE = new ItemStack(Item.glassBottle);
private static final ItemStack NULL_EMPTYCONTAINER = new ItemStack(Item.bucketEmpty);
static
{
registerFluidContainer(FluidRegistry.WATER, new ItemStack(Item.bucketWater), EMPTY_BUCKET);
registerFluidContainer(FluidRegistry.LAVA, new ItemStack(Item.bucketLava), EMPTY_BUCKET);
registerFluidContainer(FluidRegistry.WATER, new ItemStack(Item.potion), EMPTY_BOTTLE);
}
private FluidContainerRegistry(){}
/**
* Register a new fluid containing item.
*
* @param stack
* FluidStack containing the type and amount of the fluid stored in the item.
* @param filledContainer
* ItemStack representing the container when it is full.
* @param emptyContainer
* ItemStack representing the container when it is empty.
* @return True if container was successfully registered; false if it already is.
*/
public static boolean registerFluidContainer(FluidStack stack, ItemStack filledContainer, ItemStack emptyContainer)
{
return registerFluidContainer(new FluidContainerData(stack, filledContainer, emptyContainer));
}
/**
* Register a new fluid containing item. The item is assumed to hold 1000 mB of fluid. Also
* registers the Fluid if possible.
*
* @param fluid
* Fluid type that is stored in the item.
* @param filledContainer
* ItemStack representing the container when it is full.
* @param emptyContainer
* ItemStack representing the container when it is empty.
* @return True if container was successfully registered; false if it already is.
*/
public static boolean registerFluidContainer(Fluid fluid, ItemStack filledContainer, ItemStack emptyContainer)
{
if (!FluidRegistry.isFluidRegistered(fluid))
{
FluidRegistry.registerFluid(fluid);
}
return registerFluidContainer(new FluidStack(fluid, BUCKET_VOLUME), filledContainer, emptyContainer);
}
/**
* Register a new fluid containing item that does not have an empty container.
*
* @param stack
* FluidStack containing the type and amount of the fluid stored in the item.
* @param filledContainer
* ItemStack representing the container when it is full.
* @return True if container was successfully registered; false if it already is.
*/
public static boolean registerFluidContainer(FluidStack stack, ItemStack filledContainer)
{
return registerFluidContainer(new FluidContainerData(stack, filledContainer, null, true));
}
/**
* Register a new fluid containing item that does not have an empty container. The item is
* assumed to hold 1000 mB of fluid. Also registers the Fluid if possible.
*
* @param fluid
* Fluid type that is stored in the item.
* @param filledContainer
* ItemStack representing the container when it is full.
* @return True if container was successfully registered; false if it already is.
*/
public static boolean registerFluidContainer(Fluid fluid, ItemStack filledContainer)
{
if (!FluidRegistry.isFluidRegistered(fluid))
{
FluidRegistry.registerFluid(fluid);
}
return registerFluidContainer(new FluidStack(fluid, BUCKET_VOLUME), filledContainer);
}
/**
* Register a new fluid containing item.
*
* @param data
* See {@link FluidContainerData}.
* @return True if container was successfully registered; false if it already is.
*/
public static boolean registerFluidContainer(FluidContainerData data)
{
if (isFilledContainer(data.filledContainer))
{
return false;
}
containerFluidMap.put(Arrays.asList(data.filledContainer.itemID, data.filledContainer.getItemDamage()), data);
if (data.emptyContainer != null && data.emptyContainer != NULL_EMPTYCONTAINER)
{
filledContainerMap.put(Arrays.asList(data.emptyContainer.itemID, data.emptyContainer.getItemDamage(), data.fluid.fluidID), data);
emptyContainers.add(Arrays.asList(data.emptyContainer.itemID, data.emptyContainer.getItemDamage()));
}
MinecraftForge.EVENT_BUS.post(new FluidContainerRegisterEvent(data));
return true;
}
/**
* Determines the fluid type and amount inside a container.
*
* @param container
* The fluid container.
* @return FluidStack representing stored fluid.
*/
public static FluidStack getFluidForFilledItem(ItemStack container)
{
if (container == null)
{
return null;
}
FluidContainerData data = containerFluidMap.get(Arrays.asList(container.itemID, container.getItemDamage()));
return data == null ? null : data.fluid.copy();
}
/**
* Attempts to fill an empty container with a fluid.
*
* NOTE: Returns null on fail, NOT the empty container.
*
* @param fluid
* FluidStack containing the type and amount of fluid to fill.
* @param container
* ItemStack representing the empty container.
* @return Filled container if successful, otherwise null.
*/
public static ItemStack fillFluidContainer(FluidStack fluid, ItemStack container)
{
if (container == null || fluid == null)
{
return null;
}
FluidContainerData data = filledContainerMap.get(Arrays.asList(container.itemID, container.getItemDamage(), fluid.fluidID));
if (data != null && fluid.amount >= data.fluid.amount)
{
return data.filledContainer.copy();
}
return null;
}
/**
* Determines if a container holds a specific fluid.
*/
public static boolean containsFluid(ItemStack container, FluidStack fluid)
{
if (container == null || fluid == null)
{
return false;
}
FluidContainerData data = filledContainerMap.get(Arrays.asList(container.itemID, container.getItemDamage(), fluid.fluidID));
return data == null ? false : data.fluid.isFluidEqual(fluid);
}
public static boolean isBucket(ItemStack container)
{
if (container == null)
{
return false;
}
if (container.isItemEqual(EMPTY_BUCKET))
{
return true;
}
FluidContainerData data = containerFluidMap.get(Arrays.asList(container.itemID, container.getItemDamage()));
return data != null && data.emptyContainer.isItemEqual(EMPTY_BUCKET);
}
public static boolean isContainer(ItemStack container)
{
return isEmptyContainer(container) || isFilledContainer(container);
}
public static boolean isEmptyContainer(ItemStack container)
{
return container != null && emptyContainers.contains(Arrays.asList(container.itemID, container.getItemDamage()));
}
public static boolean isFilledContainer(ItemStack container)
{
return container != null && getFluidForFilledItem(container) != null;
}
public static FluidContainerData[] getRegisteredFluidContainerData()
{
return containerFluidMap.values().toArray(new FluidContainerData[containerFluidMap.size()]);
}
/**
* Wrapper class for the registry entries. Ensures that none of the attempted registrations
* contain null references unless permitted.
*/
public static class FluidContainerData
{
public final FluidStack fluid;
public final ItemStack filledContainer;
public final ItemStack emptyContainer;
public FluidContainerData(FluidStack stack, ItemStack filledContainer, ItemStack emptyContainer)
{
this(stack, filledContainer, emptyContainer, false);
}
public FluidContainerData(FluidStack stack, ItemStack filledContainer, ItemStack emptyContainer, boolean nullEmpty)
{
this.fluid = stack;
this.filledContainer = filledContainer;
this.emptyContainer = emptyContainer == null ? NULL_EMPTYCONTAINER : emptyContainer;
if (stack == null || filledContainer == null || emptyContainer == null && !nullEmpty)
{
throw new RuntimeException("Invalid FluidContainerData - a parameter was null.");
}
}
public FluidContainerData copy()
{
return new FluidContainerData(fluid, filledContainer, emptyContainer, true);
}
}
public static class FluidContainerRegisterEvent extends Event
{
public final FluidContainerData data;
public FluidContainerRegisterEvent(FluidContainerData data)
{
this.data = data.copy();
}
}
}

View file

@ -0,0 +1,97 @@
package net.minecraftforge.fluids;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Event;
public class FluidEvent extends Event
{
public final FluidStack fluid;
public final int x;
public final int y;
public final int z;
public final World world;
public FluidEvent(FluidStack fluid, World world, int x, int y, int z)
{
this.fluid = fluid;
this.world = world;
this.x = x;
this.y = y;
this.z = z;
}
/**
* Mods should fire this event when they move fluids around.
*
* @author cpw
*
*/
public static class FluidMotionEvent extends FluidEvent
{
public FluidMotionEvent(FluidStack fluid, World world, int x, int y, int z)
{
super(fluid, world, x, y, z);
}
}
/**
* Mods should fire this event when a fluid is {@link IFluidTank#fill(FluidStack, boolean)}
* their tank implementation. {@link FluidTank} does.
*
* @author cpw
*
*/
public static class FluidFillingEvent extends FluidEvent
{
public final IFluidTank tank;
public FluidFillingEvent(FluidStack fluid, World world, int x, int y, int z, IFluidTank tank)
{
super(fluid, world, x, y, z);
this.tank = tank;
}
}
/**
* Mods should fire this event when a fluid is {@link IFluidTank#drain(int, boolean)} from their
* tank.
*
* @author cpw
*
*/
public static class FluidDrainingEvent extends FluidEvent
{
public final IFluidTank tank;
public FluidDrainingEvent(FluidStack fluid, World world, int x, int y, int z, IFluidTank tank)
{
super(fluid, world, x, y, z);
this.tank = tank;
}
}
/**
* Mods should fire this event when a fluid "spills", for example, if a block containing fluid
* is broken.
*
* @author cpw
*
*/
public static class FluidSpilledEvent extends FluidEvent
{
public FluidSpilledEvent(FluidStack fluid, World world, int x, int y, int z)
{
super(fluid, world, x, y, z);
}
}
/**
* A handy shortcut for firing the various fluid events.
*
* @param event
*/
public static final void fireEvent(FluidEvent event)
{
MinecraftForge.EVENT_BUS.post(event);
}
}

View file

@ -0,0 +1,52 @@
package net.minecraftforge.fluids;
import java.util.Map;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetworkManager;
import net.minecraftforge.common.network.ForgePacket;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
public class FluidIdMapPacket extends ForgePacket
{
private BiMap<String, Integer> fluidIds = HashBiMap.create();
@Override
public byte[] generatePacket()
{
ByteArrayDataOutput dat = ByteStreams.newDataOutput();
dat.writeInt(FluidRegistry.maxID);
for (Map.Entry<String, Integer> entry : FluidRegistry.fluidIDs.entrySet())
{
dat.writeUTF(entry.getKey());
dat.writeInt(entry.getValue());
}
return dat.toByteArray();
}
@Override
public ForgePacket consumePacket(byte[] data)
{
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
int listSize = dat.readInt();
for (int i = 0; i < listSize; i++) {
String fluidName = dat.readUTF();
int fluidId = dat.readInt();
fluidIds.put(fluidName, fluidId);
}
return this;
}
@Override
public void execute(INetworkManager network, EntityPlayer player)
{
FluidRegistry.initFluidIDs(fluidIds);
}
}

View file

@ -0,0 +1,142 @@
package net.minecraftforge.fluids;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Event;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableMap;
/**
* Handles Fluid registrations. Fluids MUST be registered in order to function.
*
* @author King Lemming, CovertJaguar (LiquidDictionary)
*
*/
public abstract class FluidRegistry
{
static int maxID = 0;
static HashMap<String, Fluid> fluids = new HashMap();
static BiMap<String, Integer> fluidIDs = HashBiMap.create();
public static final Fluid WATER = new Fluid("water").setBlockID(Block.waterStill.blockID).setUnlocalizedName(Block.waterStill.getUnlocalizedName());
public static final Fluid LAVA = new Fluid("lava").setBlockID(Block.lavaStill.blockID).setLuminosity(15).setDensity(3000).setViscosity(6000).setTemperature(1300).setUnlocalizedName(Block.lavaStill.getUnlocalizedName());
public static int renderIdFluid = -1;
static
{
registerFluid(WATER);
registerFluid(LAVA);
}
private FluidRegistry(){}
/**
* Called by Forge to prepare the ID map for server -> client sync.
*/
static void initFluidIDs(BiMap<String, Integer> newfluidIDs)
{
maxID = newfluidIDs.size();
fluidIDs.clear();
fluidIDs.putAll(newfluidIDs);
}
/**
* Register a new Fluid. If a fluid with the same name already exists, registration is denied.
*
* @param fluid
* The fluid to register.
* @return True if the fluid was successfully registered; false if there is a name clash.
*/
public static boolean registerFluid(Fluid fluid)
{
if (fluidIDs.containsKey(fluid.getName()))
{
return false;
}
fluids.put(fluid.getName(), fluid);
fluidIDs.put(fluid.getName(), ++maxID);
MinecraftForge.EVENT_BUS.post(new FluidRegisterEvent(fluid.getName(), maxID));
return true;
}
public static boolean isFluidRegistered(Fluid fluid)
{
return fluidIDs.containsKey(fluid.getName());
}
public static boolean isFluidRegistered(String fluidName)
{
return fluidIDs.containsKey(fluidName);
}
public static Fluid getFluid(String fluidName)
{
return fluids.get(fluidName);
}
public static Fluid getFluid(int fluidID)
{
return fluids.get(getFluidName(fluidID));
}
public static String getFluidName(int fluidID)
{
return fluidIDs.inverse().get(fluidID);
}
public static String getFluidName(FluidStack stack)
{
return getFluidName(stack.fluidID);
}
public static int getFluidID(String fluidName)
{
return fluidIDs.get(fluidName);
}
public static FluidStack getFluidStack(String fluidName, int amount)
{
if (!fluidIDs.containsKey(fluidName))
{
return null;
}
return new FluidStack(getFluidID(fluidName), amount);
}
/**
* Returns a read-only map containing Fluid Names and their associated Fluids.
*/
public static Map<String, Fluid> getRegisteredFluids()
{
return ImmutableMap.copyOf(fluids);
}
/**
* Returns a read-only map containing Fluid Names and their associated IDs.
*/
public static Map<String, Integer> getRegisteredFluidIDs()
{
return ImmutableMap.copyOf(fluidIDs);
}
public static class FluidRegisterEvent extends Event
{
public final String fluidName;
public final int fluidID;
public FluidRegisterEvent(String fluidName, int fluidID)
{
this.fluidName = fluidName;
this.fluidID = fluidID;
}
}
}

View file

@ -0,0 +1,203 @@
package net.minecraftforge.fluids;
import java.util.Locale;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
/**
* ItemStack substitute for Fluids.
*
* NOTE: Equality is based on the Fluid, not the amount. Use
* {@link #isFluidStackIdentical(FluidStack)} to determine if FluidID, Amount and NBT Tag are all
* equal.
*
* @author King Lemming, SirSengir (LiquidStack)
*
*/
public class FluidStack
{
public int fluidID;
public int amount;
public NBTTagCompound tag;
public FluidStack(Fluid fluid, int amount)
{
this.fluidID = fluid.getID();
this.amount = amount;
}
public FluidStack(int fluidID, int amount)
{
this.fluidID = fluidID;
this.amount = amount;
}
public FluidStack(int fluidID, int amount, NBTTagCompound nbt)
{
this(fluidID, amount);
if (nbt != null)
{
tag = (NBTTagCompound) nbt.copy();
}
}
public FluidStack(FluidStack stack, int amount)
{
this(stack.fluidID, amount, stack.tag);
}
/**
* This provides a safe method for retrieving a FluidStack - if the Fluid is invalid, the stack
* will return as null.
*/
public static FluidStack loadFluidStackFromNBT(NBTTagCompound nbt)
{
if (nbt == null)
{
return null;
}
String fluidName = nbt.getString("FluidName");
if (fluidName == null)
{
fluidName = nbt.hasKey("LiquidName") ? nbt.getString("LiquidName").toLowerCase(Locale.ENGLISH) : null;
fluidName = Fluid.convertLegacyName(fluidName);
}
if (fluidName ==null || FluidRegistry.getFluid(fluidName) == null)
{
return null;
}
FluidStack stack = new FluidStack(FluidRegistry.getFluidID(fluidName), nbt.getInteger("Amount"));
if (nbt.hasKey("Tag"))
{
stack.tag = nbt.getCompoundTag("Tag");
}
else if (nbt.hasKey("extra"))
{
stack.tag = nbt.getCompoundTag("extra");
}
return stack;
}
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
{
nbt.setString("FluidName", FluidRegistry.getFluidName(fluidID));
nbt.setInteger("Amount", amount);
if (tag != null)
{
nbt.setTag("Tag", tag);
}
return nbt;
}
public final Fluid getFluid()
{
return FluidRegistry.getFluid(fluidID);
}
/**
* @return A copy of this FluidStack
*/
public FluidStack copy()
{
return new FluidStack(fluidID, amount, tag);
}
/**
* Determines if the FluidIDs and NBT Tags are equal. This does not check amounts.
*
* @param other
* The FluidStack for comparison
* @return true if the Fluids (IDs and NBT Tags) are the same
*/
public boolean isFluidEqual(FluidStack other)
{
return other != null && fluidID == other.fluidID && isFluidStackTagEqual(other);
}
private boolean isFluidStackTagEqual(FluidStack other)
{
return tag == null ? other.tag == null : other.tag == null ? false : tag.equals(other.tag);
}
/**
* Determines if the NBT Tags are equal. Useful if the FluidIDs are known to be equal.
*/
public static boolean areFluidStackTagsEqual(FluidStack stack1, FluidStack stack2)
{
return stack1 == null && stack2 == null ? true : stack1 == null || stack2 == null ? false : stack1.isFluidStackTagEqual(stack2);
}
/**
* Determines if the Fluids are equal and this stack is larger.
*
* @param other
* @return true if this FluidStack contains the other FluidStack (same fluid and >= amount)
*/
public boolean containsFluid(FluidStack other)
{
return isFluidEqual(other) && amount >= other.amount;
}
/**
* Determines if the FluidIDs, Amounts, and NBT Tags are all equal.
*
* @param other
* - the FluidStack for comparison
* @return true if the two FluidStacks are exactly the same
*/
public boolean isFluidStackIdentical(FluidStack other)
{
return isFluidEqual(other) && amount == other.amount;
}
/**
* Determines if the FluidIDs and NBT Tags are equal compared to a registered container
* ItemStack. This does not check amounts.
*
* @param other
* The ItemStack for comparison
* @return true if the Fluids (IDs and NBT Tags) are the same
*/
public boolean isFluidEqual(ItemStack other)
{
if (other == null)
{
return false;
}
if (other.getItem() instanceof IFluidContainerItem)
{
return isFluidEqual(((IFluidContainerItem) other.getItem()).getFluid(other));
}
return isFluidEqual(FluidContainerRegistry.getFluidForFilledItem(other));
}
@Override
public final int hashCode()
{
return fluidID;
}
/**
* Default equality comparison for a FluidStack. Same functionality as isFluidEqual().
*
* This is included for use in data structures.
*/
@Override
public final boolean equals(Object o)
{
if (!(o instanceof FluidStack))
{
return false;
}
return isFluidEqual((FluidStack) o);
}
}

View file

@ -0,0 +1,188 @@
package net.minecraftforge.fluids;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
/**
* Reference implementation of {@link IFluidTank}. Use/extend this or implement your own.
*
* @author King Lemming, cpw (LiquidTank)
*
*/
public class FluidTank implements IFluidTank
{
protected FluidStack fluid;
protected int capacity;
protected TileEntity tile;
public FluidTank(int capacity)
{
this(null, capacity);
}
public FluidTank(FluidStack stack, int capacity)
{
this.fluid = stack;
this.capacity = capacity;
}
public FluidTank(Fluid fluid, int amount, int capacity)
{
this(new FluidStack(fluid, amount), capacity);
}
public FluidTank readFromNBT(NBTTagCompound nbt)
{
if (!nbt.hasKey("Empty"))
{
FluidStack fluid = FluidStack.loadFluidStackFromNBT(nbt);
if (fluid != null)
{
setFluid(fluid);
}
}
return this;
}
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
{
if (fluid != null)
{
fluid.writeToNBT(nbt);
}
else
{
nbt.setString("Empty", "");
}
return nbt;
}
public void setFluid(FluidStack fluid)
{
this.fluid = fluid;
}
public void setCapacity(int capacity)
{
this.capacity = capacity;
}
/* IFluidTank */
@Override
public FluidStack getFluid()
{
return fluid;
}
@Override
public int getFluidAmount()
{
if (fluid == null)
{
return 0;
}
return fluid.amount;
}
@Override
public int getCapacity()
{
return capacity;
}
@Override
public FluidTankInfo getInfo()
{
return new FluidTankInfo(this);
}
@Override
public int fill(FluidStack resource, boolean doFill)
{
if (resource == null)
{
return 0;
}
if (!doFill)
{
if (fluid == null)
{
return Math.min(capacity, resource.amount);
}
if (!fluid.isFluidEqual(resource))
{
return 0;
}
return Math.min(capacity - fluid.amount, resource.amount);
}
if (fluid == null)
{
fluid = new FluidStack(resource, Math.min(capacity, resource.amount));
if (tile != null)
{
FluidEvent.fireEvent(new FluidEvent.FluidFillingEvent(fluid, tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, this));
}
return fluid.amount;
}
if (!fluid.isFluidEqual(resource))
{
return 0;
}
int filled = capacity - fluid.amount;
if (resource.amount < filled)
{
fluid.amount += resource.amount;
filled = resource.amount;
}
else
{
fluid.amount = capacity;
}
if (tile != null)
{
FluidEvent.fireEvent(new FluidEvent.FluidFillingEvent(fluid, tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, this));
}
return filled;
}
@Override
public FluidStack drain(int maxDrain, boolean doDrain)
{
if (fluid == null)
{
return null;
}
int drained = maxDrain;
if (fluid.amount < drained)
{
drained = fluid.amount;
}
FluidStack stack = new FluidStack(fluid, drained);
if (doDrain)
{
fluid.amount -= drained;
if (fluid.amount <= 0)
{
fluid = null;
}
if (tile != null)
{
FluidEvent.fireEvent(new FluidEvent.FluidDrainingEvent(fluid, tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, this));
}
}
return stack;
}
}

View file

@ -0,0 +1,25 @@
package net.minecraftforge.fluids;
/**
* Wrapper class used to encapsulate information about an IFluidTank.
*
* @author King Lemming
*
*/
public final class FluidTankInfo
{
public final FluidStack fluid;
public final int capacity;
public FluidTankInfo(FluidStack fluid, int capacity)
{
this.fluid = fluid;
this.capacity = capacity;
}
public FluidTankInfo(IFluidTank tank)
{
this.fluid = tank.getFluid();
this.capacity = tank.getCapacity();
}
}

View file

@ -0,0 +1,51 @@
package net.minecraftforge.fluids;
import net.minecraft.world.World;
/**
* Implement this interface on Block classes which represent world-placeable Fluids.
*
* NOTE: Using/extending the reference implementations {@link BlockFluidBase} is encouraged.
*
* @author King Lemming
*
*/
public interface IFluidBlock
{
/**
* Returns the Fluid associated with this Block.
*/
Fluid getFluid();
/**
* Attempt to drain the block. This method should be called by devices such as pumps.
*
* NOTE: The block is intended to handle its own state changes.
*
* @param doDrain
* If false, the drain will only be simulated.
* @return
*/
FluidStack drain(World world, int x, int y, int z, boolean doDrain);
/**
* Check to see if a block can be drained. This method should be called by devices such as
* pumps.
*
* @param doDrain
* If false, the drain will only be simulated.
* @return
*/
boolean canDrain(World world, int x, int y, int z);
/**
* Returns the amount of a single block is filled. Value between 0 and 1.
* 1 meaning the entire 1x1x1 cube is full, 0 meaning completely empty.
*
* If the return value is negative. It will be treated as filling the block
* from the top down instead of bottom up.
*
* @return
*/
float getFilledPercentage(World world, int x, int y, int z);
}

View file

@ -0,0 +1,59 @@
package net.minecraftforge.fluids;
import net.minecraft.item.ItemStack;
/**
* Implement this interface on Item classes that support external manipulation of their internal
* fluid storage.
*
* A reference implementation is provided {@link ItemFluidContainer}.
*
* NOTE: Use of NBT data on the containing ItemStack is encouraged.
*
* @author King Lemming
*
*/
public interface IFluidContainerItem
{
/**
*
* @param container
* ItemStack which is the fluid container.
* @return FluidStack representing the fluid in the container, null if the container is empty.
*/
FluidStack getFluid(ItemStack container);
/**
*
* @param container
* ItemStack which is the fluid container.
* @return Capacity of this fluid container.
*/
int getCapacity(ItemStack container);
/**
*
* @param container
* ItemStack which is the fluid container.
* @param resource
* FluidStack attempting to fill the container.
* @param doFill
* If false, the fill will only be simulated.
* @return Amount of fluid that was (or would have been, if simulated) filled into the
* container.
*/
int fill(ItemStack container, FluidStack resource, boolean doFill);
/**
*
* @param container
* ItemStack which is the fluid container.
* @param maxDrain
* Maximum amount of fluid to be removed from the container.
* @param doFill
* If false, the drain will only be simulated.
* @return Amount of fluid that was (or would have been, if simulated) drained from the
* container.
*/
FluidStack drain(ItemStack container, int maxDrain, boolean doDrain);
}

View file

@ -0,0 +1,82 @@
package net.minecraftforge.fluids;
import net.minecraftforge.common.ForgeDirection;
/**
* Implement this interface on TileEntities which should handle fluids, generally storing them in
* one or more internal {@link IFluidTank} objects.
*
* A reference implementation is provided {@link TileFluidHandler}.
*
* @author King Lemming
*
*/
public interface IFluidHandler
{
/**
* Fills fluid into internal tanks, distribution is left entirely to the IFluidHandler.
*
* @param from
* Orientation the Fluid is pumped in from.
* @param resource
* FluidStack representing the Fluid and maximum amount of fluid to be filled.
* @param doFill
* If false, fill will only be simulated.
* @return Amount of resource that was (or would have been, if simulated) filled.
*/
int fill(ForgeDirection from, FluidStack resource, boolean doFill);
/**
* Drains fluid out of internal tanks, distribution is left entirely to the IFluidHandler.
*
* @param from
* Orientation the Fluid is drained to.
* @param resource
* FluidStack representing the Fluid and maximum amount of fluid to be drained.
* @param doDrain
* If false, drain will only be simulated.
* @return FluidStack representing the Fluid and amount that was (or would have been, if
* simulated) drained.
*/
FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain);
/**
* Drains fluid out of internal tanks, distribution is left entirely to the IFluidHandler.
*
* This method is not Fluid-sensitive.
*
* @param from
* Orientation the fluid is drained to.
* @param maxDrain
* Maximum amount of fluid to drain.
* @param doDrain
* If false, drain will only be simulated.
* @return FluidStack representing the Fluid and amount that was (or would have been, if
* simulated) drained.
*/
FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain);
/**
* Returns true if the given fluid can be inserted into the given direction.
*
* More formally, this should return true if fluid is able to enter from the given direction.
*/
boolean canFill(ForgeDirection from, Fluid fluid);
/**
* Returns true if the given fluid can be extracted from the given direction.
*
* More formally, this should return true if fluid is able to leave from the given direction.
*/
boolean canDrain(ForgeDirection from, Fluid fluid);
/**
* Returns an array of objects which represent the internal tanks. These objects cannot be used
* to manipulate the internal tanks. See {@link FluidTankInfo}.
*
* @param from
* Orientation determining which tanks should be queried.
* @return Info for the relevant internal tanks.
*/
FluidTankInfo[] getTankInfo(ForgeDirection from);
}

View file

@ -0,0 +1,57 @@
package net.minecraftforge.fluids;
/**
* A tank is the unit of interaction with Fluid inventories.
*
* A reference implementation can be found at {@link FluidTank}.
*
* @author King Lemming, cpw (ILiquidTank)
*
*/
public interface IFluidTank
{
/**
* @return FluidStack representing the fluid in the tank, null if the tank is empty.
*/
FluidStack getFluid();
/**
* @return Current amount of fluid in the tank.
*/
int getFluidAmount();
/**
* @return Capacity of this fluid tank.
*/
int getCapacity();
/**
* Returns a wrapper object {@link FluidTankInfo } containing the capacity of the tank and the
* FluidStack it holds.
*
* Should prevent manipulation of the IFluidTank. See {@link FluidTank}.
*
* @return State information for the IFluidTank.
*/
FluidTankInfo getInfo();
/**
*
* @param resource
* FluidStack attempting to fill the tank.
* @param doFill
* If false, the fill will only be simulated.
* @return Amount of fluid that was accepted by the tank.
*/
int fill(FluidStack resource, boolean doFill);
/**
*
* @param maxDrain
* Maximum amount of fluid to be removed from the container.
* @param doFill
* If false, the fill will only be simulated.
* @return Amount of fluid that was removed from the tank.
*/
FluidStack drain(int maxDrain, boolean doDrain);
}

View file

@ -0,0 +1,158 @@
package net.minecraftforge.fluids;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
/**
* Reference implementation of {@link IFluidContainerItem}. Use/extend this or implement your own.
*
* @author King Lemming
*
*/
public class ItemFluidContainer extends Item implements IFluidContainerItem
{
protected int capacity;
public ItemFluidContainer(int itemID)
{
super(itemID);
}
public ItemFluidContainer(int itemID, int capacity)
{
super(itemID);
this.capacity = capacity;
}
public ItemFluidContainer setCapacity(int capacity)
{
this.capacity = capacity;
return this;
}
/* IFluidContainerItem */
@Override
public FluidStack getFluid(ItemStack container)
{
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Fluid"))
{
return null;
}
return FluidStack.loadFluidStackFromNBT(container.stackTagCompound.getCompoundTag("Fluid"));
}
@Override
public int getCapacity(ItemStack container)
{
return capacity;
}
@Override
public int fill(ItemStack container, FluidStack resource, boolean doFill)
{
if (resource == null)
{
return 0;
}
if (!doFill)
{
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Fluid"))
{
return Math.min(capacity, resource.amount);
}
FluidStack stack = FluidStack.loadFluidStackFromNBT(container.stackTagCompound.getCompoundTag("Fluid"));
if (stack == null)
{
return Math.min(capacity, resource.amount);
}
if (!stack.isFluidEqual(resource))
{
return 0;
}
return Math.min(capacity - stack.amount, resource.amount);
}
if (container.stackTagCompound == null)
{
container.stackTagCompound = new NBTTagCompound();
}
if (!container.stackTagCompound.hasKey("Fluid"))
{
NBTTagCompound fluidTag = resource.writeToNBT(new NBTTagCompound());
if (capacity < resource.amount)
{
fluidTag.setInteger("Amount", capacity);
container.stackTagCompound.setTag("Fluid", fluidTag);
return capacity;
}
container.stackTagCompound.setTag("Fluid", fluidTag);
return resource.amount;
}
NBTTagCompound fluidTag = container.stackTagCompound.getCompoundTag("Fluid");
FluidStack stack = FluidStack.loadFluidStackFromNBT(fluidTag);
if (!stack.isFluidEqual(resource))
{
return 0;
}
int filled = capacity - resource.amount;
if (resource.amount < filled)
{
stack.amount += resource.amount;
filled = resource.amount;
}
else
{
stack.amount = capacity;
}
container.stackTagCompound.setTag("Fluid", stack.writeToNBT(fluidTag));
return filled;
}
@Override
public FluidStack drain(ItemStack container, int maxDrain, boolean doDrain)
{
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Fluid"))
{
return null;
}
FluidStack stack = FluidStack.loadFluidStackFromNBT(container.stackTagCompound.getCompoundTag("Fluid"));
if (stack == null)
{
return null;
}
stack.amount = Math.min(stack.amount, maxDrain);
if (doDrain)
{
if (maxDrain >= capacity)
{
container.stackTagCompound.removeTag("Fluid");
if (container.stackTagCompound.hasNoTags())
{
container.stackTagCompound = null;
}
return stack;
}
NBTTagCompound fluidTag = container.stackTagCompound.getCompoundTag("Fluid");
fluidTag.setInteger("Amount", fluidTag.getInteger("Amount") - maxDrain);
container.stackTagCompound.setTag("Fluid", fluidTag);
}
return stack;
}
}

View file

@ -0,0 +1,327 @@
package net.minecraftforge.fluids;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
/**
* Default renderer for Forge fluid blocks.
*
* @author King Lemming
*
*/
public class RenderBlockFluid implements ISimpleBlockRenderingHandler
{
public static RenderBlockFluid instance = new RenderBlockFluid();
static final float LIGHT_Y_NEG = 0.5F;
static final float LIGHT_Y_POS = 1.0F;
static final float LIGHT_XZ_NEG = 0.8F;
static final float LIGHT_XZ_POS = 0.6F;
static final double RENDER_OFFSET = 0.0010000000474974513D;
public float getFluidHeightAverage(float[] flow)
{
float total = 0;
int count = 0;
float end = 0;
for (int i = 0; i < flow.length; i++)
{
if (flow[i] >= 0.875F && end != 1F)
{
end = flow[i];
}
if (flow[i] >= 0)
{
total += flow[i];
count++;
}
}
if (end == 0)
end = total / count;
return end;
}
public float getFluidHeightForRender(IBlockAccess world, int x, int y, int z, BlockFluidBase block)
{
if (world.getBlockId(x, y, z) == block.blockID)
{
if (world.getBlockMaterial(x, y - block.densityDir, z).isLiquid())
{
return 1;
}
if (world.getBlockMetadata(x, y, z) == block.getMaxRenderHeightMeta())
{
return 0.875F;
}
}
return !world.getBlockMaterial(x, y, z).isSolid() && world.getBlockId(x, y - block.densityDir, z) == block.blockID ? 1 : block.getQuantaPercentage(world, x, y, z) * 0.875F;
}
/* ISimpleBlockRenderingHandler */
@Override
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer){}
@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
{
if (!(block instanceof BlockFluidBase))
{
return false;
}
Tessellator tessellator = Tessellator.instance;
int color = block.colorMultiplier(world, x, y, z);
float red = (color >> 16 & 255) / 255.0F;
float green = (color >> 8 & 255) / 255.0F;
float blue = (color & 255) / 255.0F;
BlockFluidBase theFluid = (BlockFluidBase) block;
int bMeta = world.getBlockMetadata(x, y, z);
boolean renderTop = world.getBlockId(x, y - theFluid.densityDir, z) != theFluid.blockID;
boolean renderBottom = block.shouldSideBeRendered(world, x, y + theFluid.densityDir, z, 0) && world.getBlockId(x, y + theFluid.densityDir, z) != theFluid.blockID;
boolean[] renderSides = new boolean[]
{
block.shouldSideBeRendered(world, x, y, z - 1, 2),
block.shouldSideBeRendered(world, x, y, z + 1, 3),
block.shouldSideBeRendered(world, x - 1, y, z, 4),
block.shouldSideBeRendered(world, x + 1, y, z, 5)
};
if (!renderTop && !renderBottom && !renderSides[0] && !renderSides[1] && !renderSides[2] && !renderSides[3])
{
return false;
}
else
{
boolean rendered = false;
double heightNW, heightSW, heightSE, heightNE;
float flow11 = getFluidHeightForRender(world, x, y, z, theFluid);
if (flow11 != 1)
{
float flow00 = getFluidHeightForRender(world, x - 1, y, z - 1, theFluid);
float flow01 = getFluidHeightForRender(world, x - 1, y, z, theFluid);
float flow02 = getFluidHeightForRender(world, x - 1, y, z + 1, theFluid);
float flow10 = getFluidHeightForRender(world, x, y, z - 1, theFluid);
float flow12 = getFluidHeightForRender(world, x, y, z + 1, theFluid);
float flow20 = getFluidHeightForRender(world, x + 1, y, z - 1, theFluid);
float flow21 = getFluidHeightForRender(world, x + 1, y, z, theFluid);
float flow22 = getFluidHeightForRender(world, x + 1, y, z + 1, theFluid);
heightNW = getFluidHeightAverage(new float[]{ flow00, flow01, flow10, flow11 });
heightSW = getFluidHeightAverage(new float[]{ flow01, flow02, flow12, flow11 });
heightSE = getFluidHeightAverage(new float[]{ flow12, flow21, flow22, flow11 });
heightNE = getFluidHeightAverage(new float[]{ flow10, flow20, flow21, flow11 });
}
else
{
heightNW = flow11;
heightSW = flow11;
heightSE = flow11;
heightNE = flow11;
}
boolean rises = theFluid.densityDir == 1;
if (renderer.renderAllFaces || renderTop)
{
rendered = true;
Icon iconStill = block.getIcon(1, bMeta);
float flowDir = (float) BlockFluidBase.getFlowDirection(world, x, y, z);
if (flowDir > -999.0F)
{
iconStill = block.getIcon(2, bMeta);
}
heightNW -= RENDER_OFFSET;
heightSW -= RENDER_OFFSET;
heightSE -= RENDER_OFFSET;
heightNE -= RENDER_OFFSET;
double u1, u2, u3, u4, v1, v2, v3, v4;
if (flowDir < -999.0F)
{
u2 = iconStill.getInterpolatedU(0.0D);
v2 = iconStill.getInterpolatedV(0.0D);
u1 = u2;
v1 = iconStill.getInterpolatedV(16.0D);
u4 = iconStill.getInterpolatedU(16.0D);
v4 = v1;
u3 = u4;
v3 = v2;
}
else
{
float xFlow = MathHelper.sin(flowDir) * 0.25F;
float zFlow = MathHelper.cos(flowDir) * 0.25F;
u2 = iconStill.getInterpolatedU(8.0F + (-zFlow - xFlow) * 16.0F);
v2 = iconStill.getInterpolatedV(8.0F + (-zFlow + xFlow) * 16.0F);
u1 = iconStill.getInterpolatedU(8.0F + (-zFlow + xFlow) * 16.0F);
v1 = iconStill.getInterpolatedV(8.0F + (zFlow + xFlow) * 16.0F);
u4 = iconStill.getInterpolatedU(8.0F + (zFlow + xFlow) * 16.0F);
v4 = iconStill.getInterpolatedV(8.0F + (zFlow - xFlow) * 16.0F);
u3 = iconStill.getInterpolatedU(8.0F + (zFlow - xFlow) * 16.0F);
v3 = iconStill.getInterpolatedV(8.0F + (-zFlow - xFlow) * 16.0F);
}
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z));
tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
if (!rises)
{
tessellator.addVertexWithUV(x + 0, y + heightNW, z + 0, u2, v2);
tessellator.addVertexWithUV(x + 0, y + heightSW, z + 1, u1, v1);
tessellator.addVertexWithUV(x + 1, y + heightSE, z + 1, u4, v4);
tessellator.addVertexWithUV(x + 1, y + heightNE, z + 0, u3, v3);
}
else
{
tessellator.addVertexWithUV(x + 1, y + 1 - heightNE, z + 0, u3, v3);
tessellator.addVertexWithUV(x + 1, y + 1 - heightSE, z + 1, u4, v4);
tessellator.addVertexWithUV(x + 0, y + 1 - heightSW, z + 1, u1, v1);
tessellator.addVertexWithUV(x + 0, y + 1 - heightNW, z + 0, u2, v2);
}
}
if (renderer.renderAllFaces || renderBottom)
{
rendered = true;
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y - 1, z));
if (!rises)
{
tessellator.setColorOpaque_F(LIGHT_Y_NEG * red, LIGHT_Y_NEG * green, LIGHT_Y_NEG * blue);
renderer.renderFaceYNeg(block, x, y + RENDER_OFFSET, z, block.getIcon(0, bMeta));
}
else
{
tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
renderer.renderFaceYPos(block, x, y + RENDER_OFFSET, z, block.getIcon(1, bMeta));
}
}
for (int side = 0; side < 4; ++side)
{
int x2 = x;
int z2 = z;
switch (side)
{
case 0: --z2; break;
case 1: ++z2; break;
case 2: --x2; break;
case 3: ++x2; break;
}
Icon iconFlow = block.getIcon(side + 2, bMeta);
if (renderer.renderAllFaces || renderSides[side])
{
rendered = true;
double ty1;
double tx1;
double ty2;
double tx2;
double tz1;
double tz2;
if (side == 0)
{
ty1 = heightNW;
ty2 = heightNE;
tx1 = x;
tx2 = x + 1;
tz1 = z + RENDER_OFFSET;
tz2 = z + RENDER_OFFSET;
}
else if (side == 1)
{
ty1 = heightSE;
ty2 = heightSW;
tx1 = x + 1;
tx2 = x;
tz1 = z + 1 - RENDER_OFFSET;
tz2 = z + 1 - RENDER_OFFSET;
}
else if (side == 2)
{
ty1 = heightSW;
ty2 = heightNW;
tx1 = x + RENDER_OFFSET;
tx2 = x + RENDER_OFFSET;
tz1 = z + 1;
tz2 = z;
}
else
{
ty1 = heightNE;
ty2 = heightSE;
tx1 = x + 1 - RENDER_OFFSET;
tx2 = x + 1 - RENDER_OFFSET;
tz1 = z;
tz2 = z + 1;
}
float u1Flow = iconFlow.getInterpolatedU(0.0D);
float u2Flow = iconFlow.getInterpolatedU(8.0D);
float v1Flow = iconFlow.getInterpolatedV((1.0D - ty1) * 16.0D * 0.5D);
float v2Flow = iconFlow.getInterpolatedV((1.0D - ty2) * 16.0D * 0.5D);
float v3Flow = iconFlow.getInterpolatedV(8.0D);
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x2, y, z2));
float sideLighting = 1.0F;
if (side < 2)
{
sideLighting = LIGHT_XZ_NEG;
}
else
{
sideLighting = LIGHT_XZ_POS;
}
tessellator.setColorOpaque_F(LIGHT_Y_POS * sideLighting * red, LIGHT_Y_POS * sideLighting * green, LIGHT_Y_POS * sideLighting * blue);
if (!rises)
{
tessellator.addVertexWithUV(tx1, y + ty1, tz1, u1Flow, v1Flow);
tessellator.addVertexWithUV(tx2, y + ty2, tz2, u2Flow, v2Flow);
tessellator.addVertexWithUV(tx2, y + 0, tz2, u2Flow, v3Flow);
tessellator.addVertexWithUV(tx1, y + 0, tz1, u1Flow, v3Flow);
}
else
{
tessellator.addVertexWithUV(tx1, y + 1 - 0, tz1, u1Flow, v3Flow);
tessellator.addVertexWithUV(tx2, y + 1 - 0, tz2, u2Flow, v3Flow);
tessellator.addVertexWithUV(tx2, y + 1 - ty2, tz2, u2Flow, v2Flow);
tessellator.addVertexWithUV(tx1, y + 1 - ty1, tz1, u1Flow, v1Flow);
}
}
}
renderer.renderMinY = 0;
renderer.renderMaxY = 1;
return rendered;
}
}
@Override
public boolean shouldRender3DInInventory(){ return false; }
@Override
public int getRenderId()
{
return FluidRegistry.renderIdFluid;
}
}

View file

@ -0,0 +1,72 @@
package net.minecraftforge.fluids;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
/**
* Reference Tile Entity implementation of {@link IFluidHandler}. Use/extend this or write your own.
*
* @author King Lemming
*
*/
public class TileFluidHandler extends TileEntity implements IFluidHandler
{
protected FluidTank tank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME);
@Override
public void readFromNBT(NBTTagCompound tag)
{
super.readFromNBT(tag);
tank.writeToNBT(tag);
}
@Override
public void writeToNBT(NBTTagCompound tag)
{
super.writeToNBT(tag);
tank.readFromNBT(tag);
}
/* IFluidHandler */
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
{
return tank.fill(resource, doFill);
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
{
if (resource == null || !resource.isFluidEqual(tank.getFluid()))
{
return null;
}
return tank.drain(resource.amount, doDrain);
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{
return tank.drain(maxDrain, doDrain);
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid)
{
return true;
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid)
{
return true;
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from)
{
return new FluidTankInfo[] { tank.getInfo() };
}
}

View file

@ -8,6 +8,7 @@ import net.minecraft.nbt.NBTTagCompound;
* @author cpw
*
*/
@Deprecated //See new net.minecraftforge.fluids
public interface IBlockLiquid extends ILiquid {
/**
* Controls the type of block that is generated by this IBlockLiquid

View file

@ -13,6 +13,7 @@ package net.minecraftforge.liquids;
* Liquids implement this interface
*
*/
@Deprecated //See new net.minecraftforge.fluids
public interface ILiquid {
/**

View file

@ -5,6 +5,7 @@ package net.minecraftforge.liquids;
*
* @author cpw
*/
@Deprecated //See new net.minecraftforge.fluids
public interface ILiquidTank {
/**

View file

@ -1,7 +1,7 @@
package net.minecraftforge.liquids;
import net.minecraftforge.common.ForgeDirection;
@Deprecated //See new net.minecraftforge.fluids
public interface ITankContainer {
/**

View file

@ -11,7 +11,7 @@ package net.minecraftforge.liquids;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@Deprecated //See new net.minecraftforge.fluids
public class LiquidContainerData {
public final LiquidStack stillLiquid;

View file

@ -12,7 +12,7 @@ import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@Deprecated //See new net.minecraftforge.fluids
public class LiquidContainerRegistry
{
public static final int BUCKET_VOLUME = 1000;

View file

@ -16,6 +16,7 @@ import com.google.common.collect.ImmutableMap;
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
@Deprecated //See new net.minecraftforge.fluids
public abstract class LiquidDictionary
{

View file

@ -4,7 +4,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Event;
@Deprecated //See new net.minecraftforge.fluids
public class LiquidEvent extends Event {
public final LiquidStack liquid;
public final int x;

View file

@ -22,6 +22,7 @@ import net.minecraft.util.Icon;
*
* @author SirSengir
*/
@Deprecated //See new net.minecraftforge.fluids
public class LiquidStack
{
public final int itemID;
@ -66,17 +67,6 @@ public class LiquidStack
return nbt;
}
/**
* NO-OP now. Use {@link #loadLiquidStackFromNBT(NBTTagCompound)} to get a new instance
*
* @param nbt
*/
@Deprecated
public void readFromNBT(NBTTagCompound nbt)
{
}
/**
* @return A copy of this LiquidStack
*/

View file

@ -6,6 +6,7 @@ import net.minecraft.tileentity.TileEntity;
/**
* Reference implementation of ILiquidTank. Use this or implement your own.
*/
@Deprecated //See new net.minecraftforge.fluids
public class LiquidTank implements ILiquidTank {
private LiquidStack liquid;
private int capacity;

View file

@ -56,12 +56,16 @@ public class OreDictionary
registerOre("oreRedstone", Block.oreRedstone);
registerOre("oreEmerald", Block.oreEmerald);
registerOre("oreQuartz", Block.oreNetherQuartz);
registerOre("stone", Block.stone);
registerOre("cobblestone", Block.cobblestone);
}
// Build our list of items to replace with ore tags
Map<ItemStack, String> replacements = new HashMap<ItemStack, String>();
replacements.put(new ItemStack(Block.planks, 1, WILDCARD_VALUE), "plankWood");
replacements.put(new ItemStack(Item.stick), "stickWood");
replacements.put(new ItemStack(Block.stone), "stone");
replacements.put(new ItemStack(Block.cobblestone), "cobblestone");
// Register dyes
String[] dyes =
@ -102,6 +106,10 @@ public class OreDictionary
{
new ItemStack(Block.blockLapis),
new ItemStack(Item.cookie),
new ItemStack(Block.stoneBrick),
new ItemStack(Block.stoneSingleSlab),
new ItemStack(Block.stairsCobblestone),
new ItemStack(Block.cobblestoneWall)
};
List recipes = CraftingManager.getInstance().getRecipeList();

View file

@ -0,0 +1,113 @@
package net.minecraftforge.server;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.MapMaker;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
public class ForgeTimeTracker {
public static boolean tileEntityTracking;
public static int tileEntityTrackingDuration;
public static long tileEntityTrackingTime;
private Map<TileEntity,int[]> tileEntityTimings;
private Map<Entity,int[]> entityTimings;
private static final ForgeTimeTracker INSTANCE = new ForgeTimeTracker();
private WeakReference<TileEntity> tile;
private WeakReference<Entity> entity;
private long timing;
private ForgeTimeTracker()
{
MapMaker mm = new MapMaker();
mm.weakKeys();
tileEntityTimings = mm.makeMap();
entityTimings = mm.makeMap();
}
private void trackTileStart(TileEntity tileEntity, long nanoTime)
{
if (tileEntityTrackingTime == 0)
{
tileEntityTrackingTime = nanoTime;
}
else if (tileEntityTrackingTime + tileEntityTrackingDuration < nanoTime)
{
tileEntityTracking = false;
tileEntityTrackingTime = 0;
return;
}
tile = new WeakReference<TileEntity>(tileEntity);
timing = nanoTime;
}
private void trackTileEnd(TileEntity tileEntity, long nanoTime)
{
if (tile == null || tile.get() != tileEntity)
{
tile = null;
// race, exit
return;
}
int[] timings = tileEntityTimings.get(tileEntity);
if (timings == null)
{
timings = new int[101];
tileEntityTimings.put(tileEntity, timings);
}
int idx = timings[100] = (timings[100] + 1) % 100;
timings[idx] = (int) (nanoTime - timing);
}
public static ImmutableMap<TileEntity,int[]> getTileTimings()
{
return INSTANCE.buildImmutableTileEntityTimingMap();
}
private ImmutableMap<TileEntity, int[]> buildImmutableTileEntityTimingMap()
{
Builder<TileEntity, int[]> builder = ImmutableMap.<TileEntity,int[]>builder();
for (Entry<TileEntity, int[]> entry : tileEntityTimings.entrySet())
{
builder.put(entry.getKey(), Arrays.copyOfRange(entry.getValue(), 0, 100));
}
return builder.build();
}
public static void trackStart(TileEntity tileEntity)
{
if (!tileEntityTracking) return;
INSTANCE.trackTileStart(tileEntity, System.nanoTime());
}
public static void trackEnd(TileEntity tileEntity)
{
if (!tileEntityTracking) return;
INSTANCE.trackTileEnd(tileEntity, System.nanoTime());
}
public static void trackStart(Entity par1Entity)
{
}
public static void trackEnd(Entity par1Entity)
{
}
}

View file

@ -0,0 +1,147 @@
package net.minecraftforge.server.command;
import java.text.DecimalFormat;
import java.util.List;
import com.google.common.collect.Multiset;
import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.server.ForgeTimeTracker;
public class ForgeCommand extends CommandBase {
private MinecraftServer server;
public ForgeCommand(MinecraftServer server)
{
this.server = server;
}
private static final DecimalFormat timeFormatter = new DecimalFormat("########0.000");
@Override
public String getCommandName()
{
return "forge";
}
@Override
public String getCommandUsage(ICommandSender icommandsender)
{
return "commands.forge.usage";
}
@Override
public int getRequiredPermissionLevel()
{
return 2;
}
@Override
public void processCommand(ICommandSender sender, String[] args)
{
if (args.length == 0)
{
throw new WrongUsageException("commands.forge.usage");
}
else if ("help".equals(args[0]))
{
throw new WrongUsageException("commands.forge.usage");
}
else if ("tps".equals(args[0]))
{
displayTPS(sender,args);
}
else if ("tpslog".equals(args[0]))
{
doTPSLog(sender,args);
}
else if ("track".equals(args[0]))
{
handleTracking(sender, args);
}
else
{
throw new WrongUsageException("commands.forge.usage");
}
}
private void handleTracking(ICommandSender sender, String[] args)
{
if (args.length != 3)
{
throw new WrongUsageException("commands.forge.usage.tracking");
}
String type = args[1];
int duration = parseIntBounded(sender, args[2], 1, 60);
if ("te".equals(type))
{
doTurnOnTileEntityTracking(sender, duration);
}
else
{
throw new WrongUsageException("commands.forge.usage.tracking");
}
}
private void doTurnOnTileEntityTracking(ICommandSender sender, int duration)
{
ForgeTimeTracker.tileEntityTrackingDuration = duration;
ForgeTimeTracker.tileEntityTracking = true;
sender.sendChatToPlayer(ChatMessageComponent.func_111082_b("commands.forge.tracking.te.enabled", duration));
}
private void doTPSLog(ICommandSender sender, String[] args)
{
}
private void displayTPS(ICommandSender sender, String[] args)
{
int dim = 0;
boolean summary = true;
if (args.length > 1)
{
dim = parseInt(sender, args[1]);
summary = false;
}
if (summary)
{
for (Integer dimId : DimensionManager.getIDs())
{
double worldTickTime = ForgeCommand.mean(this.server.worldTickTimes.get(dimId)) * 1.0E-6D;
double worldTPS = Math.min(1000.0/worldTickTime, 20);
sender.sendChatToPlayer(ChatMessageComponent.func_111082_b("commands.forge.tps.summary",String.format("Dim %d", dimId), timeFormatter.format(worldTickTime), timeFormatter.format(worldTPS)));
}
double meanTickTime = ForgeCommand.mean(this.server.tickTimeArray) * 1.0E-6D;
double meanTPS = Math.min(1000.0/meanTickTime, 20);
sender.sendChatToPlayer(ChatMessageComponent.func_111082_b("commands.forge.tps.summary","Overall", timeFormatter.format(meanTickTime), timeFormatter.format(meanTPS)));
}
else
{
double worldTickTime = ForgeCommand.mean(this.server.worldTickTimes.get(dim)) * 1.0E-6D;
double worldTPS = Math.min(1000.0/worldTickTime, 20);
sender.sendChatToPlayer(ChatMessageComponent.func_111082_b("commands.forge.tps.summary",String.format("Dim %d", dim), timeFormatter.format(worldTickTime), timeFormatter.format(worldTPS)));
}
}
private static long mean(long[] values)
{
long sum = 0l;
for (long v : values)
{
sum+=v;
}
return sum / values.length;
}
}

View file

@ -2,6 +2,7 @@ package net.minecraftforge.transformers;
import java.util.List;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraftforge.event.Event;
import net.minecraftforge.event.ListenerList;
@ -11,8 +12,6 @@ import static org.objectweb.asm.Opcodes.*;
import static org.objectweb.asm.Type.*;
import static org.objectweb.asm.ClassWriter.*;
import cpw.mods.fml.relauncher.IClassTransformer;
public class EventTransformer implements IClassTransformer
{
public EventTransformer()

Binary file not shown.

2
fml

@ -1 +1 @@
Subproject commit 05a854cd2af53ca822ee8b249b0b3bbe44f94675
Subproject commit a13598b17ea9637c054d867a76298d6c080c5e32

View file

@ -4,30 +4,37 @@ import shutil, glob, fnmatch
import subprocess, logging
from optparse import OptionParser
forge_dir = os.path.dirname(os.path.abspath(__file__))
fml_dir = os.path.join(forge_dir, 'fml')
sys.path.append(fml_dir)
from forge import apply_forge_patches
from fml import setup_fml, finish_setup_fml, apply_fml_patches, setup_mcp, reset_logger
def main(mcp_dir):
src_dir = os.path.join(mcp_dir, 'src')
def fml_main(fml_dir, mcp_dir, gen_conf=True, disable_patches=False, disable_at=False, disable_merge=False, enable_server=False,
disable_client=False, disable_rename=False, disable_assets=False, decompile=False):
sys.path.append(fml_dir)
from fml import download_mcp, setup_mcp, decompile_minecraft, apply_fml_patches, finish_setup_fml
print '================ Forge ModLoader Setup Start ==================='
setup_mcp(fml_dir, mcp_dir, True)
setup_fml(fml_dir, mcp_dir)
apply_fml_patches(fml_dir, mcp_dir, os.path.join(mcp_dir, 'src'))
finish_setup_fml(fml_dir, mcp_dir)
download_mcp(fml_dir, mcp_dir)
setup_mcp(fml_dir, mcp_dir, gen_conf)
if decompile:
decompile_minecraft(fml_dir, mcp_dir, disable_at=disable_at, disable_merge=disable_merge,
enable_server=enable_server, disable_client=disable_client,
disable_assets=disable_assets)
if disable_patches:
print 'Patching disabled'
else:
apply_fml_patches(fml_dir, mcp_dir, os.path.join(mcp_dir, 'src'))
finish_setup_fml(fml_dir, mcp_dir, enable_server=enable_server, disable_client=disable_client, disable_rename=disable_rename)
else:
print 'Decompile free install is on the to-do!'
print '================ Forge ModLoader Setup End ==================='
sys.path.append(mcp_dir)
def forge_main(forge_dir, fml_dir, mcp_dir):
sys.path.append(mcp_dir)
sys.path.append(fml_dir)
from runtime.updatenames import updatenames
from runtime.updatemd5 import updatemd5
from forge import apply_forge_patches
from fml import reset_logger
print '=============================== Minecraft Forge Setup Start ====================================='
print 'Applying forge patches'
apply_forge_patches(os.path.join(forge_dir, 'fml'), mcp_dir, forge_dir, src_dir, True)
apply_forge_patches(fml_dir, mcp_dir, forge_dir, os.path.join(mcp_dir, 'src'), True)
os.chdir(mcp_dir)
updatenames(None, True, True, False)
reset_logger()
@ -35,15 +42,37 @@ def main(mcp_dir):
reset_logger()
os.chdir(forge_dir)
print '=============================== Minecraft Forge Setup Finished ================================='
if __name__ == '__main__':
parser = OptionParser()
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='Path to download/extract MCP to', default=None)
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='Path to download/extract MCP to', default=None )
parser.add_option('-p', '--no-patch', action="store_true", dest='no_patch', help='Disable application of FML patches', default=False)
parser.add_option('-a', '--no-access', action="store_true", dest='no_access', help='Disable access transformers', default=False)
parser.add_option('-s', '--server', action="store_true", dest='enable_server', help='Enable decompilation of server', default=False)
parser.add_option('-c', '--no-client', action="store_true", dest='no_client', help='Disable decompilation of server', default=False)
parser.add_option('-e', '--no-merge', action="store_true", dest='no_merge', help='Disable merging server code into client', default=False)
parser.add_option('-n', '--no-rename', action="store_true", dest='no_rename', help='Disable running updatenames', default=False)
parser.add_option( '--no-assets', action="store_true", dest='no_assets', help='Disable downloading of assets folder', default=False)
parser.add_option('-d', '--decompile', action="store_true", dest='decompile', help='Decompile minecraft and apply patches', default=True)
options, _ = parser.parse_args()
forge_dir = os.path.dirname(os.path.abspath(__file__))
fml_dir = os.path.abspath('fml')
mcp_dir = os.path.abspath('mcp')
if not options.mcp_dir is None:
main(os.path.abspath(options.mcp_dir))
elif os.path.isfile(os.path.join('..', 'runtime', 'commands.py')):
main(os.path.abspath('..'))
else:
main(os.path.abspath('mcp'))
mcp_dir = os.path.abspath(options.mcp_dir)
if options.no_client:
options.no_patch = True
if options.no_merge:
options.no_patch = True
fml_main(fml_dir, mcp_dir, disable_patches=options.no_patch,
disable_at=options.no_access, disable_merge=options.no_merge,
enable_server=options.enable_server, disable_client=options.no_client,
disable_rename=options.no_rename, disable_assets=options.no_assets,
decompile=options.decompile, gen_conf=False)
forge_main(forge_dir, fml_dir, mcp_dir)

View file

@ -1,6 +1,6 @@
--- ../src_base/minecraft/net/minecraft/block/Block.java
+++ ../src_work/minecraft/net/minecraft/block/Block.java
@@ -1,15 +1,20 @@
@@ -1,15 +1,22 @@
package net.minecraft.block;
-import cpw.mods.fml.relauncher.Side;
@ -18,12 +18,14 @@
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.EnumCreatureType;
+import net.minecraft.entity.boss.EntityDragon;
+import net.minecraft.entity.boss.EntityWither;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.player.EntityPlayer;
@@ -26,8 +31,10 @@
@@ -26,8 +33,10 @@
import net.minecraft.item.ItemSnow;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
@ -34,7 +36,7 @@
import net.minecraft.util.Icon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.StatCollector;
@@ -35,9 +42,19 @@
@@ -35,9 +44,19 @@
import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
@ -54,7 +56,7 @@
/**
* used as foreach item, if item.tab = current tab, display it on the screen
*/
@@ -454,9 +471,10 @@
@@ -460,9 +479,10 @@
return this.needsRandomTick;
}
@ -66,7 +68,7 @@
}
/**
@@ -479,7 +497,7 @@
@@ -485,7 +505,7 @@
*/
public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
@ -75,7 +77,7 @@
}
@SideOnly(Side.CLIENT)
@@ -489,7 +507,7 @@
@@ -495,7 +515,7 @@
*/
public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
@ -84,7 +86,7 @@
}
@SideOnly(Side.CLIENT)
@@ -639,7 +657,13 @@
@@ -646,7 +666,13 @@
/**
* ejects contained items into the world, and notifies neighbours of an update, as appropriate
*/
@ -99,7 +101,7 @@
/**
* Returns the quantity of items to drop on block destruction.
@@ -664,7 +688,7 @@
@@ -671,7 +697,7 @@
public float getPlayerRelativeBlockHardness(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5)
{
float f = this.getBlockHardness(par2World, par3, par4, par5);
@ -108,7 +110,7 @@
}
/**
@@ -682,18 +706,13 @@
@@ -689,18 +715,13 @@
{
if (!par1World.isRemote)
{
@ -131,7 +133,7 @@
}
}
}
@@ -926,7 +945,8 @@
@@ -933,7 +954,8 @@
public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
{
int l = par1World.getBlockId(par2, par3, par4);
@ -141,7 +143,7 @@
}
/**
@@ -1086,7 +1106,7 @@
@@ -1093,7 +1115,7 @@
par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1);
par2EntityPlayer.addExhaustion(0.025F);
@ -150,7 +152,7 @@
{
ItemStack itemstack = this.createStackedBlock(par6);
@@ -1102,12 +1122,13 @@
@@ -1109,12 +1131,13 @@
}
}
@ -165,7 +167,7 @@
}
/**
@@ -1443,4 +1464,950 @@
@@ -1454,4 +1477,979 @@
canBlockGrass[0] = true;
StatList.initBreakableStats();
}
@ -200,12 +202,7 @@
+ * @param entity The entity trying to use the ladder, CAN be null.
+ * @return True if the block should act like a ladder
+ */
+ public boolean isLadder(World world, int x, int y, int z, EntityLiving entity)
+ {
+ return isLadder(world, x, y, z);
+ }
+ @Deprecated //See EntityLiving sensitive version above
+ public boolean isLadder(World world, int x, int y, int z)
+ public boolean isLadder(World world, int x, int y, int z, EntityLivingBase entity)
+ {
+ return false;
+ }
@ -352,6 +349,7 @@
+ *
+ * @param itemList The list of items to display on the creative inventory.
+ */
+ @Deprecated
+ public void addCreativeItems(ArrayList itemList)
+ {
+ }
@ -575,7 +573,7 @@
+ * @param player The player or camera entity, null in some cases.
+ * @return True to treat this as a bed
+ */
+ public boolean isBed(World world, int x, int y, int z, EntityLiving player)
+ public boolean isBed(World world, int x, int y, int z, EntityLivingBase player)
+ {
+ return blockID == Block.bed.blockID;
+ }
@ -1011,8 +1009,7 @@
+ }
+
+ /**
+ * Determines if this block is destroyed when a ender dragon tries to fly through it.
+ * The block will be set to 0, nothing will drop.
+ * Determines if this block is can be destroyed by the specified entities normal behavior.
+ *
+ * @param world The current world
+ * @param x X Position
@ -1020,6 +1017,20 @@
+ * @param z Z position
+ * @return True to allow the ender dragon to destroy this block
+ */
+ public boolean canEntityDestroy(World world, int x, int y, int z, Entity entity)
+ {
+ if (entity instanceof EntityWither)
+ {
+ return blockID != Block.bedrock.blockID && blockID != Block.endPortal.blockID && blockID != Block.endPortalFrame.blockID;
+ }
+ else if (entity instanceof EntityDragon)
+ {
+ return canDragonDestroy(world, x, y, z);
+ }
+
+ return true;
+ }
+ @Deprecated
+ public boolean canDragonDestroy(World world, int x, int y, int z)
+ {
+ return blockID != obsidian.blockID && blockID != whiteStone.blockID && blockID != bedrock.blockID;
@ -1084,12 +1095,6 @@
+ */
+ public float getEnchantPowerBonus(World world, int x, int y, int z)
+ {
+ return getEnchantPower(world, x, y, z);
+ }
+
+ @Deprecated //Changed return to float, see above.
+ public int getEnchantPower(World world, int x, int y, int z)
+ {
+ return blockID == bookShelf.blockID ? 1 : 0;
+ }
+ /**
@ -1115,4 +1120,30 @@
+ }
+ return false;
+ }
+
+ /**
+ * Called when a tile entity on a side of this block changes is created or is destroyed.
+ * @param world The world
+ * @param x The x position of this block instance
+ * @param y The y position of this block instance
+ * @param z The z position of this block instance
+ * @param tileX The x position of the tile that changed
+ * @param tileY The y position of the tile that changed
+ * @param tileZ The z position of the tile that changed
+ */
+ public void onNeighborTileChange(World world, int x, int y, int z, int tileX, int tileY, int tileZ)
+ {
+ }
+
+ /**
+ * @return true if this block is to be notified of TileEntity changes directly through one solid block like comparators
+ */
+ public boolean weakTileChanges()
+ {
+ return false;
+ }
+
+ @Deprecated //Implemented here as we changed the IFluidBlock interface, and this allows us to do so without breaking exisitng mods.
+ // To be removed next MC version {1.6.3+}
+ public float getFilledPercentage(World world, int x, int y, int z){ return 1; }
}

View file

@ -8,12 +8,12 @@
+
final BlockRailBase theRail;
public BlockBaseRailLogic(BlockRailBase par1, World par2, int par3, int par4, int par5)
public BlockBaseRailLogic(BlockRailBase par1BlockRailBase, World par2World, int par3, int par4, int par5)
@@ -27,17 +29,11 @@
this.railY = par4;
this.railZ = par5;
int l = par2.getBlockId(par3, par4, par5);
- int i1 = par2.getBlockMetadata(par3, par4, par5);
int l = par2World.getBlockId(par3, par4, par5);
- int i1 = par2World.getBlockMetadata(par3, par4, par5);
-
- if (((BlockRailBase)Block.blocksList[l]).isPowered)
- {
@ -26,9 +26,9 @@
- }
+
+ BlockRailBase target = (BlockRailBase)Block.blocksList[l];
+ int i1 = target.getBasicRailMetadata(par2, null, par3, par4, par5);
+ isStraightRail = !target.isFlexibleRail(par2, par3, par4, par5);
+ canMakeSlopes = target.canMakeSlopes(par2, par3, par4, par5);
+ int i1 = target.getBasicRailMetadata(par2World, null, par3, par4, par5);
+ isStraightRail = !target.isFlexibleRail(par2World, par3, par4, par5);
+ canMakeSlopes = target.canMakeSlopes(par2World, par3, par4, par5);
this.setBasicRail(i1);
}

View file

@ -23,8 +23,8 @@
}
@@ -182,4 +186,22 @@
this.cactusTopIcon = par1IconRegister.registerIcon("cactus_top");
this.cactusBottomIcon = par1IconRegister.registerIcon("cactus_bottom");
this.cactusTopIcon = par1IconRegister.registerIcon(this.func_111023_E() + "_top");
this.cactusBottomIcon = par1IconRegister.registerIcon(this.func_111023_E() + "_bottom");
}
+
+ @Override

View file

@ -9,7 +9,7 @@
import java.util.Random;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
@@ -202,7 +204,14 @@
@@ -201,7 +203,14 @@
*/
public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7)
{
@ -25,7 +25,7 @@
byte b0 = 1;
if (j1 >= 2)
@@ -212,8 +221,9 @@
@@ -211,8 +220,9 @@
for (int k1 = 0; k1 < b0; ++k1)
{
@ -37,8 +37,8 @@
}
@SideOnly(Side.CLIENT)
@@ -249,4 +259,10 @@
this.iconArray[i] = par1IconRegister.registerIcon(cocoaIcons[i]);
@@ -248,4 +258,10 @@
this.iconArray[i] = par1IconRegister.registerIcon(this.func_111023_E() + "_stage_" + i);
}
}
+

View file

@ -0,0 +1,20 @@
--- ../src_base/minecraft/net/minecraft/block/BlockComparator.java
+++ ../src_work/minecraft/net/minecraft/block/BlockComparator.java
@@ -266,4 +266,17 @@
{
return new TileEntityComparator();
}
+
+ @Override
+ public void onNeighborTileChange(World world, int x, int y, int z, int tileX, int tileY, int tileZ)
+ {
+ if(y == tileY)
+ onNeighborBlockChange(world, x, y, z, world.getBlockId(tileX, tileY, tileZ));
+ }
+
+ @Override
+ public boolean weakTileChanges()
+ {
+ return true;
+ }
}

View file

@ -1,6 +1,6 @@
--- ../src_base/minecraft/net/minecraft/block/BlockDoor.java
+++ ../src_work/minecraft/net/minecraft/block/BlockDoor.java
@@ -303,7 +303,7 @@
@@ -290,7 +290,7 @@
{
if (this.blockMaterial == Material.iron)
{

View file

@ -19,7 +19,7 @@
this.setBurnRate(Block.planks.blockID, 5, 20);
this.setBurnRate(Block.woodDoubleSlab.blockID, 5, 20);
this.setBurnRate(Block.woodSingleSlab.blockID, 5, 20);
@@ -60,8 +65,7 @@
@@ -62,8 +67,7 @@
*/
private void setBurnRate(int par1, int par2, int par3)
{
@ -29,7 +29,7 @@
}
/**
@@ -121,12 +125,8 @@
@@ -123,12 +127,8 @@
{
if (par1World.getGameRules().getGameRuleBooleanValue("doFireTick"))
{
@ -44,7 +44,7 @@
if (!this.canPlaceBlockAt(par1World, par2, par3, par4))
{
@@ -155,7 +155,7 @@
@@ -157,7 +157,7 @@
par1World.setBlockToAir(par2, par3, par4);
}
}
@ -53,7 +53,7 @@
{
par1World.setBlockToAir(par2, par3, par4);
}
@@ -169,12 +169,12 @@
@@ -171,12 +171,12 @@
b0 = -50;
}
@ -72,7 +72,7 @@
for (int i1 = par2 - 1; i1 <= par2 + 1; ++i1)
{
@@ -228,9 +228,20 @@
@@ -230,9 +230,20 @@
return false;
}
@ -94,7 +94,7 @@
if (par6Random.nextInt(par5) < j1)
{
@@ -264,7 +275,12 @@
@@ -266,7 +277,12 @@
*/
private boolean canNeighborBurn(World par1World, int par2, int par3, int par4)
{
@ -108,7 +108,7 @@
}
/**
@@ -280,12 +296,12 @@
@@ -282,12 +298,12 @@
}
else
{
@ -127,7 +127,7 @@
return l;
}
}
@@ -300,21 +316,24 @@
@@ -302,21 +318,24 @@
/**
* Checks the specified block coordinate to see if it can catch fire. Args: blockAccess, x, y, z
@ -157,7 +157,7 @@
}
/**
@@ -372,9 +391,9 @@
@@ -374,9 +393,9 @@
float f1;
float f2;
@ -170,7 +170,7 @@
{
for (l = 0; l < 2; ++l)
{
@@ -385,7 +404,7 @@
@@ -387,7 +406,7 @@
}
}
@ -179,7 +179,7 @@
{
for (l = 0; l < 2; ++l)
{
@@ -396,7 +415,7 @@
@@ -398,7 +417,7 @@
}
}
@ -188,7 +188,7 @@
{
for (l = 0; l < 2; ++l)
{
@@ -407,7 +426,7 @@
@@ -409,7 +428,7 @@
}
}
@ -197,7 +197,7 @@
{
for (l = 0; l < 2; ++l)
{
@@ -418,7 +437,7 @@
@@ -420,7 +439,7 @@
}
}
@ -206,7 +206,7 @@
{
for (l = 0; l < 2; ++l)
{
@@ -467,4 +486,46 @@
@@ -469,4 +488,46 @@
{
return this.iconArray[0];
}

View file

@ -9,3 +9,17 @@
l += (i2 & 16711680) >> 16;
i1 += (i2 & 65280) >> 8;
j1 += i2 & 255;
@@ -81,6 +81,13 @@
}
return (float)(par0 + 1) / 9.0F;
+ }
+
+
+ @Deprecated //Implemented here for compatibility, need to change this when we make vanilla fluids use our fluid methods.
+ public float getFilledPercentage(IBlockAccess world, int x, int y, int z)
+ {
+ return 1 - BlockFluid.getFluidHeightPercent(world.getBlockMetadata(x, y, z));
}
@SideOnly(Side.CLIENT)

View file

@ -4,7 +4,7 @@
import java.util.Random;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.entity.EntityLiving;
+import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
@ -86,7 +86,7 @@
}
+
+ @Override
+ public boolean isLadder(World world, int x, int y, int z, EntityLiving entity)
+ public boolean isLadder(World world, int x, int y, int z, EntityLivingBase entity)
+ {
+ return true;
+ }

View file

@ -19,7 +19,7 @@
+public class BlockLeaves extends BlockLeavesBase implements IShearable
{
public static final String[] LEAF_TYPES = new String[] {"oak", "spruce", "birch", "jungle"};
public static final String[][] field_94396_b = new String[][] {{"leaves", "leaves_spruce", "leaves", "leaves_jungle"}, {"leaves_opaque", "leaves_spruce_opaque", "leaves_opaque", "leaves_jungle_opaque"}};
public static final String[][] field_94396_b = new String[][] {{"leaves_oak", "leaves_spruce", "leaves_birch", "leaves_jungle"}, {"leaves_oak_opaque", "leaves_spruce_opaque", "leaves_birch_opaque", "leaves_jungle_opaque"}};
@@ -107,10 +111,9 @@
{
int j2 = par1World.getBlockId(par2 + k1, par3 + l1, par4 + i2);

View file

@ -1,6 +1,6 @@
--- ../src_base/minecraft/net/minecraft/block/BlockLog.java
+++ ../src_work/minecraft/net/minecraft/block/BlockLog.java
@@ -69,14 +69,9 @@
@@ -60,14 +60,9 @@
{
int j2 = par1World.getBlockId(par2 + k1, par3 + l1, par4 + i2);
@ -17,8 +17,8 @@
}
}
}
@@ -176,4 +171,16 @@
this.iconArray[i] = par1IconRegister.registerIcon(treeTextureTypes[i]);
@@ -125,4 +120,16 @@
this.tree_top[i] = par1IconRegister.registerIcon(this.func_111023_E() + "_" + woodType[i] + "_top");
}
}
+

View file

@ -1,7 +1,7 @@
--- ../src_base/minecraft/net/minecraft/block/BlockMushroom.java
+++ ../src_work/minecraft/net/minecraft/block/BlockMushroom.java
@@ -6,6 +6,8 @@
import net.minecraft.client.renderer.texture.IconRegister;
@@ -3,6 +3,8 @@
import java.util.Random;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenBigMushroom;
+
@ -9,7 +9,7 @@
public class BlockMushroom extends BlockFlower
{
@@ -102,7 +104,9 @@
@@ -96,7 +98,9 @@
if (par3 >= 0 && par3 < 256)
{
int l = par1World.getBlockId(par2, par3 - 1, par4);

View file

@ -17,7 +17,7 @@
public class BlockNetherStalk extends BlockFlower
{
@@ -39,7 +42,8 @@
@@ -38,7 +41,8 @@
*/
public boolean canBlockStay(World par1World, int par2, int par3, int par4)
{
@ -27,7 +27,7 @@
}
/**
@@ -81,25 +85,7 @@
@@ -80,25 +84,7 @@
*/
public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7)
{
@ -54,8 +54,8 @@
}
/**
@@ -143,4 +129,23 @@
this.iconArray[i] = par1IconRegister.registerIcon(field_94373_a[i]);
@@ -142,4 +128,23 @@
this.iconArray[i] = par1IconRegister.registerIcon(this.func_111023_E() + "_stage_" + i);
}
}
+

View file

@ -1,6 +1,6 @@
--- ../src_base/minecraft/net/minecraft/block/BlockPistonBase.java
+++ ../src_work/minecraft/net/minecraft/block/BlockPistonBase.java
@@ -437,7 +437,7 @@
@@ -439,7 +439,7 @@
return false;
}
@ -9,7 +9,7 @@
}
}
@@ -455,14 +455,14 @@
@@ -457,14 +457,14 @@
{
if (l1 < 13)
{
@ -26,7 +26,7 @@
{
if (!canPushBlock(i2, par0World, i1, j1, k1, true))
{
@@ -505,14 +505,14 @@
@@ -507,14 +507,14 @@
if (l1 < 13)
{
@ -43,7 +43,7 @@
{
if (!canPushBlock(i2, par1World, i1, j1, k1, true))
{
@@ -533,7 +533,9 @@
@@ -535,7 +535,9 @@
continue;
}

View file

@ -9,7 +9,7 @@
public class BlockSapling extends BlockFlower
{
public static final String[] WOOD_TYPES = new String[] {"oak", "spruce", "birch", "jungle"};
@@ -77,6 +79,8 @@
@@ -76,6 +78,8 @@
*/
public void growTree(World par1World, int par2, int par3, int par4, Random par5Random)
{

View file

@ -9,7 +9,7 @@
import java.util.Random;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.entity.EntityLiving;
+import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@ -24,7 +24,7 @@
{
public BlockVine(int par1)
{
@@ -439,14 +444,26 @@
@@ -440,14 +445,26 @@
*/
public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6)
{
@ -55,7 +55,7 @@
+ }
+
+ @Override
+ public boolean isLadder(World world, int x, int y, int z, EntityLiving entity)
+ public boolean isLadder(World world, int x, int y, int z, EntityLivingBase entity)
+ {
+ return true;
}

View file

@ -1,6 +1,6 @@
--- ../src_base/minecraft/net/minecraft/client/Minecraft.java
+++ ../src_work/minecraft/net/minecraft/client/Minecraft.java
@@ -123,6 +123,14 @@
@@ -137,6 +137,14 @@
import com.google.common.collect.MapDifference;
@ -13,9 +13,9 @@
+import net.minecraftforge.event.world.WorldEvent;
+
@SideOnly(Side.CLIENT)
public abstract class Minecraft implements Runnable, IPlayerUsage
public class Minecraft implements IPlayerUsage
{
@@ -372,7 +380,7 @@
@@ -416,7 +424,7 @@
try
{
@ -24,25 +24,25 @@
}
catch (LWJGLException lwjglexception)
{
@@ -450,7 +458,7 @@
}
@@ -497,7 +505,7 @@
this.effectRenderer = new EffectRenderer(this.theWorld, this.renderEngine);
FMLClientHandler.instance().finishMinecraftLoading();
this.checkGLError("Post startup");
- this.ingameGUI = new GuiIngame(this);
+ this.ingameGUI = new GuiIngameForge(this);
if (this.serverName != null)
{
@@ -1238,7 +1246,7 @@
@@ -1300,7 +1308,7 @@
if (this.thePlayer.canCurrentToolHarvestBlock(j, k, l))
if (this.thePlayer.isCurrentToolAdventureModeExempt(j, k, l))
{
- this.effectRenderer.addBlockHitEffects(j, k, l, this.objectMouseOver.sideHit);
+ this.effectRenderer.addBlockHitEffects(j, k, l, this.objectMouseOver);
this.thePlayer.swingItem();
}
}
@@ -1304,7 +1312,8 @@
@@ -1366,7 +1374,8 @@
{
int j1 = itemstack != null ? itemstack.stackSize : 0;
@ -52,7 +52,7 @@
{
flag = false;
this.thePlayer.swingItem();
@@ -1330,7 +1339,8 @@
@@ -1392,7 +1401,8 @@
{
ItemStack itemstack1 = this.thePlayer.inventory.getCurrentItem();
@ -62,7 +62,7 @@
{
this.entityRenderer.itemRenderer.resetEquippedProgress2();
}
@@ -2010,6 +2020,11 @@
@@ -2046,6 +2056,11 @@
{
this.statFileWriter.syncStats();
@ -74,7 +74,7 @@
if (par1WorldClient == null)
{
NetClientHandler netclienthandler = this.getNetHandler();
@@ -2027,6 +2042,18 @@
@@ -2063,6 +2078,18 @@
if (this.theIntegratedServer != null)
{
this.theIntegratedServer.initiateShutdown();
@ -93,7 +93,7 @@
}
this.theIntegratedServer = null;
@@ -2354,103 +2381,12 @@
@@ -2236,107 +2263,12 @@
if (this.objectMouseOver != null)
{
boolean flag = this.thePlayer.capabilities.isCreativeMode;
@ -136,6 +136,10 @@
- {
- j = Item.painting.itemID;
- }
- else if (this.objectMouseOver.entityHit instanceof EntityLeashKnot)
- {
- j = Item.field_111214_ch.itemID;
- }
- else if (this.objectMouseOver.entityHit instanceof EntityItemFrame)
- {
- EntityItemFrame entityitemframe = (EntityItemFrame)this.objectMouseOver.entityHit;
@ -201,7 +205,7 @@
if (flag)
{
@@ -2539,11 +2475,18 @@
@@ -2419,11 +2351,18 @@
par1PlayerUsageSnooper.addData("gl_max_texture_size", Integer.valueOf(getGLMaximumTextureSize()));
}
@ -220,7 +224,7 @@
for (int i = 16384; i > 0; i >>= 1)
{
GL11.glTexImage2D(GL11.GL_PROXY_TEXTURE_2D, 0, GL11.GL_RGBA, i, i, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer)null);
@@ -2551,6 +2494,7 @@
@@ -2431,6 +2370,7 @@
if (j != 0)
{

View file

@ -10,52 +10,49 @@
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.io.File;
@@ -53,9 +57,11 @@
@@ -61,9 +65,11 @@
private Random rand = new Random();
private int ticksBeforeMusic;
+ public static int MUSIC_INTERVAL = 12000;
+
public SoundManager()
public SoundManager(ResourceManager par1ResourceManager, GameSettings par2GameSettings, File par3File)
{
- this.ticksBeforeMusic = this.rand.nextInt(12000);
+ this.ticksBeforeMusic = this.rand.nextInt(MUSIC_INTERVAL);
}
/**
@@ -70,6 +76,8 @@
{
this.tryToSetLibraryAndCodecs();
this.options = par2GameSettings;
this.field_130085_i = par3File;
this.soundPoolSounds = new SoundPool(par1ResourceManager, "sound", true);
@@ -75,6 +81,7 @@
SoundSystemConfig.addLibrary(LibraryLWJGLOpenAL.class);
SoundSystemConfig.setCodec("ogg", CodecJOrbis.class);
SoundSystemConfig.setCodec("wav", CodecWav.class);
+ MinecraftForge.EVENT_BUS.post(new SoundSetupEvent(this));
}
+ ModCompatibilityClient.audioModLoad(this);
catch (SoundSystemException soundsystemexception)
{
@@ -90,6 +97,7 @@
this.stopAllSounds();
this.closeMinecraft();
this.tryToSetLibraryAndCodecs();
+ MinecraftForge.EVENT_BUS.post(new SoundLoadEvent(this));
}
/**
@@ -89,6 +97,8 @@
SoundSystemConfig.setCodec("ogg", CodecJOrbis.class);
SoundSystemConfig.setCodec("mus", CodecMus.class);
SoundSystemConfig.setCodec("wav", CodecWav.class);
+ ModCompatibilityClient.audioModAddCodecs();
+ MinecraftForge.EVENT_BUS.post(new SoundSetupEvent(this));
sndSystem = new SoundSystem();
this.options.soundVolume = f;
this.options.musicVolume = f1;
@@ -179,10 +189,12 @@
}
SoundPoolEntry soundpoolentry = this.soundPoolMusic.getRandomSound();
+ soundpoolentry = ModCompatibilityClient.audioModPickBackgroundMusic(this, soundpoolentry);
+ soundpoolentry = SoundEvent.getResult(new PlayBackgroundMusicEvent(this, soundpoolentry));
if (soundpoolentry != null)
private void func_130083_h()
@@ -236,10 +244,11 @@
else
{
- this.ticksBeforeMusic = this.rand.nextInt(12000) + 12000;
+ this.ticksBeforeMusic = this.rand.nextInt(MUSIC_INTERVAL) + MUSIC_INTERVAL;
sndSystem.backgroundMusic("BgMusic", soundpoolentry.soundUrl, soundpoolentry.soundName, false);
sndSystem.setVolume("BgMusic", this.options.musicVolume);
sndSystem.play("BgMusic");
@@ -249,6 +261,7 @@
SoundPoolEntry soundpoolentry = this.soundPoolMusic.getRandomSound();
+ soundpoolentry = SoundEvent.getResult(new PlayBackgroundMusicEvent(this, soundpoolentry));
if (soundpoolentry != null)
{
- this.ticksBeforeMusic = this.rand.nextInt(12000) + 12000;
+ this.ticksBeforeMusic = this.rand.nextInt(MUSIC_INTERVAL) + MUSIC_INTERVAL;
this.sndSystem.backgroundMusic("BgMusic", soundpoolentry.func_110457_b(), soundpoolentry.func_110458_a(), false);
this.sndSystem.setVolume("BgMusic", this.options.musicVolume);
this.sndSystem.play("BgMusic");
@@ -307,6 +316,7 @@
if (par1Str != null)
{
SoundPoolEntry soundpoolentry = this.soundPoolStreaming.getRandomSoundFromSoundPool(par1Str);
@ -63,43 +60,43 @@
if (soundpoolentry != null)
{
@@ -260,6 +273,7 @@
float f3 = 16.0F;
sndSystem.newStreamingSource(true, s1, soundpoolentry.soundUrl, soundpoolentry.soundName, false, par2, par3, par4, 2, f3 * 4.0F);
sndSystem.setVolume(s1, 0.5F * this.options.soundVolume);
@@ -317,6 +327,7 @@
this.sndSystem.newStreamingSource(true, s1, soundpoolentry.func_110457_b(), soundpoolentry.func_110458_a(), false, par2, par3, par4, 2, 64.0F);
this.sndSystem.setVolume(s1, 0.5F * this.options.soundVolume);
+ MinecraftForge.EVENT_BUS.post(new PlayStreamingSourceEvent(this, s1, par2, par3, par4));
sndSystem.play(s1);
this.sndSystem.play(s1);
}
}
@@ -439,6 +453,7 @@
if (loaded && this.options.soundVolume != 0.0F)
@@ -485,6 +496,7 @@
if (this.loaded && this.options.soundVolume != 0.0F)
{
SoundPoolEntry soundpoolentry = this.soundPoolSounds.getRandomSoundFromSoundPool(par1Str);
+ soundpoolentry = SoundEvent.getResult(new PlaySoundEvent(this, soundpoolentry, par1Str, par2, par3, par4, par5, par6));
if (soundpoolentry != null && par5 > 0.0F)
{
@@ -460,6 +475,7 @@
}
@@ -506,6 +518,7 @@
sndSystem.setVolume(s1, par5 * this.options.soundVolume);
this.sndSystem.setPitch(s1, par6);
this.sndSystem.setVolume(s1, par5 * this.options.soundVolume);
+ MinecraftForge.EVENT_BUS.post(new PlaySoundSourceEvent(this, s1, par2, par3, par4));
sndSystem.play(s1);
this.sndSystem.play(s1);
}
}
@@ -474,6 +490,7 @@
if (loaded && this.options.soundVolume != 0.0F)
@@ -520,6 +533,7 @@
if (this.loaded && this.options.soundVolume != 0.0F)
{
SoundPoolEntry soundpoolentry = this.soundPoolSounds.getRandomSoundFromSoundPool(par1Str);
+ soundpoolentry = SoundEvent.getResult(new PlaySoundEffectEvent(this, soundpoolentry, par1Str, par2, par3));
if (soundpoolentry != null)
if (soundpoolentry != null && par2 > 0.0F)
{
@@ -489,6 +506,7 @@
@@ -535,6 +549,7 @@
par2 *= 0.25F;
sndSystem.setPitch(s1, par3);
sndSystem.setVolume(s1, par2 * this.options.soundVolume);
this.sndSystem.setPitch(s1, par3);
this.sndSystem.setVolume(s1, par2 * this.options.soundVolume);
+ MinecraftForge.EVENT_BUS.post(new PlaySoundEffectSourceEvent(this, s1));
sndSystem.play(s1);
this.sndSystem.play(s1);
}
}

View file

@ -1,53 +0,0 @@
--- ../src_base/minecraft/net/minecraft/client/audio/SoundPool.java
+++ ../src_work/minecraft/net/minecraft/client/audio/SoundPool.java
@@ -4,6 +4,7 @@
import cpw.mods.fml.relauncher.SideOnly;
import java.io.File;
import java.net.MalformedURLException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -36,6 +37,26 @@
*/
public SoundPoolEntry addSound(String par1Str, File par2File)
{
+ try
+ {
+ return addSound(par1Str, par2File.toURI().toURL());
+ }
+ catch (MalformedURLException ex)
+ {
+ ex.printStackTrace();
+ throw new RuntimeException(ex);
+ }
+ }
+
+ /**
+ * URL version of addSound, as the back-end sound engine has full support for various types of URLs
+ *
+ * @param par1Str The name of the sound to add
+ * @param url The url of the sound resource
+ * @return A SoundPoolEntry for the newly added sound
+ */
+ public SoundPoolEntry addSound(String par1Str, URL url)
+ {
try
{
String s1 = par1Str;
@@ -56,13 +77,13 @@
this.nameToSoundPoolEntriesMapping.put(par1Str, new ArrayList());
}
- SoundPoolEntry soundpoolentry = new SoundPoolEntry(s1, par2File.toURI().toURL());
+ SoundPoolEntry soundpoolentry = new SoundPoolEntry(s1, url);
((List)this.nameToSoundPoolEntriesMapping.get(par1Str)).add(soundpoolentry);
this.allSoundPoolEntries.add(soundpoolentry);
++this.numberOfSoundPoolEntries;
return soundpoolentry;
}
- catch (MalformedURLException malformedurlexception)
+ catch (Exception malformedurlexception)
{
malformedurlexception.printStackTrace();
throw new RuntimeException(malformedurlexception);

View file

@ -1,15 +1,15 @@
--- ../src_base/minecraft/net/minecraft/client/entity/EntityPlayerSP.java
+++ ../src_work/minecraft/net/minecraft/client/entity/EntityPlayerSP.java
@@ -46,6 +46,8 @@
@@ -49,6 +49,8 @@
import net.minecraft.util.MovementInput;
import net.minecraft.util.Session;
import net.minecraft.util.StringUtils;
import net.minecraft.world.World;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.event.entity.PlaySoundAtEntityEvent;
@SideOnly(Side.CLIENT)
public class EntityPlayerSP extends EntityPlayer
@@ -661,6 +663,12 @@
public class EntityPlayerSP extends AbstractClientPlayer
@@ -685,6 +687,12 @@
public void playSound(String par1Str, float par2, float par3)
{
@ -21,4 +21,4 @@
+ par1Str = event.name;
this.worldObj.playSound(this.posX, this.posY - (double)this.yOffset, this.posZ, par1Str, par2, par3, false);
}
}

View file

@ -1,9 +1,9 @@
--- ../src_base/minecraft/net/minecraft/client/gui/GuiControls.java
+++ ../src_work/minecraft/net/minecraft/client/gui/GuiControls.java
@@ -6,6 +6,8 @@
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.StringTranslate;
+
+import net.minecraftforge.client.GuiControlsScrollPanel;
@ -18,12 +18,10 @@
public GuiControls(GuiScreen par1GuiScreen, GameSettings par2GameSettings)
{
@@ -43,15 +47,10 @@
@@ -43,14 +47,9 @@
*/
public void initGui()
{
+ scrollPane = new GuiControlsScrollPanel(this, options, mc);
StringTranslate stringtranslate = StringTranslate.getInstance();
- int i = this.getLeftBorder();
-
- for (int j = 0; j < this.options.keyBindings.length; ++j)
@ -31,13 +29,14 @@
- this.buttonList.add(new GuiSmallButton(j, i + j % 2 * 160, this.height / 6 + 24 * (j >> 1), 70, 20, this.options.getOptionDisplayString(j)));
- }
-
- this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height / 6 + 168, stringtranslate.translateKey("gui.done")));
+ this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height - 28, stringtranslate.translateKey("gui.done")));
+ scrollPane.registerScrollButtons(buttonList, 7, 8);
this.screenTitle = stringtranslate.translateKey("controls.title");
- this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height / 6 + 168, I18n.func_135053_a("gui.done")));
+ scrollPane = new GuiControlsScrollPanel(this, options, mc);
+ this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height - 28, I18n.func_135053_a("gui.done")));
+ scrollPane.registerScrollButtons(7, 8);
this.screenTitle = I18n.func_135053_a("controls.title");
}
@@ -59,20 +58,10 @@
@@ -58,20 +57,10 @@
* Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e).
*/
protected void actionPerformed(GuiButton par1GuiButton)
@ -59,7 +58,7 @@
}
}
@@ -81,17 +70,7 @@
@@ -80,17 +69,7 @@
*/
protected void mouseClicked(int par1, int par2, int par3)
{
@ -78,7 +77,7 @@
}
/**
@@ -99,14 +78,7 @@
@@ -98,14 +77,7 @@
*/
protected void keyTyped(char par1, int par2)
{
@ -94,7 +93,7 @@
{
super.keyTyped(par1, par2);
}
@@ -118,6 +90,7 @@
@@ -117,6 +89,7 @@
public void drawScreen(int par1, int par2, float par3)
{
this.drawDefaultBackground();
@ -102,7 +101,7 @@
this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 20, 16777215);
int k = this.getLeftBorder();
int l = 0;
@@ -158,6 +131,10 @@
@@ -157,6 +130,10 @@
break;
}
}

View file

@ -1,6 +1,6 @@
--- ../src_base/minecraft/net/minecraft/client/gui/GuiCreateWorld.java
+++ ../src_work/minecraft/net/minecraft/client/gui/GuiCreateWorld.java
@@ -377,7 +377,7 @@
@@ -376,7 +376,7 @@
}
else if (par1GuiButton.id == 8)
{
@ -9,13 +9,12 @@
}
}
}
@@ -395,7 +395,8 @@
@@ -394,7 +394,7 @@
this.buttonBonusItems.drawButton = this.moreOptions;
this.buttonWorldType.drawButton = this.moreOptions;
this.buttonAllowCommands.drawButton = this.moreOptions;
- this.buttonCustomize.drawButton = this.moreOptions && WorldType.worldTypes[this.worldTypeId] == WorldType.FLAT;
+ this.buttonCustomize.drawButton = this.moreOptions && (WorldType.worldTypes[this.worldTypeId].isCustomizable());
+
StringTranslate stringtranslate;
if (this.moreOptions)
{

View file

@ -1,6 +1,6 @@
--- ../src_base/minecraft/net/minecraft/client/gui/GuiIngame.java
+++ ../src_work/minecraft/net/minecraft/client/gui/GuiIngame.java
@@ -34,6 +34,8 @@
@@ -40,6 +40,8 @@
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
@ -9,7 +9,7 @@
@SideOnly(Side.CLIENT)
public class GuiIngame extends Gui
{
@@ -90,9 +92,16 @@
@@ -99,9 +101,16 @@
ItemStack itemstack = this.mc.thePlayer.inventory.armorItemInSlot(3);
@ -29,30 +29,29 @@
}
if (!this.mc.thePlayer.isPotionActive(Potion.confusion))
@@ -174,7 +183,7 @@
k3 = l - 39;
l2 = k3 - 10;
- k2 = this.mc.thePlayer.getTotalArmorValue();
+ k2 = ForgeHooks.getTotalArmorValue(mc.thePlayer);
i3 = -1;
if (this.mc.thePlayer.isPotionActive(Potion.regeneration))
@@ -435,7 +444,16 @@
GL11.glPushMatrix();
@@ -275,6 +284,16 @@
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fontrenderer.drawStringWithShadow(s1, i1, j1, 16777215 + (j5 << 24));
fontrenderer.drawStringWithShadow(s1, k1, i2, 16777215 + (j2 << 24));
+ FontRenderer font = highlightingItemStack.getItem().getFontRenderer(highlightingItemStack);
+ if (font != null)
+ {
+ i1 = (k - font.getStringWidth(s1)) / 2;
+ font.drawStringWithShadow(s1, i1, j1, 16777215 + (j5 << 24));
+ k1 = (k - font.getStringWidth(s1)) / 2;
+ font.drawStringWithShadow(s1, k1, i2, 16777215 + (j2 << 24));
+ }
+ else
+ {
+ fontrenderer.drawStringWithShadow(s1, i1, j1, 16777215 + (j5 << 24));
+ fontrenderer.drawStringWithShadow(s1, k1, i2, 16777215 + (j2 << 24));
+ }
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
@@ -563,7 +582,7 @@
int k2 = Math.max(10 - (j2 - 2), 3);
int l2 = i2 - (j2 - 1) * k2 - 10;
float f2 = f1;
- int i3 = this.mc.thePlayer.getTotalArmorValue();
+ int i3 = ForgeHooks.getTotalArmorValue(mc.thePlayer);
int j3 = -1;
if (this.mc.thePlayer.isPotionActive(Potion.regeneration))

Some files were not shown because too many files have changed in this diff Show more