Update to 1.2.4, no modloadermp anymore

This commit is contained in:
Christian Weeks 2012-03-29 00:31:46 -04:00
parent 785aef9551
commit e4d36feb31
17 changed files with 921 additions and 867 deletions

View File

@ -2,8 +2,7 @@
<classpath> <classpath>
<classpathentry kind="src" path="client"/> <classpathentry kind="src" path="client"/>
<classpathentry kind="src" path="common"/> <classpathentry kind="src" path="common"/>
<classpathentry kind="src" path="server"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry combineaccessrules="false" kind="src" path="/forge-client"/> <classpathentry combineaccessrules="false" kind="src" path="/forge-client"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

View File

@ -7,14 +7,20 @@
cpw cpw
====================================================================== --> ====================================================================== -->
<project name="mod_IronChests" default="build"> <project name="mod_IronChests" default="buildandclean">
<description> <description>
Iron Chests Iron Chests
</description> </description>
<property name="modname" value="mod_ironchests" /> <property name="modname" value="mod_ironchests" />
<property name="version" value="3.1" /> <property name="version.file" value="cpw/mods/ironchest/Version.java"/>
<property name="mcp.home" location="/home/cpw/projects/mcworkspace/forge59" /> <property name="version.major" value="3"/>
<property name="version.minor" value="2"/>
<property name="version.rev" value="0"/>
<property name="version.build" value="0"/>
<property name="version" value="${version.major}.${version.minor}.${version.rev}.${version.build}" />
<property name="mcdev.home" location="/home/cpw/projects/mcworkspace"/>
<property name="mcp.home" location="${mcdev.home}/forge67" />
<property name="mcp.obfoutput" location="${mcp.home}/reobf" /> <property name="mcp.obfoutput" location="${mcp.home}/reobf" />
<property name="client.mcp.obfoutput" location="${mcp.obfoutput}/minecraft" /> <property name="client.mcp.obfoutput" location="${mcp.obfoutput}/minecraft" />
<property name="server.mcp.obfoutput" location="${mcp.obfoutput}/minecraft_server" /> <property name="server.mcp.obfoutput" location="${mcp.obfoutput}/minecraft_server" />
@ -74,7 +80,8 @@
<target name="extract-built-jar"> <target name="extract-built-jar">
<side prop="output" src="mcp.obfoutput" side="${side}"/> <side prop="output" src="mcp.obfoutput" side="${side}"/>
<property name="jarname" value="${modname}-${side}-${version}" /> <property name="jarname" value="${modname}-${side}-${version}" />
<jar destfile="${basedir}/${jarname}.zip" > <mkdir dir="${basedir}/target"/>
<jar destfile="${basedir}/target/${jarname}.zip" >
<fileset dir="${output}" includes="**/*.class" /> <fileset dir="${output}" includes="**/*.class" />
<fileset dir="${resource.dir}" erroronmissingdir="false"> <fileset dir="${resource.dir}" erroronmissingdir="false">
<selector if="is.client"> <selector if="is.client">
@ -82,11 +89,13 @@
</selector> </selector>
</fileset> </fileset>
</jar> </jar>
<jar destfile="${basedir}/${jarname}.zip" update="true">
</jar>
</target> </target>
<target name="build" depends="merge-client,merge-server,build-client,build-server" /> <target name="build" depends="merge-client,merge-server,build-client,build-server" />
<target name="buildandclean" depends="build">
<antcall target="clean"/>
</target>
<!-- antcall target to merge source to a side --> <!-- antcall target to merge source to a side -->
<target name="clean-source"> <target name="clean-source">
<side prop="delete-targ" src="mcp.srcdir" side="${side}"/> <side prop="delete-targ" src="mcp.srcdir" side="${side}"/>
@ -108,6 +117,14 @@
<copy todir="${merge-to}" overwrite="true" verbose="true"> <copy todir="${merge-to}" overwrite="true" verbose="true">
<fileset dir="${side-from}" includes="**/*.java" /> <fileset dir="${side-from}" includes="**/*.java" />
<fileset dir="${common.src.dir}" includes="**/*.java" /> <fileset dir="${common.src.dir}" includes="**/*.java" />
<filterchain>
<replacetokens>
<token key="MAJOR" value="${version.major}" />
<token key="MINOR" value="${version.minor}" />
<token key="REV" value="${version.rev}" />
<token key="BUILD" value="${version.build}" />
</replacetokens>
</filterchain>
</copy> </copy>
</target> </target>

View File

@ -3,112 +3,73 @@ package cpw.mods.ironchest.client;
import java.io.File; import java.io.File;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.src.BaseModMp;
import net.minecraft.src.ChestItemRenderHelper; import net.minecraft.src.ChestItemRenderHelper;
import net.minecraft.src.EntityItem; import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityPlayer; import net.minecraft.src.EntityPlayerSP;
import net.minecraft.src.GuiScreen; import net.minecraft.src.GuiScreen;
import net.minecraft.src.ModLoader; import net.minecraft.src.ModLoader;
import net.minecraft.src.ModLoaderMp;
import net.minecraft.src.NBTTagCompound; import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.Packet;
import net.minecraft.src.TileEntity; import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import net.minecraft.src.forge.MinecraftForgeClient; import net.minecraft.src.forge.MinecraftForgeClient;
import cpw.mods.ironchest.ChestChangerType; import cpw.mods.ironchest.ChestChangerType;
import cpw.mods.ironchest.IProxy; import cpw.mods.ironchest.IProxy;
import cpw.mods.ironchest.IronChestType; import cpw.mods.ironchest.IronChestType;
import cpw.mods.ironchest.TileEntityIronChest; import cpw.mods.ironchest.TileEntityIronChest;
public class ClientProxy extends BaseModMp implements IProxy { public class ClientProxy implements IProxy {
@Override @Override
public void registerRenderInformation() { public void registerRenderInformation() {
ChestItemRenderHelper.instance=new IronChestRenderHelper(); ChestItemRenderHelper.instance = new IronChestRenderHelper();
MinecraftForgeClient.preloadTexture("/cpw/mods/ironchest/sprites/block_textures.png"); MinecraftForgeClient.preloadTexture("/cpw/mods/ironchest/sprites/block_textures.png");
MinecraftForgeClient.preloadTexture("/cpw/mods/ironchest/sprites/item_textures.png"); MinecraftForgeClient.preloadTexture("/cpw/mods/ironchest/sprites/item_textures.png");
} }
@Override @Override
public void registerTileEntities() { public void registerTileEntities() {
for (IronChestType typ : IronChestType.values()) { for (IronChestType typ : IronChestType.values()) {
ModLoader.registerTileEntity(typ.clazz, typ.name(), new TileEntityIronChestRenderer()); ModLoader.registerTileEntity(typ.clazz, typ.name(), new TileEntityIronChestRenderer());
} }
} }
@Override @Override
public void registerTranslations() { public void registerTranslations() {
for (IronChestType typ : IronChestType.values()) { for (IronChestType typ : IronChestType.values()) {
ModLoader.addLocalization(typ.name() + ".name", typ.friendlyName); ModLoader.addLocalization(typ.name() + ".name", typ.friendlyName);
} }
for (ChestChangerType typ : ChestChangerType.values()) { for (ChestChangerType typ : ChestChangerType.values()) {
ModLoader.addLocalization("item."+typ.itemName+".name", typ.descriptiveName); ModLoader.addLocalization("item." + typ.itemName + ".name", typ.descriptiveName);
} }
} }
@Override @Override
public void showGUI(TileEntityIronChest te, EntityPlayer player) { public File getMinecraftDir() {
GUIChest.GUI.showGUI(te, player); return Minecraft.getMinecraftDir();
}
}
@Override @Override
public File getMinecraftDir() { public void applyExtraDataToDrops(EntityItem entityitem, NBTTagCompound data) {
return Minecraft.getMinecraftDir(); entityitem.item.setTagCompound(data);
}
@Override }
public void applyExtraDataToDrops(EntityItem entityitem, NBTTagCompound data) {
entityitem.item.setTagCompound(data);
}
@Override @Override
public void registerGUI(int guiId) { public boolean isRemote() {
ModLoaderMp.registerGUI(this, guiId); return ModLoader.getMinecraftInstance().theWorld.isRemote;
} }
@Override @Override
public String getVersion() { public GuiScreen getGuiScreen(int ID, EntityPlayerSP player, World world, int X, int Y, int Z) {
// Do nothing, we never get loaded like that TileEntity te = world.getBlockTileEntity(X, Y, Z);
return ""; if (te != null && te instanceof TileEntityIronChest) {
} return GUIChest.GUI.buildGUI(IronChestType.values()[ID], player.inventory, (TileEntityIronChest) te);
} else {
return null;
}
}
@Override @Override
public void load() { public World getCurrentWorld() {
// Do Nothing, we never get loaded like that return ModLoader.getMinecraftInstance().theWorld;
} }
@Override
public GuiScreen handleGUI(int i) {
for (IronChestType type: IronChestType.values()) {
if (type.guiId==i) {
return GUIChest.GUI.buildGUI(type,ModLoader.getMinecraftInstance().thePlayer.inventory,IronChestType.makeEntity(type.ordinal()));
}
}
return null;
}
@Override
public void handleTileEntityPacket(int x, int y, int z, int type, int[] intData, float[] floatData, String[] stringData) {
TileEntity te=ModLoader.getMinecraftInstance().theWorld.getBlockTileEntity(x, y, z);
if (te!=null && te instanceof TileEntityIronChest) {
TileEntityIronChest icte=(TileEntityIronChest)te;
icte.handlePacketData(type,intData,floatData,stringData);
}
}
@Override
public Packet getDescriptionPacket(TileEntityIronChest tile) {
// NOOP on client
return null;
}
@Override
public void sendTileEntityUpdate(TileEntityIronChest tile) {
// NOOP on client
}
@Override
public boolean isRemote() {
return ModLoader.getMinecraftInstance().theWorld.isRemote;
}
} }

