diff --git a/src/main/java/net/mcft/copy/betterstorage/BetterStorage.java b/src/main/java/net/mcft/copy/betterstorage/BetterStorage.java index 2695372c..4d5d0efb 100644 --- a/src/main/java/net/mcft/copy/betterstorage/BetterStorage.java +++ b/src/main/java/net/mcft/copy/betterstorage/BetterStorage.java @@ -60,7 +60,6 @@ public void preInit(FMLPreInitializationEvent event) { globalConfig.load(); globalConfig.save(); - BetterStorage.log.info(Constants.modName + " will overwrite some of its own items. Don't worry, this is normal."); BetterStorageTiles.initialize(); BetterStorageItems.initialize(); diff --git a/src/main/java/net/mcft/copy/betterstorage/client/model/ModelLockableDoor.java b/src/main/java/net/mcft/copy/betterstorage/client/model/ModelLockableDoor.java new file mode 100644 index 00000000..b5decdf2 --- /dev/null +++ b/src/main/java/net/mcft/copy/betterstorage/client/model/ModelLockableDoor.java @@ -0,0 +1,45 @@ +package net.mcft.copy.betterstorage.client.model; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraftforge.common.util.ForgeDirection; + +public class ModelLockableDoor extends ModelBase { + + private ModelRenderer main; + + public ModelLockableDoor() { + + textureWidth = 64; + textureHeight = 64; + + main = new ModelRenderer(this, 0, 0); + + main.addBox(-1.5F, 0F, -14.5F, 3, 32, 16); + main.setRotationPoint(-6.5F, -8F, 6.5F); + } + + public void renderAll() { + float foo = 1 / 16.0F; + main.render(foo); + } + + public void setOrientation(ForgeDirection orientation) { + float x, y, z; + + switch (orientation) { + case WEST: x = -6.5F; y = -8F; z = 6.5F; break; + case EAST: x = 6.5F; y = -8F; z = -6.5F; break; + case SOUTH: x = -6.5F; y = -8F; z = -6.5F; break; + default: x = 6.5F; y = -8F; z = 6.5F; break; + } + + main.setRotationPoint(x, y, z); + } + + public void setRotation(float rotation) { + rotation = rotation / 360 * ((float)Math.PI * 2); + main.rotateAngleY = rotation; + } + +} diff --git a/src/main/java/net/mcft/copy/betterstorage/client/renderer/TileEntityBackpackRenderer.java b/src/main/java/net/mcft/copy/betterstorage/client/renderer/TileEntityBackpackRenderer.java index 4c268b09..a3a15d9b 100644 --- a/src/main/java/net/mcft/copy/betterstorage/client/renderer/TileEntityBackpackRenderer.java +++ b/src/main/java/net/mcft/copy/betterstorage/client/renderer/TileEntityBackpackRenderer.java @@ -55,7 +55,9 @@ public void renderTileEntityAt(TileEntityBackpack backpack, double x, double y, if ((backpack.stack != null) && (backpack.stack.isItemEnchanted())) { float f9 = (backpack.ticksExisted + partialTicks) / 3; + RenderUtils.bindTexture(Resources.enchantedEffect); + GL11.glEnable(GL11.GL_BLEND); GL11.glColor4f(0.5F, 0.5F, 0.5F, 1.0F); GL11.glDepthMask(false); diff --git a/src/main/java/net/mcft/copy/betterstorage/client/renderer/TileEntityLockableDoorRenderer.java b/src/main/java/net/mcft/copy/betterstorage/client/renderer/TileEntityLockableDoorRenderer.java new file mode 100644 index 00000000..5c184285 --- /dev/null +++ b/src/main/java/net/mcft/copy/betterstorage/client/renderer/TileEntityLockableDoorRenderer.java @@ -0,0 +1,73 @@ +package net.mcft.copy.betterstorage.client.renderer; + +import net.mcft.copy.betterstorage.attachment.LockAttachment; +import net.mcft.copy.betterstorage.client.model.ModelLockableDoor; +import net.mcft.copy.betterstorage.misc.Resources; +import net.mcft.copy.betterstorage.tile.entity.TileEntityLockableDoor; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +public class TileEntityLockableDoorRenderer extends TileEntitySpecialRenderer { + + private ModelLockableDoor model = new ModelLockableDoor(); + + public void renderTileEntityAt(TileEntityLockableDoor arg0, double x, double y, double z, float partialTicks) { + + GL11.glPushMatrix(); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glTranslated(x, y + 2.0, z + 1.0); + GL11.glScalef(1.0F, -1.0F, -1.0F); + GL11.glTranslated(0.5F, 0.5F, 0.5F); + + float angle = arg0.isOpen ? 1F : 0F; + + switch (arg0.orientation) { + case WEST: angle *= -90F; break; + case EAST: angle *= -90F; angle += 180F; break; + case SOUTH: angle *= -90F; angle -= 90F; break; + default: angle = 1 - angle; angle *= 90F; break; + } + + GL11.glPushMatrix(); + GL11.glRotatef(180F, 1, 0, 0); + GL11.glRotatef(90F, 0, 1, 0); + + switch (arg0.orientation) { + case WEST: GL11.glTranslatef(0.5F - 1.5F / 16F, -0.5F + 2 / 16F, -0.5F + 1.5F / 16F); break; + case EAST: GL11.glTranslatef(-0.5F + 1.5F / 16F, -0.5F + 2 / 16F, 0.5F - 1.5F / 16F); break; + case SOUTH: GL11.glTranslatef(-0.5F + 1.5F / 16F, -0.5F + 2 / 16F, -0.5F + 1.5F / 16F); break; + default: GL11.glTranslatef(0.5F - 1.5F / 16F, -0.5F + 2 / 16F, 0.5F - 1.5F / 16F); break; + } + + GL11.glRotatef(-angle, 0, 1, 0); + GL11.glTranslatef(-0.5F - 3F / 16F, 0F, 0F); + GL11.glScalef(1F, 1F, 2.5F); + + LockAttachment a = arg0.lockAttachment; + a.getRenderer().render(a, partialTicks); + GL11.glPopMatrix(); + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + bindTexture(Resources.textureLockableDoor); + + GL11.glPushMatrix(); + model.setOrientation(arg0.orientation); + model.setRotation(angle); + model.renderAll(); + GL11.glPopMatrix(); + + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glPopMatrix(); + } + + @Override + public void renderTileEntityAt(TileEntity arg0, double arg1, double arg2, double arg3, float arg4) { + renderTileEntityAt((TileEntityLockableDoor)arg0, arg1, arg2, arg3, arg4); + } + +} diff --git a/src/main/java/net/mcft/copy/betterstorage/config/GlobalConfig.java b/src/main/java/net/mcft/copy/betterstorage/config/GlobalConfig.java index 3b05fed4..f8ac5996 100644 --- a/src/main/java/net/mcft/copy/betterstorage/config/GlobalConfig.java +++ b/src/main/java/net/mcft/copy/betterstorage/config/GlobalConfig.java @@ -25,6 +25,7 @@ public class GlobalConfig extends Config { public static final String reinforcedLockerEnabled = "tile.reinforcedLocker"; public static final String craftingStationEnabled = "tile.craftingStation"; public static final String flintBlockEnabled = "tile.flintBlock"; + public static final String lockableDoorEnabled = "tile.lockableDoor"; // Items public static final String keyEnabled = "item.key"; @@ -91,6 +92,7 @@ public GlobalConfig(File file) { new BooleanSetting(this, reinforcedLockerEnabled, true); new BooleanSetting(this, craftingStationEnabled, true); new BooleanSetting(this, flintBlockEnabled, true); + new BooleanSetting(this, lockableDoorEnabled, true); // Items new BooleanSetting(this, keyEnabled, true); diff --git a/src/main/java/net/mcft/copy/betterstorage/content/BetterStorageTileEntities.java b/src/main/java/net/mcft/copy/betterstorage/content/BetterStorageTileEntities.java index c7141949..fc0eff12 100644 --- a/src/main/java/net/mcft/copy/betterstorage/content/BetterStorageTileEntities.java +++ b/src/main/java/net/mcft/copy/betterstorage/content/BetterStorageTileEntities.java @@ -7,6 +7,7 @@ import net.mcft.copy.betterstorage.tile.entity.TileEntityBackpack; import net.mcft.copy.betterstorage.tile.entity.TileEntityCardboardBox; import net.mcft.copy.betterstorage.tile.entity.TileEntityCraftingStation; +import net.mcft.copy.betterstorage.tile.entity.TileEntityLockableDoor; import net.mcft.copy.betterstorage.tile.entity.TileEntityLocker; import net.mcft.copy.betterstorage.tile.entity.TileEntityReinforcedChest; import net.mcft.copy.betterstorage.tile.entity.TileEntityReinforcedLocker; @@ -26,7 +27,8 @@ public static void register() { GameRegistry.registerTileEntity(TileEntityCardboardBox.class, Constants.containerCardboardBox); GameRegistry.registerTileEntity(TileEntityReinforcedLocker.class, Constants.containerReinforcedLocker); GameRegistry.registerTileEntity(TileEntityCraftingStation.class, Constants.containerCraftingStation); - + GameRegistry.registerTileEntity(TileEntityLockableDoor.class, Constants.lockableDoor); + Addon.registerTileEntitesAll(); } diff --git a/src/main/java/net/mcft/copy/betterstorage/content/BetterStorageTiles.java b/src/main/java/net/mcft/copy/betterstorage/content/BetterStorageTiles.java index f5a320c0..098cc774 100644 --- a/src/main/java/net/mcft/copy/betterstorage/content/BetterStorageTiles.java +++ b/src/main/java/net/mcft/copy/betterstorage/content/BetterStorageTiles.java @@ -8,6 +8,7 @@ import net.mcft.copy.betterstorage.tile.TileCraftingStation; import net.mcft.copy.betterstorage.tile.TileEnderBackpack; import net.mcft.copy.betterstorage.tile.TileFlintBlock; +import net.mcft.copy.betterstorage.tile.TileLockableDoor; import net.mcft.copy.betterstorage.tile.TileLocker; import net.mcft.copy.betterstorage.tile.TileReinforcedChest; import net.mcft.copy.betterstorage.tile.TileReinforcedLocker; @@ -26,6 +27,7 @@ public final class BetterStorageTiles { public static TileReinforcedLocker reinforcedLocker; public static TileCraftingStation craftingStation; public static TileFlintBlock flintBlock; + public static TileLockableDoor lockableDoor; private BetterStorageTiles() { } @@ -41,6 +43,7 @@ public static void initialize() { reinforcedLocker = MiscUtils.conditionalNew(TileReinforcedLocker.class, GlobalConfig.reinforcedLockerEnabled); craftingStation = MiscUtils.conditionalNew(TileCraftingStation.class, GlobalConfig.craftingStationEnabled); flintBlock = MiscUtils.conditionalNew(TileFlintBlock.class, GlobalConfig.flintBlockEnabled); + lockableDoor = MiscUtils.conditionalNew(TileLockableDoor.class, GlobalConfig.lockableDoorEnabled); Addon.initializeTilesAll(); diff --git a/src/main/java/net/mcft/copy/betterstorage/misc/Constants.java b/src/main/java/net/mcft/copy/betterstorage/misc/Constants.java index 199e36af..39a954f7 100644 --- a/src/main/java/net/mcft/copy/betterstorage/misc/Constants.java +++ b/src/main/java/net/mcft/copy/betterstorage/misc/Constants.java @@ -23,6 +23,7 @@ public final class Constants { public static final String containerThaumcraftBackpack = "container." + modId + ".thaumcraftBackpack"; public static final String containerThaumiumChest = "container." + modId + ".thaumiumChest"; + public static final String lockableDoor = modId + ".lockableDoor"; private Constants() { } diff --git a/src/main/java/net/mcft/copy/betterstorage/misc/Resources.java b/src/main/java/net/mcft/copy/betterstorage/misc/Resources.java index 76623682..b5cbe049 100644 --- a/src/main/java/net/mcft/copy/betterstorage/misc/Resources.java +++ b/src/main/java/net/mcft/copy/betterstorage/misc/Resources.java @@ -7,7 +7,8 @@ @SideOnly(Side.CLIENT) public final class Resources { - public static final ResourceLocation textureEmpty = new BetterStorageResource("textures/empty.png"); + public static final ResourceLocation textureEmpty = new BetterStorageResource("textures/empty.png"); + public static final ResourceLocation enchantedItem = new ResourceLocation("minecraft", "textures/misc/enchanted_item_glint.png"); public static final ResourceLocation enchantedEffect = new ResourceLocation("textures/misc/enchanted_item_glint.png"); @@ -25,7 +26,8 @@ public final class Resources { public static final ResourceLocation textureCardboardArmor = new BetterStorageResource("textures/models/cardboardArmor.png"); public static final ResourceLocation textureCardboardLeggins = new BetterStorageResource("textures/models/cardboardArmor_leggings.png"); public static final ResourceLocation textureCluckOverlay = new BetterStorageResource("textures/models/cluck.png"); - + public static final ResourceLocation textureLockableDoor = new BetterStorageResource("textures/models/lockableDoor.png"); + public static final ResourceLocation modelLocker = new BetterStorageResource("models/locker.obj"); public static final ResourceLocation modelLockerLarge = new BetterStorageResource("models/locker_large.obj"); diff --git a/src/main/java/net/mcft/copy/betterstorage/proxy/ClientProxy.java b/src/main/java/net/mcft/copy/betterstorage/proxy/ClientProxy.java index 4158cda7..99da00ae 100644 --- a/src/main/java/net/mcft/copy/betterstorage/proxy/ClientProxy.java +++ b/src/main/java/net/mcft/copy/betterstorage/proxy/ClientProxy.java @@ -15,6 +15,7 @@ import net.mcft.copy.betterstorage.client.renderer.RenderFrienderman; import net.mcft.copy.betterstorage.client.renderer.TileEntityArmorStandRenderer; import net.mcft.copy.betterstorage.client.renderer.TileEntityBackpackRenderer; +import net.mcft.copy.betterstorage.client.renderer.TileEntityLockableDoorRenderer; import net.mcft.copy.betterstorage.client.renderer.TileEntityLockerRenderer; import net.mcft.copy.betterstorage.client.renderer.TileEntityReinforcedChestRenderer; import net.mcft.copy.betterstorage.content.BetterStorageItems; @@ -27,6 +28,7 @@ import net.mcft.copy.betterstorage.tile.TileArmorStand; import net.mcft.copy.betterstorage.tile.entity.TileEntityArmorStand; import net.mcft.copy.betterstorage.tile.entity.TileEntityBackpack; +import net.mcft.copy.betterstorage.tile.entity.TileEntityLockableDoor; import net.mcft.copy.betterstorage.tile.entity.TileEntityLocker; import net.mcft.copy.betterstorage.tile.entity.TileEntityReinforcedChest; import net.mcft.copy.betterstorage.tile.entity.TileEntityReinforcedLocker; @@ -40,6 +42,7 @@ import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; @@ -70,6 +73,7 @@ public class ClientProxy extends CommonProxy { public static int armorStandRenderId; public static int backpackRenderId; public static int reinforcedLockerRenderId; + public static int lockableDoorRenderId; public static final Map, BetterStorageRenderingHandler> renderingHandlers = new HashMap, BetterStorageRenderingHandler>(); @@ -101,6 +105,7 @@ private void registerRenderers() { armorStandRenderId = registerTileEntityRenderer(TileEntityArmorStand.class, new TileEntityArmorStandRenderer(), false, 0, 1, 0); backpackRenderId = registerTileEntityRenderer(TileEntityBackpack.class, new TileEntityBackpackRenderer(), true, -160, 1.5F, 0.14F); reinforcedLockerRenderId = registerTileEntityRenderer(TileEntityReinforcedLocker.class, new TileEntityLockerRenderer()); + lockableDoorRenderId = registerTileEntityRenderer(TileEntityLockableDoor.class, new TileEntityLockableDoorRenderer(), false, 0, 1, 0); Addon.registerRenderersAll(); @@ -135,6 +140,7 @@ public void drawBlockHighlight(DrawBlockHighlightEvent event) { EntityPlayer player = event.player; World world = player.worldObj; MovingObjectPosition target = WorldUtils.rayTrace(player, event.partialTicks); + if ((target == null) || (target.typeOfHit != MovingObjectType.BLOCK)) return; int x = target.blockX; int y = target.blockY; @@ -146,6 +152,8 @@ public void drawBlockHighlight(DrawBlockHighlightEvent event) { if (block instanceof TileArmorStand) box = getArmorStandHighlightBox(player, world, x, y, z, target.hitVec); + else if (block == Blocks.iron_door) + box = getIronDoorHightlightBox(player, world, x, y, z, target.hitVec, block); else if (tileEntity instanceof IHasAttachments) box = getAttachmentPointsHighlightBox(player, tileEntity, target); @@ -196,7 +204,7 @@ else if (tileEntity instanceof IHasAttachments) event.setCanceled(true); } - + private AxisAlignedBB getArmorStandHighlightBox(EntityPlayer player, World world, int x, int y, int z, Vec3 hitVec) { int metadata = world.getBlockMetadata(x, y, z); @@ -266,7 +274,9 @@ public void onRenderPlayerSpecialsPre(RenderPlayerEvent.Specials.Pre event) { if (backpack.isItemEnchanted()) { float f9 = player.ticksExisted + partial; + RenderUtils.bindTexture(Resources.enchantedEffect); + GL11.glEnable(GL11.GL_BLEND); GL11.glColor4f(0.5F, 0.5F, 0.5F, 1.0F); GL11.glDepthFunc(GL11.GL_EQUAL); diff --git a/src/main/java/net/mcft/copy/betterstorage/proxy/CommonProxy.java b/src/main/java/net/mcft/copy/betterstorage/proxy/CommonProxy.java index d13bfbea..ea214690 100644 --- a/src/main/java/net/mcft/copy/betterstorage/proxy/CommonProxy.java +++ b/src/main/java/net/mcft/copy/betterstorage/proxy/CommonProxy.java @@ -3,14 +3,17 @@ import net.mcft.copy.betterstorage.attachment.EnumAttachmentInteraction; import net.mcft.copy.betterstorage.attachment.IHasAttachments; import net.mcft.copy.betterstorage.content.BetterStorageItems; +import net.mcft.copy.betterstorage.content.BetterStorageTiles; import net.mcft.copy.betterstorage.entity.EntityCluckington; import net.mcft.copy.betterstorage.item.IDyeableItem; import net.mcft.copy.betterstorage.item.ItemBucketSlime; import net.mcft.copy.betterstorage.item.cardboard.ICardboardItem; import net.mcft.copy.betterstorage.item.cardboard.ItemCardboardSheet; +import net.mcft.copy.betterstorage.misc.SetBlockFlag; import net.mcft.copy.betterstorage.misc.handlers.BackpackHandler; import net.mcft.copy.betterstorage.misc.handlers.CraftingHandler; import net.mcft.copy.betterstorage.tile.crate.CratePileCollection; +import net.mcft.copy.betterstorage.tile.entity.TileEntityLockableDoor; import net.mcft.copy.betterstorage.utils.StackUtils; import net.mcft.copy.betterstorage.utils.WorldUtils; import net.minecraft.block.Block; @@ -21,8 +24,12 @@ import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.event.entity.player.EntityInteractEvent; import net.minecraftforge.event.entity.player.PlayerEvent.BreakSpeed; import net.minecraftforge.event.entity.player.PlayerInteractEvent; @@ -111,6 +118,66 @@ public void onPlayerInteract(PlayerInteractEvent event) { !ItemCardboardSheet.isEffective(holding)) event.useItem = Result.DENY; + if (!world.isRemote && BetterStorageTiles.lockableDoor != null && rightClick && block == Blocks.iron_door) { + + MovingObjectPosition target = WorldUtils.rayTrace(player, 1F); + if(target != null && getIronDoorHightlightBox(player, world, x, y, z, target.hitVec, block) != null) { + + int meta = world.getBlockMetadata(x, y, z); + if (meta >= 8) { + y -= 1; + meta = world.getBlockMetadata(x, y, z); + } + + int rotation = meta & 3; + ForgeDirection orientation = rotation == 0 ? ForgeDirection.WEST : rotation == 1 ? ForgeDirection.NORTH : rotation == 2 ? ForgeDirection.EAST : ForgeDirection.SOUTH; + + world.setBlock(x, y, z, BetterStorageTiles.lockableDoor, 0, SetBlockFlag.SEND_TO_CLIENT); + world.setBlock(x, y + 1, z, BetterStorageTiles.lockableDoor, 1, SetBlockFlag.SEND_TO_CLIENT); + + TileEntityLockableDoor te = WorldUtils.get(world, x, y, z, TileEntityLockableDoor.class); + te.orientation = orientation; + te.setLock(holding); + + player.inventory.setInventorySlotContents(player.inventory.currentItem, null); + } + } + } + + protected AxisAlignedBB getIronDoorHightlightBox(EntityPlayer player, World world, int x, int y, int z, Vec3 hitVec, Block block) { + if(!StackUtils.isLock(player.getCurrentEquippedItem())) return null; + + int meta = world.getBlockMetadata(x, y, z); + if(meta >= 8) { + y -= 1; + meta = world.getBlockMetadata(x, y, z); + } + + boolean isOpen = (meta & 4) == 4; + int rotation = (meta & 3); + + //TODO Maybe change the bounding box of the doors somehow to match LockableDoor. + AxisAlignedBB box; + switch(rotation) { + case 0 : + if(!isOpen) box = AxisAlignedBB.getAABBPool().getAABB(x - 0.005 / 16F, y + 14.5 / 16F, z + 10 / 16F, x + 3.005 / 16F, y + 20.5 / 16F, z + 15 / 16F); + else box = AxisAlignedBB.getAABBPool().getAABB(x + 10 / 16F, y + 14.5 / 16F, z - 0.005 / 16F, x + 15 / 16F, y + 20.5 / 16F, z + 3.005 / 16F); + break; + case 1 : + if(!isOpen) box = AxisAlignedBB.getAABBPool().getAABB(x + 1 / 16F, y + 14.5 / 16F, z - 0.005 / 16F, x + 6 / 16F, y + 20.5 / 16F, z + 3.005 / 16F); + else box = AxisAlignedBB.getAABBPool().getAABB(x + 12.995 / 16F, y + 14.5 / 16F, z + 10 / 16F, x + 16.005 / 16F, y + 20.5 / 16F, z + 15 / 16F); + break; + case 2 : + if(!isOpen) box = AxisAlignedBB.getAABBPool().getAABB(x + 12.995 / 16F, y + 14.5 / 16F, z + 1 / 16F, x + 16.005 / 16F, y + 20.5 / 16F, z + 6 / 16F); + else box = AxisAlignedBB.getAABBPool().getAABB(x + 1 / 16F, y + 14.5 / 16F, z + 12.995 / 16F, x + 6 / 16F, y + 20.5 / 16F, z + 16.005 / 16F); + break; + default : + if(!isOpen) box = AxisAlignedBB.getAABBPool().getAABB(x + 10 / 16F, y + 14.5 / 16F, z + 12.995 / 16F, x + 15 / 16F, y + 20.5 / 16F, z + 16.005 / 16F); + else box = AxisAlignedBB.getAABBPool().getAABB(x + 0.005 / 16F, y + 14.5 / 16F, z + 1 / 16F, x + 3.005 / 16F, y + 20.5 / 16F, z + 6 / 16F); + break; + } + + return box.isVecInside(hitVec) ? box : null; } @SubscribeEvent diff --git a/src/main/java/net/mcft/copy/betterstorage/tile/TileLockableDoor.java b/src/main/java/net/mcft/copy/betterstorage/tile/TileLockableDoor.java new file mode 100644 index 00000000..30a1626c --- /dev/null +++ b/src/main/java/net/mcft/copy/betterstorage/tile/TileLockableDoor.java @@ -0,0 +1,213 @@ +package net.mcft.copy.betterstorage.tile; + +import java.util.Random; + +import net.mcft.copy.betterstorage.api.BetterStorageEnchantment; +import net.mcft.copy.betterstorage.attachment.Attachments; +import net.mcft.copy.betterstorage.attachment.EnumAttachmentInteraction; +import net.mcft.copy.betterstorage.attachment.IHasAttachments; +import net.mcft.copy.betterstorage.proxy.ClientProxy; +import net.mcft.copy.betterstorage.tile.entity.TileEntityLockableDoor; +import net.mcft.copy.betterstorage.utils.WorldUtils; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public class TileLockableDoor extends TileBetterStorage { + + public TileLockableDoor() { + super(Material.wood); + + setCreativeTab(null); + setHardness(8.0F); + setResistance(20.0F); + setStepSound(soundTypeWood); + setBlockBounds(0F, 0F, 0F, 3 / 16F, 2F, 1F); + setHarvestLevel("axe", 2); + } + + @Override + public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) { + int metadata = world.getBlockMetadata(x, y, z); + float offset = metadata == 0 ? 0F : -1F; + TileEntityLockableDoor te = WorldUtils.get(world, x, y + (int)offset, z, TileEntityLockableDoor.class); + + if (te == null) { + setBlockBounds(0F, 0F + offset, 0F, 3 / 16F, 2F + offset, 1F); + return; + } + + switch (te.orientation) { + case WEST: + if (te.isOpen) setBlockBounds(0F, 0F + offset, 1 / 16F, 1F, 2F + offset, 2 / 16F); + else setBlockBounds(1 / 16F, 0F + offset, 0F, 2 / 16F, 2F + offset, 1F); + break; + case EAST: + if (te.isOpen) setBlockBounds(0F, 0F + offset, 14 / 16F, 1F, 2F + offset, 15 / 16F); + else setBlockBounds(14 / 16F, 0F + offset, 0F, 15 / 16F, 2F + offset, 1F); + break; + case SOUTH: + if (te.isOpen) setBlockBounds(1 / 16F, 0F + offset, 0F, 2 / 16F, 2F + offset, 1F); + else setBlockBounds(0F, 0F + offset, 14 / 16F, 1F, 2F + offset, 15 / 16F); + break; + default: + if (te.isOpen) setBlockBounds(14 / 16F, 0F + offset, 0F, 15 / 16F, 2F + offset, 1F); + else setBlockBounds(0F, 0F + offset, 1 / 16F, 1F, 2F + offset, 2 / 16F); + break; + } + } + + @Override + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { + setBlockBoundsBasedOnState(world, x, y, z); + return super.getCollisionBoundingBoxFromPool(world, x, y, z); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister iconRegister) { + blockIcon = iconRegister.registerIcon("door_iron_lower"); + } + + @Override + public float getBlockHardness(World world, int x, int y, int z) { + if (world.getBlockMetadata(x, y, z) > 0) y -= 1; + TileEntityLockableDoor lockable = WorldUtils.get(world, x, y, z, TileEntityLockableDoor.class); + if ((lockable != null) && (lockable.getLock() != null)) return -1; + else return super.getBlockHardness(world, x, y, z); + } + + @Override + public float getExplosionResistance(Entity entity, World world, int x, int y, int z, double explosionX, double explosionY, double explosionZ) { + if (world.getBlockMetadata(x, y, z) > 0) y -= 1; + float modifier = 1.0F; + TileEntityLockableDoor lockable = WorldUtils.get(world, x, y, z, TileEntityLockableDoor.class); + if (lockable != null) { + int persistance = BetterStorageEnchantment.getLevel(lockable.getLock(), "persistance"); + if (persistance > 0) modifier += Math.pow(2, persistance); + } + return super.getExplosionResistance(entity) * modifier; + } + + @Override + public boolean onBlockEventReceived(World world, int x, int y, int z, int eventId, int eventPar) { + TileEntity te = world.getTileEntity(x, y, z); + return ((te != null) ? te.receiveClientEvent(eventId, eventPar) : false); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { + //TODO It will place a block in front of the bottom block when shift clicking the upper block. + if (world.getBlockMetadata(x, y, z) > 0) y -= 1; + TileEntityLockableDoor te = WorldUtils.get(world, x, y, z, TileEntityLockableDoor.class); + return te.onBlockActivated(world, x, y, z, player, side, hitX, hitY, hitZ); + } + + @Override + public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player) { + if (world.getBlockMetadata(x, y, z) > 0) y -= 1; + Attachments attachments = WorldUtils.get(world, x, y, z, IHasAttachments.class).getAttachments(); + boolean abort = attachments.interact(WorldUtils.rayTrace(player, 1.0F), player, EnumAttachmentInteraction.attack); + } + + @Override + public MovingObjectPosition collisionRayTrace(World world, int x, int y, int z, Vec3 start, Vec3 end) { + int metadata = world.getBlockMetadata(x, y, z); + if (metadata > 0) y -= 1; + IHasAttachments te = WorldUtils.get(world, x, y, z, IHasAttachments.class); + return te != null ? te.getAttachments().rayTrace(world, x, y, z, start, end) : super.collisionRayTrace(world, x, y, z, start, end); + } + + @Override + public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z) { + return new ItemStack(Items.iron_door); + } + + @Override + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + return world.setBlockToAir(x, y, z); + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + if (meta > 0) return; + super.breakBlock(world, x, y, z, block, meta); + } + + @Override + public void onNeighborBlockChange(World world, int x, int y, int z, Block block) { + int metadata = world.getBlockMetadata(x, y, z); + int targetY = y + ((metadata == 0) ? 1 : -1); + int targetMeta = ((metadata == 0) ? 1 : 0); + if (world.getBlock(x, y - 1, z) == Blocks.air && metadata == 0) world.setBlockToAir(x, y, z); + if ((world.getBlock(x, targetY, z) == this) && (world.getBlockMetadata(x, targetY, z) == targetMeta)) return; + world.setBlockToAir(x, y, z); + if (metadata == 0) WorldUtils.spawnItem(world, x, y, z, new ItemStack(Items.iron_door)); + } + + @Override + public void onBlockPreDestroy(World world, int x, int y, int z, int meta) { + if(meta == 0) { + TileEntityLockableDoor te = WorldUtils.get(world, x, y, z, TileEntityLockableDoor.class); + WorldUtils.dropStackFromBlock(te, te.getLock()); + te.setLockWithUpdate(null); + } + super.onBlockPreDestroy(world, x, y, z, meta); + } + + @Override + public boolean isOpaqueCube() { return false; } + @Override + public boolean renderAsNormalBlock() { return false; } + + @Override + public int quantityDropped(int meta, int fortune, Random random) { + return ((meta == 0) ? 1 : 0); + } + + @Override + public boolean canProvidePower() { return true; } + + @Override + public int isProvidingWeakPower(IBlockAccess world, int x, int y, int z, int side) { + if (world.getBlockMetadata(x, y, z) > 0) y -= 1; + TileEntityLockableDoor te = WorldUtils.get(world, x, y, z, TileEntityLockableDoor.class); + return te == null ? 0 : (te.isPowered() ? 15 : 0); + } + @Override + public int isProvidingStrongPower(IBlockAccess world, int x, int y, int z, int side) { + return isProvidingWeakPower(world, x, y, z, side); + } + + @Override + public void updateTick(World world, int x, int y, int z, Random random) { + if(world.getBlockMetadata(x, y, z) != 0) return; + WorldUtils.get(world, x, y, z, TileEntityLockableDoor.class).setPowered(false); + } + + @Override + @SideOnly(Side.CLIENT) + public int getRenderType() { return ClientProxy.lockableDoorRenderId; } + + @Override + public TileEntity createTileEntity(World world, int metadata) { + return ((metadata == 0) ? new TileEntityLockableDoor() : null); + } + + @Override + public boolean hasTileEntity(int metadata) { return true; } + +} diff --git a/src/main/java/net/mcft/copy/betterstorage/tile/entity/TileEntityLockableDoor.java b/src/main/java/net/mcft/copy/betterstorage/tile/entity/TileEntityLockableDoor.java new file mode 100644 index 00000000..1891a058 --- /dev/null +++ b/src/main/java/net/mcft/copy/betterstorage/tile/entity/TileEntityLockableDoor.java @@ -0,0 +1,195 @@ +package net.mcft.copy.betterstorage.tile.entity; + +import net.mcft.copy.betterstorage.api.lock.EnumLockInteraction; +import net.mcft.copy.betterstorage.api.lock.ILock; +import net.mcft.copy.betterstorage.api.lock.ILockable; +import net.mcft.copy.betterstorage.attachment.Attachments; +import net.mcft.copy.betterstorage.attachment.IHasAttachments; +import net.mcft.copy.betterstorage.attachment.LockAttachment; +import net.mcft.copy.betterstorage.misc.SetBlockFlag; +import net.mcft.copy.betterstorage.utils.WorldUtils; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public class TileEntityLockableDoor extends TileEntity implements ILockable, IHasAttachments { + + private Attachments attachments = new Attachments(this); + public LockAttachment lockAttachment; + public ForgeDirection orientation = ForgeDirection.NORTH; + + private boolean powered = false; + private boolean swing = false; + + public boolean isOpen = false; + + public TileEntityLockableDoor() { + + lockAttachment = attachments.add(LockAttachment.class); + lockAttachment.setScale(0.5F, 1.5F); + } + + @Override + @SideOnly(Side.CLIENT) + public AxisAlignedBB getRenderBoundingBox() { + return WorldUtils.getAABB(this, 0, 0, 0, 0, 1, 0); + } + + private void updateLockPosition() { + //Maybe we should use the orientation that the attachment has by itself. + switch (orientation) { + case WEST: + if (isOpen) lockAttachment.setBox(12.5, -1.5, 1.5, 5, 6, 3); + else lockAttachment.setBox(1.5, -1.5, 12.5, 3, 6, 5); + break; + case EAST: + if (isOpen) lockAttachment.setBox(3.5, -1.5, 14.5, 5, 6, 3); + else lockAttachment.setBox(14.5, -1.5, 3.5, 3, 6, 5); + break; + case SOUTH: + if (isOpen) lockAttachment.setBox(1.5, -1.5, 3.5, 3, 6, 5); + else lockAttachment.setBox(12.5, -1.5, 14.5, 5, 6, 3); + break; + default: + if (isOpen) lockAttachment.setBox(14.5, -1.5, 12.5, 3, 6, 5); + else lockAttachment.setBox(3.5, -1.5, 1.5, 5, 6, 3); + break; + } + } + + @Override + public Attachments getAttachments() { + return attachments; + } + + @Override + public ItemStack getLock() { + return lockAttachment.getItem(); + } + + @Override + public boolean isLockValid(ItemStack lock) { + return (lock == null) || (lock.getItem() instanceof ILock); + } + + @Override + public void setLock(ItemStack lock) { + // Turn it back into a normal iron door + if(lock == null) { + lockAttachment.setItem(null); + int rotation = orientation == ForgeDirection.WEST ? 0 : orientation == ForgeDirection.NORTH ? 1 : orientation == ForgeDirection.EAST ? 2 : 3; + worldObj.setBlock(xCoord, yCoord, zCoord, Blocks.iron_door, rotation, SetBlockFlag.SEND_TO_CLIENT); + worldObj.setBlock(xCoord, yCoord + 1, zCoord, Blocks.iron_door, 8, SetBlockFlag.SEND_TO_CLIENT); + worldObj.notifyBlockChange(xCoord, yCoord, zCoord, Blocks.iron_door); + worldObj.notifyBlockChange(xCoord, yCoord + 1, zCoord, Blocks.iron_door); + } else setLockWithUpdate(lock); + } + + public void setLockWithUpdate(ItemStack lock) { + lockAttachment.setItem(lock); + updateLockPosition(); + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + markDirty(); + } + + @Override + public boolean canUse(EntityPlayer player) { + return isOpen; + } + + @Override + public void useUnlocked(EntityPlayer player) { + isOpen = !isOpen; + player.worldObj.addBlockEvent(xCoord, yCoord, zCoord, getBlockType(), 0, isOpen ? 1 : 0); + updateLockPosition(); + } + + @Override + public void applyTrigger() { + setPowered(true); + } + + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { + if(world.isRemote) return true; + if(canUse(player)) useUnlocked(player); + else ((ILock)getLock().getItem()).applyEffects(getLock(), this, player, EnumLockInteraction.OPEN); + return true; + } + + @Override + public boolean receiveClientEvent(int eventID, int par) { + worldObj.playAuxSFX(1003, xCoord, yCoord, zCoord, 0); + swing = true; + isOpen = par == 1; + updateLockPosition(); + return true; + } + + @Override + public void updateEntity() + { + attachments.update(); + } + + @Override + public void readFromNBT(NBTTagCompound compound) { + super.readFromNBT(compound); + isOpen = compound.getBoolean("isOpen"); + orientation = ForgeDirection.getOrientation(compound.getByte("orientation")); + if (compound.hasKey("lock")) lockAttachment.setItem(ItemStack.loadItemStackFromNBT(compound.getCompoundTag("lock"))); + updateLockPosition(); + } + + @Override + public void writeToNBT(NBTTagCompound compound) { + super.writeToNBT(compound); + compound.setBoolean("isOpen", isOpen); + compound.setByte("orientation", (byte) orientation.ordinal()); + if (lockAttachment.getItem() != null) compound.setTag("lock", lockAttachment.getItem().writeToNBT(new NBTTagCompound())); + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound compound = new NBTTagCompound(); + compound.setBoolean("isOpen", isOpen); + compound.setByte("orientation", (byte) orientation.ordinal()); + if (lockAttachment.getItem() != null) compound.setTag("lock", lockAttachment.getItem().writeToNBT(new NBTTagCompound())); + return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, compound); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + super.onDataPacket(net, pkt); + NBTTagCompound compound = pkt.func_148857_g(); + if (!compound.hasKey("lock")) lockAttachment.setItem(null); + else lockAttachment.setItem(ItemStack.loadItemStackFromNBT(compound.getCompoundTag("lock"))); + orientation = ForgeDirection.getOrientation(compound.getByte("orientation")); + isOpen = compound.getBoolean("isOpen"); + updateLockPosition(); + } + + public boolean isPowered() { + return powered; + } + + public void setPowered(boolean powered) { + + if (this.powered == powered) return; + this.powered = powered; + + if (powered) worldObj.scheduleBlockUpdate(xCoord, yCoord, zCoord, getBlockType(), 10); + WorldUtils.notifyBlocksAround(worldObj, xCoord, yCoord, zCoord); + WorldUtils.notifyBlocksAround(worldObj, xCoord, yCoord + 1, zCoord); + } + +} diff --git a/src/main/java/net/mcft/copy/betterstorage/utils/WorldUtils.java b/src/main/java/net/mcft/copy/betterstorage/utils/WorldUtils.java index 5461dc43..04562fa6 100644 --- a/src/main/java/net/mcft/copy/betterstorage/utils/WorldUtils.java +++ b/src/main/java/net/mcft/copy/betterstorage/utils/WorldUtils.java @@ -6,6 +6,7 @@ import net.mcft.copy.betterstorage.container.ContainerBetterStorage; import net.mcft.copy.betterstorage.inventory.InventoryTileEntity; import net.mcft.copy.betterstorage.tile.entity.TileEntityContainer; +import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.item.EntityItem; @@ -136,6 +137,18 @@ public static int syncPlayersUsing(TileEntityContainer te, int numUsingPlayers) return syncPlayersUsing(te, numUsingPlayers, te.getPlayerInventory()); } + /** This will perform a {@link World#notifyBlockOfNeighborChange()} on every adjacent block including the block at x|y|z.*/ + public static void notifyBlocksAround(World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + world.notifyBlocksOfNeighborChange(x, y, z, block); + world.notifyBlocksOfNeighborChange(x + 1, y, z, block); + world.notifyBlocksOfNeighborChange(x - 1, y, z, block); + world.notifyBlocksOfNeighborChange(x, y + 1, z, block); + world.notifyBlocksOfNeighborChange(x, y - 1, z, block); + world.notifyBlocksOfNeighborChange(x, y, z + 1, block); + world.notifyBlocksOfNeighborChange(x, y, z - 1, block); + } + // Misc functions public static MovingObjectPosition rayTrace(EntityPlayer player, float partialTicks) { diff --git a/src/main/resources/assets/betterstorage/textures/models/lockableDoor.png b/src/main/resources/assets/betterstorage/textures/models/lockableDoor.png new file mode 100644 index 00000000..9399bdec Binary files /dev/null and b/src/main/resources/assets/betterstorage/textures/models/lockableDoor.png differ