View File

@ -38,20 +38,7 @@ public class GUIChest extends GuiContainer {
} }
public static GUIChest buildGUI(IronChestType type, IInventory playerInventory, TileEntityIronChest chestInventory) { public static GUIChest buildGUI(IronChestType type, IInventory playerInventory, TileEntityIronChest chestInventory) {
for (GUI gui : values()) { return new GUIChest(values()[chestInventory.getType().ordinal()],playerInventory,chestInventory);
if (chestInventory.getType()==gui.mainType) {
return new GUIChest(gui,playerInventory,chestInventory);
}
}
return null;
}
public static void showGUI(TileEntityIronChest te, EntityPlayer player) {
GUIChest gui=buildGUI(te.getType(),player.inventory,te);
if (gui!=null) {
ModLoader.openGUI(player, gui);
} else {
player.displayGUIChest(te);
}
} }
} }

View File

@ -12,6 +12,7 @@ import static org.lwjgl.opengl.GL11.glTranslatef;
import java.util.Random; import java.util.Random;
import net.minecraft.src.Block; import net.minecraft.src.Block;
import net.minecraft.src.EntityItem;
import net.minecraft.src.Item; import net.minecraft.src.Item;
import net.minecraft.src.ItemStack; import net.minecraft.src.ItemStack;
import net.minecraft.src.ModelChest; import net.minecraft.src.ModelChest;
@ -20,7 +21,8 @@ import net.minecraft.src.Tessellator;
import net.minecraft.src.TileEntity; import net.minecraft.src.TileEntity;
import net.minecraft.src.TileEntitySpecialRenderer; import net.minecraft.src.TileEntitySpecialRenderer;
import net.minecraft.src.forge.ForgeHooksClient; import net.minecraft.src.forge.ForgeHooksClient;
import net.minecraft.src.forge.ICustomItemRenderer; import net.minecraft.src.forge.IItemRenderer;
import net.minecraft.src.forge.ItemRenderType;
import net.minecraft.src.forge.MinecraftForgeClient; import net.minecraft.src.forge.MinecraftForgeClient;
import cpw.mods.ironchest.IronChestType; import cpw.mods.ironchest.IronChestType;
import cpw.mods.ironchest.TileEntityIronChest; import cpw.mods.ironchest.TileEntityIronChest;
@ -101,6 +103,7 @@ public class TileEntityIronChestRenderer extends TileEntitySpecialRenderer {
glDisable(2896 /* GL_LIGHTING */); glDisable(2896 /* GL_LIGHTING */);
glEnable(32826 /* GL_RESCALE_NORMAL_EXT */); glEnable(32826 /* GL_RESCALE_NORMAL_EXT */);
glTranslatef((float) x, (float) y, (float) z); glTranslatef((float) x, (float) y, (float) z);
EntityItem customitem=new EntityItem(tileEntityRenderer.worldObj);
for (ItemStack item : tile.getTopItemStacks()) { for (ItemStack item : tile.getTopItemStacks()) {
if (shift > shifts.length) { if (shift > shifts.length) {
break; break;
@ -113,7 +116,7 @@ public class TileEntityIronChestRenderer extends TileEntitySpecialRenderer {
shiftY = shifts[shift][1]; shiftY = shifts[shift][1];
shiftZ = shifts[shift][2]; shiftZ = shifts[shift][2];
shift++; shift++;
ICustomItemRenderer customRenderer = MinecraftForgeClient.getCustomItemRenderer(item.itemID); IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item,ItemRenderType.ENTITY);
float localScale = blockScale; float localScale = blockScale;
if (item.itemID < Block.blocksList.length && Block.blocksList[item.itemID]!=null) { if (item.itemID < Block.blocksList.length && Block.blocksList[item.itemID]!=null) {
int j = Block.blocksList[item.itemID].getRenderType(); int j = Block.blocksList[item.itemID].getRenderType();
@ -135,9 +138,10 @@ public class TileEntityIronChestRenderer extends TileEntitySpecialRenderer {
} }
if (customRenderer != null) { if (customRenderer != null) {
customitem.item=item;
bindTextureByName("/terrain.png"); bindTextureByName("/terrain.png");
ForgeHooksClient.overrideTexture(item.getItem()); ForgeHooksClient.overrideTexture(item.getItem());
ForgeHooksClient.renderCustomItem(customRenderer, renderBlocks, item.itemID, item.getItemDamage(), 1.0F); ForgeHooksClient.renderEntityItem(customRenderer, renderBlocks, customitem);
} else if (item.itemID < Block.blocksList.length && Block.blocksList[item.itemID]!=null && RenderBlocks.renderItemIn3d(Block.blocksList[item.itemID].getRenderType())) { } else if (item.itemID < Block.blocksList.length && Block.blocksList[item.itemID]!=null && RenderBlocks.renderItemIn3d(Block.blocksList[item.itemID].getRenderType())) {
bindTextureByName("/terrain.png"); bindTextureByName("/terrain.png");
ForgeHooksClient.overrideTexture(Block.blocksList[item.itemID]); ForgeHooksClient.overrideTexture(Block.blocksList[item.itemID]);

View File

@ -19,179 +19,185 @@ import net.minecraft.src.forge.ITextureProvider;
public class BlockIronChest extends BlockContainer implements ITextureProvider { public class BlockIronChest extends BlockContainer implements ITextureProvider {
private Random random; private Random random;
public BlockIronChest(int id) {
super(id, Material.iron);
setBlockName("IronChest");
setHardness(3.0F);
setRequiresSelfNotify();
if (id>=256) {
disableStats();
}
random=new Random();
}
@Override public BlockIronChest(int id) {
public TileEntity getBlockEntity() { super(id, Material.iron);
return null; setBlockName("IronChest");
} setHardness(3.0F);
setRequiresSelfNotify();
if (id >= 256) {
disableStats();
}
random = new Random();
}
@Override @Override
public String getTextureFile() { public TileEntity getBlockEntity() {
return "/cpw/mods/ironchest/sprites/block_textures.png"; return null;
} }
@Override @Override
public boolean isOpaqueCube() { public String getTextureFile() {
return false; return "/cpw/mods/ironchest/sprites/block_textures.png";
} }
@Override
public boolean renderAsNormalBlock() {
return false;
}
@Override
public int getRenderType() {
return 22;
}
@Override
public TileEntity getBlockEntity(int metadata) {
return IronChestType.makeEntity(metadata);
}
public int getBlockTexture(IBlockAccess worldAccess, int i, int j, int k, int l) { @Override
int meta=worldAccess.getBlockMetadata(i, j, k); public boolean isOpaqueCube() {
IronChestType type=IronChestType.values()[meta]; return false;
TileEntity te = worldAccess.getBlockTileEntity(i, j, k); }
TileEntityIronChest icte=null;
if (te!=null && te instanceof TileEntityIronChest) {
icte=(TileEntityIronChest)te;
}
if (l==0 || l==1) { // Top and Bottom
return type.getTextureRow()*16+1;
} else if (icte!=null && l==icte.getFacing()) { // Front
return type.getTextureRow()*16+2;
} else { // Back and Sides
return type.getTextureRow()*16;
}
}
@Override @Override
public int getBlockTextureFromSideAndMetadata(int i, int j) { public boolean renderAsNormalBlock() {
IronChestType typ=IronChestType.values()[j]; return false;
switch (i) { }
case 0:
case 1: @Override
return typ.getTextureRow()*16+1; public int getRenderType() {
case 3: return 22;
return typ.getTextureRow()*16+2; }
default:
return typ.getTextureRow()*16; @Override
} public TileEntity getBlockEntity(int metadata) {
} return IronChestType.makeEntity(metadata);
@Override }
public boolean blockActivated(World world, int i, int j, int k, EntityPlayer player) {
TileEntity te = world.getBlockTileEntity(i, j, k); public int getBlockTexture(IBlockAccess worldAccess, int i, int j, int k, int l) {
int meta = worldAccess.getBlockMetadata(i, j, k);
if(te == null || !(te instanceof TileEntityIronChest)) IronChestType type = IronChestType.values()[meta];
TileEntity te = worldAccess.getBlockTileEntity(i, j, k);
TileEntityIronChest icte = null;
if (te != null && te instanceof TileEntityIronChest) {
icte = (TileEntityIronChest) te;
}
if (l == 0 || l == 1) { // Top and Bottom
return type.getTextureRow() * 16 + 1;
} else if (icte != null && l == icte.getFacing()) { // Front
return type.getTextureRow() * 16 + 2;
} else { // Back and Sides
return type.getTextureRow() * 16;
}
}
@Override
public int getBlockTextureFromSideAndMetadata(int i, int j) {
IronChestType typ = IronChestType.values()[j];
switch (i) {
case 0:
case 1:
return typ.getTextureRow() * 16 + 1;
case 3:
return typ.getTextureRow() * 16 + 2;
default:
return typ.getTextureRow() * 16;
}
}
@Override
public boolean blockActivated(World world, int i, int j, int k, EntityPlayer player) {
TileEntity te = world.getBlockTileEntity(i, j, k);
if (te == null || !(te instanceof TileEntityIronChest))
{
return true;
}
if (world.isBlockSolidOnSide(i, j + 1, k, 0))
{
return true;
}
if (world.isRemote) {
return true;
}
player.openGui(mod_IronChest.instance, ((TileEntityIronChest) te).getType().ordinal(), world, i, j, k);
return true;
}
@Override
public void onBlockAdded(World world, int i, int j, int k) {
super.onBlockAdded(world, i, j, k);
world.markBlockNeedsUpdate(i, j, k);
}
@Override
public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityliving) {
byte chestFacing = 0;
int facing = MathHelper.floor_double((double) ((entityliving.rotationYaw * 4F) / 360F) + 0.5D) & 3;
if (facing == 0) {
chestFacing = 2;
}
if (facing == 1) {
chestFacing = 5;
}
if (facing == 2) {
chestFacing = 3;
}
if (facing == 3) {
chestFacing = 4;
}
TileEntity te = world.getBlockTileEntity(i, j, k);
if (te != null && te instanceof TileEntityIronChest) {
((TileEntityIronChest) te).setFacing(chestFacing);
world.markBlockNeedsUpdate(i, j, k);
}
}
@Override
protected int damageDropped(int i) {
return i;
}
public void onBlockRemoval(World world, int i, int j, int k)
{
TileEntityIronChest tileentitychest = (TileEntityIronChest) world.getBlockTileEntity(i, j, k);
if (tileentitychest != null)
{
dropContent(0, tileentitychest, world);
}
super.onBlockRemoval(world, i, j, k);
}
public void dropContent(int newSize, TileEntityIronChest chest, World world) {
for (int l = newSize; l < chest.getSizeInventory(); l++)
{
ItemStack itemstack = chest.getStackInSlot(l);
if (itemstack == null)
{
continue;
}
float f = random.nextFloat() * 0.8F + 0.1F;
float f1 = random.nextFloat() * 0.8F + 0.1F;
float f2 = random.nextFloat() * 0.8F + 0.1F;
while (itemstack.stackSize > 0)
{
int i1 = random.nextInt(21) + 10;
if (i1 > itemstack.stackSize)
{ {
return true; i1 = itemstack.stackSize;
} }
itemstack.stackSize -= i1;
if(world.isBlockSolidOnSide(i, j + 1, k, 0)) EntityItem entityitem = new EntityItem(world, (float) chest.xCoord + f, (float) chest.yCoord + (newSize > 0 ? 1 : 0) + f1, (float) chest.zCoord + f2,
new ItemStack(itemstack.itemID, i1, itemstack.getItemDamage()));
float f3 = 0.05F;
entityitem.motionX = (float) random.nextGaussian() * f3;
entityitem.motionY = (float) random.nextGaussian() * f3 + 0.2F;
entityitem.motionZ = (float) random.nextGaussian() * f3;
if (itemstack.hasTagCompound())
{ {
return true; mod_IronChest.proxy.applyExtraDataToDrops(entityitem, (NBTTagCompound) itemstack.getTagCompound().copy());
} }
world.spawnEntityInWorld(entityitem);
if (world.isRemote) { }
return true; }
} }
mod_IronChest.openGUI(player, (TileEntityIronChest)te);
return true;
}
@Override
public void onBlockAdded(World world, int i, int j, int k) {
super.onBlockAdded(world, i, j, k);
world.markBlockNeedsUpdate(i, j, k);
}
@Override
public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityliving) {
byte chestFacing = 0;
int facing = MathHelper.floor_double((double) ((entityliving.rotationYaw * 4F) / 360F) + 0.5D) & 3;
if (facing == 0) {
chestFacing = 2;
}
if (facing == 1) {
chestFacing = 5;
}
if (facing == 2) {
chestFacing = 3;
}
if (facing == 3) {
chestFacing = 4;
}
TileEntity te = world.getBlockTileEntity(i, j, k);
if (te != null && te instanceof TileEntityIronChest) {
((TileEntityIronChest) te).setFacing(chestFacing);
world.markBlockNeedsUpdate(i, j, k);
}
}
@Override
protected int damageDropped(int i) {
return i;
}
public void onBlockRemoval(World world, int i, int j, int k) @SuppressWarnings({ "rawtypes", "unchecked" })
{ @Override
TileEntityIronChest tileentitychest = (TileEntityIronChest)world.getBlockTileEntity(i, j, k); public void addCreativeItems(ArrayList itemList) {
if (tileentitychest != null) for (IronChestType type : IronChestType.values()) {
{ itemList.add(new ItemStack(this, 1, type.ordinal()));
dropContent(0, tileentitychest, world); }
} }
super.onBlockRemoval(world, i, j, k); }
}
public void dropContent(int newSize, TileEntityIronChest chest, World world) {
for (int l = newSize; l < chest.getSizeInventory(); l++)
{
ItemStack itemstack = chest.getStackInSlot(l);
if (itemstack == null)
{
continue;
}
float f = random.nextFloat() * 0.8F + 0.1F;
float f1 = random.nextFloat() * 0.8F + 0.1F;
float f2 = random.nextFloat() * 0.8F + 0.1F;
while (itemstack.stackSize > 0)
{
int i1 = random.nextInt(21) + 10;
if (i1 > itemstack.stackSize)
{
i1 = itemstack.stackSize;
}
itemstack.stackSize -= i1;
EntityItem entityitem = new EntityItem(world, (float)chest.xCoord + f, (float)chest.yCoord + (newSize>0 ? 1 : 0) + f1, (float)chest.zCoord + f2, new ItemStack(itemstack.itemID, i1, itemstack.getItemDamage()));
float f3 = 0.05F;
entityitem.motionX = (float)random.nextGaussian() * f3;
entityitem.motionY = (float)random.nextGaussian() * f3 + 0.2F;
entityitem.motionZ = (float)random.nextGaussian() * f3;
if (itemstack.hasTagCompound())
{
mod_IronChest.proxy.applyExtraDataToDrops(entityitem, (NBTTagCompound)itemstack.getTagCompound().copy());
}
world.spawnEntityInWorld(entityitem);
}
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void addCreativeItems(ArrayList itemList) {
for (IronChestType type : IronChestType.values()) {
itemList.add(new ItemStack(this,1,type.ordinal()));
}
}
}

View File

@ -43,7 +43,7 @@ public enum ChestChangerType {
} }
public ItemChestChanger buildItem(Configuration cfg, int id) { public ItemChestChanger buildItem(Configuration cfg, int id) {
int itemId=Integer.parseInt(cfg.getOrCreateIntProperty(itemName, Configuration.ITEM_PROPERTY, id).value); int itemId=Integer.parseInt(cfg.getOrCreateIntProperty(itemName, Configuration.CATEGORY_ITEM, id).value);
item=new ItemChestChanger(itemId,this); item=new ItemChestChanger(itemId,this);
return item; return item;
} }

View File

@ -3,7 +3,6 @@ package cpw.mods.ironchest;
import net.minecraft.src.Container; import net.minecraft.src.Container;
import net.minecraft.src.EntityPlayer; import net.minecraft.src.EntityPlayer;
import net.minecraft.src.IInventory; import net.minecraft.src.IInventory;
import net.minecraft.src.InventoryPlayer;
import net.minecraft.src.ItemStack; import net.minecraft.src.ItemStack;
import net.minecraft.src.Slot; import net.minecraft.src.Slot;

View File

@ -3,11 +3,11 @@ package cpw.mods.ironchest;
import java.io.File; import java.io.File;
import net.minecraft.src.EntityItem; import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.NBTTagCompound; import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.Packet; import net.minecraft.src.World;
import net.minecraft.src.forge.IGuiHandler;
public interface IProxy { public interface IProxy extends IGuiHandler {
public abstract void registerRenderInformation(); public abstract void registerRenderInformation();
@ -15,19 +15,11 @@ public interface IProxy {
public abstract void registerTranslations(); public abstract void registerTranslations();
public abstract void showGUI(TileEntityIronChest te, EntityPlayer player);
public abstract File getMinecraftDir(); public abstract File getMinecraftDir();
public abstract void applyExtraDataToDrops(EntityItem item, NBTTagCompound data); public abstract void applyExtraDataToDrops(EntityItem item, NBTTagCompound data);
public abstract void registerGUI(int guiId);
public abstract void handleTileEntityPacket(int x, int y, int z, int type, int[] intData, float[] floatData, String[] stringData);
public abstract Packet getDescriptionPacket(TileEntityIronChest tile);
public abstract void sendTileEntityUpdate(TileEntityIronChest tile);
public abstract boolean isRemote(); public abstract boolean isRemote();
public abstract World getCurrentWorld();
} }

View File

@ -7,131 +7,110 @@ import net.minecraft.src.Block;
import net.minecraft.src.Item; import net.minecraft.src.Item;
import net.minecraft.src.ItemStack; import net.minecraft.src.ItemStack;
import net.minecraft.src.ModLoader; import net.minecraft.src.ModLoader;
import net.minecraft.src.mod_IronChest;
import net.minecraft.src.forge.Configuration;
public enum IronChestType { public enum IronChestType {
IRON(54, 9, true, "Iron Chest", "guiIronChest", "ironchest.png", 0, Item.ingotIron, TileEntityIronChest.class, "mmmmPmmmm","mGmG3GmGm"), IRON(54, 9, true, "Iron Chest", "ironchest.png", 0, Item.ingotIron, TileEntityIronChest.class, "mmmmPmmmm", "mGmG3GmGm"),
GOLD(81, 9, true, "Gold Chest", "guiGoldChest", "goldchest.png", 1, Item.ingotGold, TileEntityGoldChest.class, "mmmmPmmmm","mGmG4GmGm"), GOLD(81, 9, true, "Gold Chest", "goldchest.png", 1, Item.ingotGold, TileEntityGoldChest.class, "mmmmPmmmm", "mGmG4GmGm"),
DIAMOND(108, 12, true, "Diamond Chest", "guiDiamondChest", "diamondchest.png", 2, Item.diamond, TileEntityDiamondChest.class, "GGGmPmGGG", "GGGG4Gmmm"), DIAMOND(108, 12, true, "Diamond Chest", "diamondchest.png", 2, Item.diamond, TileEntityDiamondChest.class, "GGGmPmGGG", "GGGG4Gmmm"),
COPPER(45, 9, false, "Copper Chest", "guiCopperChest", "copperchest.png", 3, null, TileEntityCopperChest.class, "mmmmCmmmm"), COPPER(45, 9, false, "Copper Chest", "copperchest.png", 3, null, TileEntityCopperChest.class, "mmmmCmmmm"),
SILVER(72, 9, false, "Silver Chest", "guiSilverChest", "silverchest.png", 4, null, TileEntitySilverChest.class, "mmmm0mmmm", "mGmG3GmGm"), SILVER(72, 9, false, "Silver Chest", "silverchest.png", 4, null, TileEntitySilverChest.class, "mmmm0mmmm", "mGmG3GmGm"),
CRYSTAL(108, 12, true, "Crystal Chest", "guiDiamondChest", "crystalchest.png", 5, Item.itemsList[Block.glass.blockID], TileEntityCrystalChest.class, "GGGGPGGGG"); CRYSTAL(108, 12, true, "Crystal Chest", "crystalchest.png", 5, Item.itemsList[Block.glass.blockID], TileEntityCrystalChest.class, "GGGGPGGGG");
int size; int size;
private int rowLength; private int rowLength;
public String friendlyName; public String friendlyName;
private boolean tieredChest; private boolean tieredChest;
private String modelTexture; private String modelTexture;
private String guiName; private int textureRow;
private int textureRow; public Class<? extends TileEntityIronChest> clazz;
public Class<? extends TileEntityIronChest> clazz; Item mat;
Item mat; private String[] recipes;
private String[] recipes; private ArrayList<ItemStack> matList;
public int guiId;
private ArrayList<ItemStack> matList;
IronChestType(int size, int rowLength, boolean tieredChest, String friendlyName, String guiName, String modelTexture, int textureRow, Item mat, IronChestType(int size, int rowLength, boolean tieredChest, String friendlyName, String modelTexture, int textureRow, Item mat,
Class<? extends TileEntityIronChest> clazz, String... recipes) { Class<? extends TileEntityIronChest> clazz, String... recipes) {
this.size = size; this.size = size;
this.rowLength = rowLength; this.rowLength = rowLength;
this.tieredChest = tieredChest; this.tieredChest = tieredChest;
this.friendlyName = friendlyName; this.friendlyName = friendlyName;
this.guiName = guiName; this.modelTexture = "/cpw/mods/ironchest/sprites/" + modelTexture;
this.modelTexture = "/cpw/mods/ironchest/sprites/" + modelTexture; this.textureRow = textureRow;
this.textureRow = textureRow; this.clazz = clazz;
this.clazz = clazz; this.mat = mat;
this.mat = mat; this.recipes = recipes;
this.recipes = recipes; this.matList = new ArrayList<ItemStack>();
this.matList=new ArrayList<ItemStack>(); if (mat != null) {
if (mat!=null) { matList.add(new ItemStack(mat));
matList.add(new ItemStack(mat)); }
} }
}
public String getModelTexture() { public String getModelTexture() {
return modelTexture; return modelTexture;
} }
public int getTextureRow() { public int getTextureRow() {
return textureRow; return textureRow;
} }
public static TileEntityIronChest makeEntity(int metadata) { public static TileEntityIronChest makeEntity(int metadata) {
// Compatibility // Compatibility
int chesttype = metadata; int chesttype = metadata;
try { try {
TileEntityIronChest te = values()[chesttype].clazz.newInstance(); TileEntityIronChest te = values()[chesttype].clazz.newInstance();
return te; return te;
} catch (InstantiationException e) { } catch (InstantiationException e) {
// unpossible // unpossible
e.printStackTrace(); e.printStackTrace();
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
// unpossible // unpossible
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;
} }
public static void registerTranslations() { public static void registerTranslations() {
} }
public static void generateTieredRecipies(BlockIronChest blockResult) { public static void generateTieredRecipies(BlockIronChest blockResult) {
ItemStack previous = new ItemStack(Block.chest); ItemStack previous = new ItemStack(Block.chest);
for (IronChestType typ : values()) { for (IronChestType typ : values()) {
if (!typ.tieredChest) if (!typ.tieredChest)
continue; continue;
generateRecipesForType(blockResult, previous, typ, typ.mat); generateRecipesForType(blockResult, previous, typ, typ.mat);
previous = new ItemStack(blockResult, 1, typ.ordinal()); previous = new ItemStack(blockResult, 1, typ.ordinal());
} }
} }
public static void generateRecipesForType(BlockIronChest blockResult, Object previousTier, IronChestType type, Object mat) { public static void generateRecipesForType(BlockIronChest blockResult, Object previousTier, IronChestType type, Object mat) {
for (String recipe : type.recipes) { for (String recipe : type.recipes) {
String[] recipeSplit = new String[] { recipe.substring(0, 3), recipe.substring(3, 6), recipe.substring(6, 9) }; String[] recipeSplit = new String[] { recipe.substring(0, 3), recipe.substring(3, 6), recipe.substring(6, 9) };
addRecipe(new ItemStack(blockResult, 1, type.ordinal()), recipeSplit, 'm', mat, 'P', previousTier, 'G', Block.glass, 'C', Block.chest, addRecipe(new ItemStack(blockResult, 1, type.ordinal()), recipeSplit, 'm', mat, 'P', previousTier, 'G', Block.glass, 'C', Block.chest,
'0', new ItemStack(blockResult, 1, 0)/* Iron */, '1', new ItemStack(blockResult, 1, 1)/* GOLD */, '3', new ItemStack(blockResult, '0', new ItemStack(blockResult, 1, 0)/* Iron */, '1', new ItemStack(blockResult, 1, 1)/* GOLD */, '3', new ItemStack(blockResult,
1, 3)/* Copper */, '4', new ItemStack(blockResult,1,4)); 1, 3)/* Copper */, '4', new ItemStack(blockResult, 1, 4));
} }
} }
public static void addRecipe(ItemStack is, Object... parts) { public static void addRecipe(ItemStack is, Object... parts) {
ModLoader.addRecipe(is, parts); ModLoader.addRecipe(is, parts);
} }
public int getGUI() { public int getRowCount() {
return guiId; return size / rowLength;
} }
public static void initGUIs(Configuration cfg) { public int getRowLength() {
int defGUI = 51; return rowLength;
for (IronChestType typ : values()) { }
if (typ.guiName != null) {
typ.guiId = Integer.parseInt(cfg.getOrCreateIntProperty(typ.guiName, Configuration.GENERAL_PROPERTY, defGUI++).value);
mod_IronChest.proxy.registerGUI(typ.guiId);
} else {
typ.guiId = -1;
}
}
}
public int getRowCount() { public void addMat(ItemStack ore) {
return size / rowLength; this.matList.add(ore);
} }
public int getRowLength() { public List<ItemStack> getMatList() {
return rowLength; return matList;
} }
public void addMat(ItemStack ore) { public boolean isTransparent() {
this.matList.add(ore); return this == CRYSTAL;
} }
public List<ItemStack> getMatList() {
return matList;
}
public boolean isTransparent() {
return this==CRYSTAL;
}
} }

View File

@ -5,7 +5,6 @@ import net.minecraft.src.Item;
import net.minecraft.src.ItemStack; import net.minecraft.src.ItemStack;
import net.minecraft.src.TileEntity; import net.minecraft.src.TileEntity;
import net.minecraft.src.World; import net.minecraft.src.World;
import net.minecraft.src.mod_IronChest;
import net.minecraft.src.forge.ITextureProvider; import net.minecraft.src.forge.ITextureProvider;
public class ItemChestChanger extends Item implements ITextureProvider { public class ItemChestChanger extends Item implements ITextureProvider {
@ -32,8 +31,8 @@ public class ItemChestChanger extends Item implements ITextureProvider {
world.setBlockTileEntity(X, Y, Z, newchest); world.setBlockTileEntity(X, Y, Z, newchest);
world.setBlockMetadataWithNotify(X, Y, Z, newchest.getType().ordinal()); world.setBlockMetadataWithNotify(X, Y, Z, newchest.getType().ordinal());
world.notifyBlocksOfNeighborChange(X, Y, Z, world.getBlockId(X, Y, Z)); world.notifyBlocksOfNeighborChange(X, Y, Z, world.getBlockId(X, Y, Z));
world.markBlockNeedsUpdate(X, Y, Z);
stack.stackSize=0; stack.stackSize=0;
mod_IronChest.proxy.sendTileEntityUpdate(newchest);
return true; return true;
} else { } else {
return false; return false;

View File

@ -0,0 +1,96 @@
package cpw.mods.ironchest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.src.NetworkManager;
import net.minecraft.src.Packet;
import net.minecraft.src.Packet1Login;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import net.minecraft.src.mod_IronChest;
import net.minecraft.src.forge.IConnectionHandler;
import net.minecraft.src.forge.IPacketHandler;
import net.minecraft.src.forge.MessageManager;
public class PacketHandler implements IPacketHandler, IConnectionHandler {
@Override
public void onConnect(NetworkManager network) {
}
@Override
public void onLogin(NetworkManager network, Packet1Login login) {
MessageManager.getInstance().registerChannel(network, this, "IronChest");
}
@Override
public void onDisconnect(NetworkManager network, String message, Object[] args) {
MessageManager.getInstance().removeConnection(network);
}
@Override
public void onPacketData(NetworkManager network, String channel, byte[] data) {
DataInputStream dis=new DataInputStream(new ByteArrayInputStream(data));
int x;
int y;
int z;
int typ;
boolean hasStacks;
int[] items=null;
try {
x = dis.readInt();
y = dis.readInt();
z = dis.readInt();
typ=dis.readByte();
hasStacks=dis.readByte()!=0;
if (hasStacks) {
items = new int[24];
for (int i=0; i<items.length; i++) {
items[i]=dis.readInt();
}
}
} catch (IOException e) {
return;
}
World world=mod_IronChest.proxy.getCurrentWorld();
TileEntity te=world.getBlockTileEntity(x, y, z);
if (te instanceof TileEntityIronChest) {
TileEntityIronChest icte = (TileEntityIronChest)te;
icte.handlePacketData(typ, items);
}
}
public static Packet getPacket(TileEntityIronChest tileEntityIronChest) {
ByteArrayOutputStream bos=new ByteArrayOutputStream(140);
DataOutputStream dos=new DataOutputStream(bos);
int x=tileEntityIronChest.xCoord;
int y=tileEntityIronChest.yCoord;
int z=tileEntityIronChest.zCoord;
int typ=tileEntityIronChest.getType().ordinal();
int[] items=tileEntityIronChest.buildIntDataList();
boolean hasStacks=(items!=null);
try {
dos.writeInt(x);
dos.writeInt(y);
dos.writeInt(z);
dos.writeByte(typ);
dos.writeByte(hasStacks? 1 : 0);
if (hasStacks) {
for (int i=0; i<24; i++) {
dos.writeInt(items[i]);
}
}
} catch (IOException e) {
// UNPOSSIBLE?
}
Packet250CustomPayload pkt=new Packet250CustomPayload();
pkt.channel="IronChest";
pkt.data=bos.toByteArray();
pkt.length=bos.size();
return pkt;
}
}

View File

@ -1,6 +1,7 @@
package cpw.mods.ironchest; package cpw.mods.ironchest;
import net.minecraft.src.ModLoader; import net.minecraft.src.ModLoader;
import net.minecraft.src.forge.MinecraftForge;
public enum ServerClientProxy { public enum ServerClientProxy {
CLIENT("cpw.mods.ironchest.client.ClientProxy"), CLIENT("cpw.mods.ironchest.client.ClientProxy"),
@ -21,15 +22,10 @@ public enum ServerClientProxy {
} }
} }
public static IProxy getProxy() { public static IProxy getProxy() {
try { if (MinecraftForge.isClient()) {
ModLoader.class.getMethod("getMinecraftInstance"); return CLIENT.buildProxy();
} catch (SecurityException e) { } else {
// UNPOSSIBLE return SERVER.buildProxy();
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
return SERVER.buildProxy();
} }
return CLIENT.buildProxy();
} }
} }

View File

@ -13,369 +13,373 @@ import net.minecraft.src.TileEntity;
import net.minecraft.src.mod_IronChest; import net.minecraft.src.mod_IronChest;
public class TileEntityIronChest extends TileEntity implements IInventory { public class TileEntityIronChest extends TileEntity implements IInventory {
private int ticksSinceSync; private int ticksSinceSync;
public float prevLidAngle; public float prevLidAngle;
public float lidAngle; public float lidAngle;
private int numUsingPlayers; private int numUsingPlayers;
private IronChestType type; private IronChestType type;
public ItemStack[] chestContents; public ItemStack[] chestContents;
private ItemStack[] topStacks; private ItemStack[] topStacks;
private byte facing; private byte facing;
private boolean inventoryTouched; private boolean inventoryTouched;
private boolean hadStuff; private boolean hadStuff;
public TileEntityIronChest() { public TileEntityIronChest() {
this(IronChestType.IRON); this(IronChestType.IRON);
} }
protected TileEntityIronChest(IronChestType type) { protected TileEntityIronChest(IronChestType type) {
super(); super();
this.type = type; this.type = type;
this.chestContents = new ItemStack[getSizeInventory()]; this.chestContents = new ItemStack[getSizeInventory()];
this.topStacks = new ItemStack[8]; this.topStacks = new ItemStack[8];
} }
public ItemStack[] getContents() { public ItemStack[] getContents() {
return chestContents; return chestContents;
} }
@Override @Override
public int getSizeInventory() { public int getSizeInventory() {
return type.size; return type.size;
} }
public byte getFacing() { public byte getFacing() {
return this.facing; return this.facing;
} }
@Override @Override
public String getInvName() { public String getInvName() {
return type.name(); return type.name();
} }
public IronChestType getType() { public IronChestType getType() {
return type; return type;
} }
@Override @Override
public ItemStack getStackInSlot(int i) { public ItemStack getStackInSlot(int i) {
inventoryTouched = true; inventoryTouched = true;
return chestContents[i]; return chestContents[i];
} }
@Override @Override
public void onInventoryChanged() { public void onInventoryChanged() {
super.onInventoryChanged(); super.onInventoryChanged();
sortTopStacks(); sortTopStacks();
} }
protected void sortTopStacks() { protected void sortTopStacks() {
if (!type.isTransparent() || mod_IronChest.proxy.isRemote()) { if (!type.isTransparent() || mod_IronChest.proxy.isRemote()) {
return; return;
} }
ItemStack[] tempCopy = new ItemStack[getSizeInventory()]; ItemStack[] tempCopy = new ItemStack[getSizeInventory()];
boolean hasStuff = false; boolean hasStuff = false;
int compressedIdx = 0; int compressedIdx = 0;
mainLoop: for (int i = 0; i < getSizeInventory(); i++) { mainLoop: for (int i = 0; i < getSizeInventory(); i++) {
if (chestContents[i] != null) { if (chestContents[i] != null) {
for (int j = 0; j < compressedIdx; j++) { for (int j = 0; j < compressedIdx; j++) {
if (tempCopy[j].isItemEqual(chestContents[i])) { if (tempCopy[j].isItemEqual(chestContents[i])) {
tempCopy[j].stackSize += chestContents[i].stackSize; tempCopy[j].stackSize += chestContents[i].stackSize;
continue mainLoop; continue mainLoop;
} }
} }
tempCopy[compressedIdx++] = chestContents[i].copy(); tempCopy[compressedIdx++] = chestContents[i].copy();
hasStuff = true; hasStuff = true;
} }
} }
if (!hasStuff && hadStuff) { if (!hasStuff && hadStuff) {
hadStuff = false; hadStuff = false;
for (int i = 0; i < topStacks.length; i++) { for (int i = 0; i < topStacks.length; i++) {
topStacks[i] = null; topStacks[i] = null;
} }
mod_IronChest.proxy.sendTileEntityUpdate(this); if (worldObj!=null) {
return; worldObj.markBlockNeedsUpdate(xCoord, yCoord, zCoord);
} }
hadStuff = true; return;
Arrays.sort(tempCopy, new Comparator<ItemStack>() { }
@Override hadStuff = true;
public int compare(ItemStack o1, ItemStack o2) { Arrays.sort(tempCopy, new Comparator<ItemStack>() {
if (o1 == null) { @Override
return 1; public int compare(ItemStack o1, ItemStack o2) {
} else if (o2 == null) { if (o1 == null) {
return -1; return 1;
} else { } else if (o2 == null) {
return o2.stackSize - o1.stackSize; return -1;
} } else {
} return o2.stackSize - o1.stackSize;
}); }
int p = 0; }
for (int i = 0; i < tempCopy.length; i++) { });
if (tempCopy[i] != null && tempCopy[i].stackSize > 0) { int p = 0;
topStacks[p++] = tempCopy[i]; for (int i = 0; i < tempCopy.length; i++) {
if (p == topStacks.length) { if (tempCopy[i] != null && tempCopy[i].stackSize > 0) {
break; topStacks[p++] = tempCopy[i];
} if (p == topStacks.length) {
} break;
} }
for (int i = p; i < topStacks.length; i++) { }
topStacks[i] = null; }
} for (int i = p; i < topStacks.length; i++) {
mod_IronChest.proxy.sendTileEntityUpdate(this); topStacks[i] = null;
} }
if (worldObj!=null) {
worldObj.markBlockNeedsUpdate(xCoord, yCoord, zCoord);
}
}
@Override @Override
public ItemStack decrStackSize(int i, int j) { public ItemStack decrStackSize(int i, int j) {
if (chestContents[i] != null) if (chestContents[i] != null)
{ {
if (chestContents[i].stackSize <= j) if (chestContents[i].stackSize <= j)
{ {
ItemStack itemstack = chestContents[i]; ItemStack itemstack = chestContents[i];
chestContents[i] = null; chestContents[i] = null;
onInventoryChanged(); onInventoryChanged();
return itemstack; return itemstack;
} }
ItemStack itemstack1 = chestContents[i].splitStack(j); ItemStack itemstack1 = chestContents[i].splitStack(j);
if (chestContents[i].stackSize == 0) if (chestContents[i].stackSize == 0)
{ {
chestContents[i] = null; chestContents[i] = null;
} }
onInventoryChanged(); onInventoryChanged();
return itemstack1; return itemstack1;
} }
else else
{ {
return null; return null;
} }
} }
@Override @Override
public void setInventorySlotContents(int i, ItemStack itemstack) { public void setInventorySlotContents(int i, ItemStack itemstack) {
chestContents[i] = itemstack; chestContents[i] = itemstack;
if (itemstack != null && itemstack.stackSize > getInventoryStackLimit()) if (itemstack != null && itemstack.stackSize > getInventoryStackLimit())
{ {
itemstack.stackSize = getInventoryStackLimit(); itemstack.stackSize = getInventoryStackLimit();
} }
onInventoryChanged(); onInventoryChanged();
} }
@Override @Override
public void readFromNBT(NBTTagCompound nbttagcompound) public void readFromNBT(NBTTagCompound nbttagcompound)
{ {
super.readFromNBT(nbttagcompound); super.readFromNBT(nbttagcompound);
NBTTagList nbttaglist = nbttagcompound.getTagList("Items"); NBTTagList nbttaglist = nbttagcompound.getTagList("Items");
chestContents = new ItemStack[getSizeInventory()]; chestContents = new ItemStack[getSizeInventory()];
for (int i = 0; i < nbttaglist.tagCount(); i++) for (int i = 0; i < nbttaglist.tagCount(); i++)
{ {
NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.tagAt(i); NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.tagAt(i);
int j = nbttagcompound1.getByte("Slot") & 0xff; int j = nbttagcompound1.getByte("Slot") & 0xff;
if (j >= 0 && j < chestContents.length) if (j >= 0 && j < chestContents.length)
{ {
chestContents[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1); chestContents[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
} }
} }
facing = nbttagcompound.getByte("facing"); facing = nbttagcompound.getByte("facing");
sortTopStacks(); sortTopStacks();
} }
@Override @Override
public void writeToNBT(NBTTagCompound nbttagcompound) public void writeToNBT(NBTTagCompound nbttagcompound)
{ {
super.writeToNBT(nbttagcompound); super.writeToNBT(nbttagcompound);
NBTTagList nbttaglist = new NBTTagList(); NBTTagList nbttaglist = new NBTTagList();
for (int i = 0; i < chestContents.length; i++) for (int i = 0; i < chestContents.length; i++)
{ {
if (chestContents[i] != null) if (chestContents[i] != null)
{ {
NBTTagCompound nbttagcompound1 = new NBTTagCompound(); NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Slot", (byte) i); nbttagcompound1.setByte("Slot", (byte) i);
chestContents[i].writeToNBT(nbttagcompound1); chestContents[i].writeToNBT(nbttagcompound1);
nbttaglist.appendTag(nbttagcompound1); nbttaglist.appendTag(nbttagcompound1);
} }
} }
nbttagcompound.setTag("Items", nbttaglist); nbttagcompound.setTag("Items", nbttaglist);
nbttagcompound.setByte("facing", facing); nbttagcompound.setByte("facing", facing);
} }
@Override @Override
public int getInventoryStackLimit() { public int getInventoryStackLimit() {
return 64; return 64;
} }
@Override @Override
public boolean isUseableByPlayer(EntityPlayer entityplayer) { public boolean isUseableByPlayer(EntityPlayer entityplayer) {
if (worldObj == null) { if (worldObj == null) {
return true; return true;
} }
if (worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this) { if (worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this) {
return false; return false;
} }
return entityplayer.getDistanceSq((double) xCoord + 0.5D, (double) yCoord + 0.5D, (double) zCoord + 0.5D) <= 64D; return entityplayer.getDistanceSq((double) xCoord + 0.5D, (double) yCoord + 0.5D, (double) zCoord + 0.5D) <= 64D;
} }
@Override @Override
public void updateEntity() { public void updateEntity() {
super.updateEntity(); super.updateEntity();
// Resynchronize clients with the server state // Resynchronize clients with the server state
if ((++ticksSinceSync % 20) * 4 == 0) { if ((++ticksSinceSync % 20) * 4 == 0) {
worldObj.playNoteAt(xCoord, yCoord, zCoord, 3, ((numUsingPlayers << 3) & 0xF8) | (facing & 0x7)); worldObj.playNoteAt(xCoord, yCoord, zCoord, 3, ((numUsingPlayers << 3) & 0xF8) | (facing & 0x7));
if (inventoryTouched) { if (inventoryTouched) {
inventoryTouched = false; inventoryTouched = false;
sortTopStacks(); sortTopStacks();
} }
} }
prevLidAngle = lidAngle; prevLidAngle = lidAngle;
float f = 0.1F; float f = 0.1F;
if (numUsingPlayers > 0 && lidAngle == 0.0F) { if (numUsingPlayers > 0 && lidAngle == 0.0F) {
double d = (double) xCoord + 0.5D; double d = (double) xCoord + 0.5D;
double d1 = (double) zCoord + 0.5D; double d1 = (double) zCoord + 0.5D;
worldObj.playSoundEffect(d, (double) yCoord + 0.5D, d1, "random.chestopen", 0.5F, worldObj.rand.nextFloat() * 0.1F + 0.9F); worldObj.playSoundEffect(d, (double) yCoord + 0.5D, d1, "random.chestopen", 0.5F, worldObj.rand.nextFloat() * 0.1F + 0.9F);
} }
if (numUsingPlayers == 0 && lidAngle > 0.0F || numUsingPlayers > 0 && lidAngle < 1.0F) { if (numUsingPlayers == 0 && lidAngle > 0.0F || numUsingPlayers > 0 && lidAngle < 1.0F) {
float f1 = lidAngle; float f1 = lidAngle;
if (numUsingPlayers > 0) { if (numUsingPlayers > 0) {
lidAngle += f; lidAngle += f;
} else { } else {
lidAngle -= f; lidAngle -= f;
} }
if (lidAngle > 1.0F) { if (lidAngle > 1.0F) {
lidAngle = 1.0F; lidAngle = 1.0F;
} }
float f2 = 0.5F; float f2 = 0.5F;
if (lidAngle < f2 && f1 >= f2) { if (lidAngle < f2 && f1 >= f2) {
double d2 = (double) xCoord + 0.5D; double d2 = (double) xCoord + 0.5D;
double d3 = (double) zCoord + 0.5D; double d3 = (double) zCoord + 0.5D;
worldObj.playSoundEffect(d2, (double) yCoord + 0.5D, d3, "random.chestclosed", 0.5F, worldObj.rand.nextFloat() * 0.1F + 0.9F); worldObj.playSoundEffect(d2, (double) yCoord + 0.5D, d3, "random.chestclosed", 0.5F, worldObj.rand.nextFloat() * 0.1F + 0.9F);
} }
if (lidAngle < 0.0F) { if (lidAngle < 0.0F) {
lidAngle = 0.0F; lidAngle = 0.0F;
} }
} }
} }
@Override @Override
public void onTileEntityPowered(int i, int j) public void onTileEntityPowered(int i, int j)
{ {
if (i == 1) if (i == 1)
{ {
numUsingPlayers = j; numUsingPlayers = j;
} else if (i == 2) { } else if (i == 2) {
facing = (byte) j; facing = (byte) j;
} else if (i == 3) { } else if (i == 3) {
facing = (byte) (j & 0x7); facing = (byte) (j & 0x7);
numUsingPlayers = (j & 0xF8) >> 3; numUsingPlayers = (j & 0xF8) >> 3;
} }
} }
@Override @Override
public void openChest() { public void openChest() {
if (worldObj == null) if (worldObj == null)
return; return;
numUsingPlayers++; numUsingPlayers++;
worldObj.playNoteAt(xCoord, yCoord, zCoord, 1, numUsingPlayers); worldObj.playNoteAt(xCoord, yCoord, zCoord, 1, numUsingPlayers);
} }
@Override @Override
public void closeChest() { public void closeChest() {
if (worldObj == null) if (worldObj == null)
return; return;
numUsingPlayers--; numUsingPlayers--;
worldObj.playNoteAt(xCoord, yCoord, zCoord, 1, numUsingPlayers); worldObj.playNoteAt(xCoord, yCoord, zCoord, 1, numUsingPlayers);
} }
public void setFacing(byte chestFacing) { public void setFacing(byte chestFacing) {
this.facing = chestFacing; this.facing = chestFacing;
} }
public TileEntityIronChest applyUpgradeItem(ItemChestChanger itemChestChanger) { public TileEntityIronChest applyUpgradeItem(ItemChestChanger itemChestChanger) {
if (numUsingPlayers > 0) { if (numUsingPlayers > 0) {
return null; return null;
} }
if (!itemChestChanger.getType().canUpgrade(this.getType())) { if (!itemChestChanger.getType().canUpgrade(this.getType())) {
return null; return null;
} }
TileEntityIronChest newEntity = IronChestType.makeEntity(itemChestChanger.getTargetChestOrdinal(getType().ordinal())); TileEntityIronChest newEntity = IronChestType.makeEntity(itemChestChanger.getTargetChestOrdinal(getType().ordinal()));
int newSize = newEntity.chestContents.length; int newSize = newEntity.chestContents.length;
System.arraycopy(chestContents, 0, newEntity.chestContents, 0, Math.min(newSize, chestContents.length)); System.arraycopy(chestContents, 0, newEntity.chestContents, 0, Math.min(newSize, chestContents.length));
BlockIronChest block = mod_IronChest.ironChestBlock; BlockIronChest block = mod_IronChest.ironChestBlock;
block.dropContent(newSize, this, this.worldObj); block.dropContent(newSize, this, this.worldObj);
newEntity.setFacing(facing); newEntity.setFacing(facing);
newEntity.sortTopStacks(); newEntity.sortTopStacks();
return newEntity; return newEntity;
} }
public ItemStack[] getTopItemStacks() { public ItemStack[] getTopItemStacks() {
return topStacks; return topStacks;
} }
public TileEntityIronChest updateFromMetadata(int l) { public TileEntityIronChest updateFromMetadata(int l) {
if (worldObj != null && worldObj.isRemote) { if (worldObj != null && worldObj.isRemote) {
if (l != type.ordinal()) { if (l != type.ordinal()) {
worldObj.setBlockTileEntity(xCoord, yCoord, zCoord, IronChestType.makeEntity(l)); worldObj.setBlockTileEntity(xCoord, yCoord, zCoord, IronChestType.makeEntity(l));
return (TileEntityIronChest) worldObj.getBlockTileEntity(xCoord, yCoord, zCoord); return (TileEntityIronChest) worldObj.getBlockTileEntity(xCoord, yCoord, zCoord);
} }
} }
return this; return this;
} }
public Packet getDescriptionPacket() { public Packet getDescriptionPacket() {
return mod_IronChest.proxy.getDescriptionPacket(this); return PacketHandler.getPacket(this);
} }
public void handlePacketData(int typeData, int[] intData, float[] floatData, String[] stringData) { public void handlePacketData(int typeData, int[] intData) {
TileEntityIronChest chest = this; TileEntityIronChest chest = this;
if (this.type.ordinal() != typeData) { if (this.type.ordinal() != typeData) {
chest = updateFromMetadata(typeData); chest = updateFromMetadata(typeData);
} }
if (IronChestType.values()[typeData].isTransparent() && intData != null) { if (IronChestType.values()[typeData].isTransparent() && intData != null) {
int pos = 0; int pos = 0;
if (intData.length < chest.topStacks.length * 3) { if (intData.length < chest.topStacks.length * 3) {
return; return;
} }
for (int i = 0; i < chest.topStacks.length; i++) { for (int i = 0; i < chest.topStacks.length; i++) {
if (intData[pos + 2] != 0) { if (intData[pos + 2] != 0) {
ItemStack is = new ItemStack(intData[pos], intData[pos + 2], intData[pos + 1]); ItemStack is = new ItemStack(intData[pos], intData[pos + 2], intData[pos + 1]);
chest.topStacks[i] = is; chest.topStacks[i] = is;
} else { } else {
chest.topStacks[i] = null; chest.topStacks[i] = null;
} }
pos += 3; pos += 3;
} }
} }
} }
public int[] buildIntDataList() { public int[] buildIntDataList() {
if (type.isTransparent()) { if (type.isTransparent()) {
int[] sortList = new int[topStacks.length * 3]; int[] sortList = new int[topStacks.length * 3];
int pos = 0; int pos = 0;
for (ItemStack is : topStacks) { for (ItemStack is : topStacks) {
if (is != null) { if (is != null) {
sortList[pos++] = is.itemID; sortList[pos++] = is.itemID;
sortList[pos++] = is.getItemDamage(); sortList[pos++] = is.getItemDamage();
sortList[pos++] = is.stackSize; sortList[pos++] = is.stackSize;
} else { } else {
sortList[pos++] = 0; sortList[pos++] = 0;
sortList[pos++] = 0; sortList[pos++] = 0;
sortList[pos++] = 0; sortList[pos++] = 0;
} }
} }
return sortList; return sortList;
} }
return null; return null;
} }
public ItemStack getStackInSlotOnClosing(int par1) public ItemStack getStackInSlotOnClosing(int par1)
{ {
if (this.chestContents[par1] != null) if (this.chestContents[par1] != null)
{ {
ItemStack var2 = this.chestContents[par1]; ItemStack var2 = this.chestContents[par1];
this.chestContents[par1] = null; this.chestContents[par1] = null;
return var2; return var2;
} }
else else
{ {
return null; return null;
} }
} }
} }

View File

@ -0,0 +1,17 @@
package cpw.mods.ironchest;
public class Version {
public static final String MAJOR="@MAJOR@";
public static final String MINOR="@MINOR@";
public static final String REV="@REV@";
public static final String BUILD="@BUILD@";
public static final String version() {
return MAJOR+"."+MINOR;
}
public static final String name() {
return "Iron Chest ("+MAJOR+"."+MINOR+") rev "+REV+" build "+BUILD;
}
}

View File

@ -6,103 +6,110 @@ import java.lang.reflect.Method;
import net.minecraft.src.forge.Configuration; import net.minecraft.src.forge.Configuration;
import net.minecraft.src.forge.IOreHandler; import net.minecraft.src.forge.IOreHandler;
import net.minecraft.src.forge.MinecraftForge; import net.minecraft.src.forge.MinecraftForge;
import net.minecraft.src.forge.NetworkMod;
import cpw.mods.ironchest.BlockIronChest; import cpw.mods.ironchest.BlockIronChest;
import cpw.mods.ironchest.ChestChangerType; import cpw.mods.ironchest.ChestChangerType;
import cpw.mods.ironchest.IProxy; import cpw.mods.ironchest.IProxy;
import cpw.mods.ironchest.IronChestType; import cpw.mods.ironchest.IronChestType;
import cpw.mods.ironchest.ItemChestChanger; import cpw.mods.ironchest.ItemChestChanger;
import cpw.mods.ironchest.ItemIronChest; import cpw.mods.ironchest.ItemIronChest;
import cpw.mods.ironchest.PacketHandler;
import cpw.mods.ironchest.ServerClientProxy; import cpw.mods.ironchest.ServerClientProxy;
import cpw.mods.ironchest.TileEntityIronChest; import cpw.mods.ironchest.Version;
public class mod_IronChest extends BaseModMp { public class mod_IronChest extends NetworkMod {
public static BlockIronChest ironChestBlock; public static BlockIronChest ironChestBlock;
public static ItemChestChanger itemChestChanger; public static ItemChestChanger itemChestChanger;
public static IProxy proxy; public static IProxy proxy;
public static mod_IronChest instance;
@Override @Override
public String getVersion() { public String getVersion() {
return "3.1"; return Version.version();
} }
@Override @Override
public void load() { public void load() {
MinecraftForge.versionDetect("IronChest", 1, 4, 0); MinecraftForge.versionDetect("IronChest", 2, 0, 0);
proxy = ServerClientProxy.getProxy(); instance = this;
File cfgFile = new File(proxy.getMinecraftDir(), "config/IronChest.cfg"); proxy = ServerClientProxy.getProxy();
Configuration cfg = new Configuration(cfgFile); File cfgFile = new File(proxy.getMinecraftDir(), "config/IronChest.cfg");
try { Configuration cfg = new Configuration(cfgFile);
cfg.load(); try {
int bId=Integer.parseInt(cfg.getOrCreateBlockIdProperty("ironChests", 181).value); cfg.load();
if (bId>=256) { int bId = cfg.getOrCreateBlockIdProperty("ironChests", 181).getInt(181);
throw new RuntimeException(String.format("IronChest detected an invalid block id %s\n",bId)); if (bId >= 256) {
} throw new RuntimeException(String.format("IronChest detected an invalid block id %s\n", bId));
ironChestBlock = new BlockIronChest(bId); }
ChestChangerType.buildItems(cfg, 19501); ironChestBlock = new BlockIronChest(bId);
IronChestType.initGUIs(cfg); ChestChangerType.buildItems(cfg, 19501);
} catch (Exception e) { } catch (Exception e) {
ModLoader.getLogger().severe("IronChest was unable to load it's configuration successfully"); ModLoader.getLogger().severe("IronChest was unable to load it's configuration successfully");
e.printStackTrace(System.err); e.printStackTrace(System.err);
throw new RuntimeException(e); throw new RuntimeException(e);
} finally { } finally {
cfg.save(); cfg.save();
} }
ModLoader.registerBlock(ironChestBlock, ItemIronChest.class); ModLoader.registerBlock(ironChestBlock, ItemIronChest.class);
MinecraftForge.registerOreHandler(new IOreHandler() { MinecraftForge.registerOreHandler(new IOreHandler() {
@Override @Override
public void registerOre(String oreClass, ItemStack ore) { public void registerOre(String oreClass, ItemStack ore) {
if ("ingotCopper".equals(oreClass)) { if ("ingotCopper".equals(oreClass)) {
IronChestType.COPPER.addMat(ore); IronChestType.COPPER.addMat(ore);
IronChestType.generateRecipesForType(ironChestBlock, Block.chest, IronChestType.COPPER, ore); IronChestType.generateRecipesForType(ironChestBlock, Block.chest, IronChestType.COPPER, ore);
ChestChangerType.generateRecipe(IronChestType.COPPER); ChestChangerType.generateRecipe(IronChestType.COPPER);
} }
if ("ingotSilver".equals(oreClass)) { if ("ingotSilver".equals(oreClass)) {
IronChestType.SILVER.addMat(ore); IronChestType.SILVER.addMat(ore);
IronChestType.generateRecipesForType(ironChestBlock, ironChestBlock, IronChestType.SILVER, ore); IronChestType.generateRecipesForType(ironChestBlock, ironChestBlock, IronChestType.SILVER, ore);
ChestChangerType.generateRecipe(IronChestType.SILVER); ChestChangerType.generateRecipe(IronChestType.SILVER);
} }
if ("ingotRefinedIron".equals(oreClass)) { if ("ingotRefinedIron".equals(oreClass)) {
IronChestType.IRON.addMat(ore); IronChestType.IRON.addMat(ore);
IronChestType.generateRecipesForType(ironChestBlock, Block.chest, IronChestType.IRON, ore); IronChestType.generateRecipesForType(ironChestBlock, Block.chest, IronChestType.IRON, ore);
ChestChangerType.generateRecipe(IronChestType.IRON); ChestChangerType.generateRecipe(IronChestType.IRON);
} }
} }
}); });
proxy.registerTranslations(); proxy.registerTranslations();
proxy.registerTileEntities(); proxy.registerTileEntities();
ChestChangerType.generateRecipe(IronChestType.IRON); ChestChangerType.generateRecipe(IronChestType.IRON);
ChestChangerType.generateRecipe(IronChestType.GOLD); ChestChangerType.generateRecipe(IronChestType.GOLD);
ChestChangerType.generateRecipe(IronChestType.DIAMOND); ChestChangerType.generateRecipe(IronChestType.DIAMOND);
IronChestType.generateTieredRecipies(ironChestBlock); IronChestType.generateTieredRecipies(ironChestBlock);
proxy.registerRenderInformation(); MinecraftForge.setGuiHandler(this, proxy);
} MinecraftForge.registerConnectionHandler(new PacketHandler());
proxy.registerRenderInformation();
}
@Override
public void modsLoaded() {
try {
Class<?> equivexmaps = Class.forName("ee.EEMaps");
Method addEMC = equivexmaps.getMethod("addEMC", int.class, int.class, int.class);
Method addMeta = equivexmaps.getMethod("addMeta", int.class, int.class);
int[] chestEMCValues = new int[] { 8 * 8 + 256 * 8, 8 * 8 + 256 * 8 + 2048 * 8, 2 * 8192 + 8 * 8 + 256 * 8 + 2048 * 8 + 6, 85 * 8 + 8 * 8,
85 * 8 + 8 * 8 + 512 * 8, 2 * 8192 + 8 * 8 + 256 * 8 + 2048 * 8 + 6 + 8 };
for (IronChestType icType : IronChestType.values()) {
addEMC.invoke(null, ironChestBlock.blockID, icType.ordinal(), chestEMCValues[icType.ordinal()]);
}
addMeta.invoke(null, ironChestBlock.blockID, IronChestType.values().length - 1);
ModLoader.getLogger().fine("mod_IronChest registered chests with Equivalent Exchange");
} catch (Exception ex) {
ModLoader.getLogger().fine("mod_IronChest unable to load Equivalent Exchange integration");
}
}
@Override @Override
public void modsLoaded() { public boolean clientSideRequired() {
try { return true;
Class<?> equivexmaps=Class.forName("ee.EEMaps"); }
Method addEMC=equivexmaps.getMethod("addEMC",int.class,int.class,int.class);
Method addMeta=equivexmaps.getMethod("addMeta",int.class,int.class); @Override
int[] chestEMCValues=new int[] { 8*8+256*8, 8*8+256*8+2048*8, 2*8192+8*8+256*8+2048*8+6, 85*8+8*8, 85*8+8*8+512*8, 2*8192+8*8+256*8+2048*8+6+8 }; public boolean serverSideRequired() {
for (IronChestType icType : IronChestType.values()) { return true;
addEMC.invoke(null,ironChestBlock.blockID,icType.ordinal(),chestEMCValues[icType.ordinal()]); }
}
addMeta.invoke(null,ironChestBlock.blockID,IronChestType.values().length-1);
ModLoader.getLogger().fine("mod_IronChest registered chests with Equivalent Exchange");
} catch (Exception ex) {
ModLoader.getLogger().fine("mod_IronChest unable to load Equivalent Exchange integration");
}
}
public static void openGUI(EntityPlayer player, TileEntityIronChest te) {
proxy.showGUI(te,player);
}
public void handleTileEntityPacket(int x, int y, int z, int type, int[] intData, float[] floatData, String[] stringData) {
proxy.handleTileEntityPacket(x,y,z,type,intData,floatData,stringData);
}
} }

View File

@ -2,14 +2,13 @@ package cpw.mods.ironchest.server;
import java.io.File; import java.io.File;
import net.minecraft.src.BaseModMp; import net.minecraft.src.Container;
import net.minecraft.src.EntityItem; import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityPlayer; import net.minecraft.src.EntityPlayerMP;
import net.minecraft.src.ModLoader; import net.minecraft.src.ModLoader;
import net.minecraft.src.ModLoaderMp;
import net.minecraft.src.NBTTagCompound; import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.Packet; import net.minecraft.src.TileEntity;
import net.minecraft.src.mod_IronChest; import net.minecraft.src.World;
import cpw.mods.ironchest.ContainerIronChestBase; import cpw.mods.ironchest.ContainerIronChestBase;
import cpw.mods.ironchest.IProxy; import cpw.mods.ironchest.IProxy;
import cpw.mods.ironchest.IronChestType; import cpw.mods.ironchest.IronChestType;
@ -34,11 +33,6 @@ public class ServerProxy implements IProxy {
// NOOP on server // NOOP on server
} }
@Override
public void showGUI(TileEntityIronChest te, EntityPlayer player) {
ModLoader.openGUI(player, te.getType().guiId, te, new ContainerIronChestBase(player.inventory,te, te.getType(), 1, 1));
}
@Override @Override
public File getMinecraftDir() { public File getMinecraftDir() {
return new File("."); return new File(".");
@ -49,29 +43,26 @@ public class ServerProxy implements IProxy {
entityitem.item.setTagCompound(data); entityitem.item.setTagCompound(data);
} }
@Override
public void registerGUI(int guiId) {
// NOOP on server
}
@Override
public void handleTileEntityPacket(int x, int y, int z, int type, int[] intData, float[] floatData, String[] stringData) {
// NOOP on server
}
@Override
public Packet getDescriptionPacket(TileEntityIronChest tile) {
return ModLoaderMp.getTileEntityPacket(ModLoaderMp.getModInstance(mod_IronChest.class), tile.xCoord, tile.yCoord, tile.zCoord, tile.getType().ordinal(), tile.buildIntDataList(),null,null);
}
@Override
public void sendTileEntityUpdate(TileEntityIronChest tile) {
ModLoaderMp.sendTileEntityPacket(tile);
}
@Override @Override
public boolean isRemote() { public boolean isRemote() {
return false; return false;
} }
@Override
public Container getGuiContainer(int ID, EntityPlayerMP player, World world, int X, int Y, int Z) {
TileEntity te=world.getBlockTileEntity(X, Y, Z);
if (te!=null && te instanceof TileEntityIronChest) {
TileEntityIronChest icte=(TileEntityIronChest) te;
return new ContainerIronChestBase(player.inventory, icte, icte.getType(), 0, 0);
} else {
return null;
}
}
@Override
public World getCurrentWorld() {
// NOOP on server: there's lots
return null;
}
} }