Add bookshelves
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
package electroblob.wizardry;
|
||||
|
||||
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.inventory.ContainerBookshelf;
|
||||
import electroblob.wizardry.inventory.ContainerPortableWorkbench;
|
||||
import electroblob.wizardry.item.ItemSpellBook;
|
||||
import electroblob.wizardry.item.ItemWizardHandbook;
|
||||
import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.tileentity.ContainerPortableWorkbench;
|
||||
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
|
||||
import electroblob.wizardry.tileentity.TileEntityBookshelf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -20,40 +22,73 @@ public class WizardryGuiHandler implements IGuiHandler {
|
||||
public static final int ARCANE_WORKBENCH = nextGuiId++;
|
||||
public static final int WIZARD_HANDBOOK = nextGuiId++;
|
||||
public static final int PORTABLE_CRAFTING = nextGuiId++;
|
||||
public static final int BOOKSHELF = nextGuiId++;
|
||||
|
||||
@Override
|
||||
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z){
|
||||
|
||||
if(id == ARCANE_WORKBENCH){
|
||||
|
||||
TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z));
|
||||
|
||||
if(tileEntity instanceof TileEntityArcaneWorkbench){
|
||||
return new ContainerArcaneWorkbench(player.inventory, (TileEntityArcaneWorkbench)tileEntity);
|
||||
}
|
||||
|
||||
}else if(id == PORTABLE_CRAFTING){
|
||||
return new ContainerPortableWorkbench(player.inventory, world, new BlockPos(x, y, z));
|
||||
|
||||
}else if(id == BOOKSHELF){
|
||||
|
||||
TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z));
|
||||
|
||||
if(tileEntity instanceof TileEntityBookshelf){
|
||||
return new ContainerBookshelf(player.inventory, (TileEntityBookshelf)tileEntity);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z){
|
||||
|
||||
if(id == ARCANE_WORKBENCH){
|
||||
|
||||
TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z));
|
||||
|
||||
if(tileEntity instanceof TileEntityArcaneWorkbench){
|
||||
return new electroblob.wizardry.client.gui.GuiArcaneWorkbench(player.inventory,
|
||||
(TileEntityArcaneWorkbench)tileEntity);
|
||||
}
|
||||
|
||||
}else if(id == WIZARD_HANDBOOK && (player.getHeldItemMainhand().getItem() instanceof ItemWizardHandbook
|
||||
|| player.getHeldItemOffhand().getItem() instanceof ItemWizardHandbook)){
|
||||
|
||||
return new electroblob.wizardry.client.gui.handbook.GuiWizardHandbook();
|
||||
|
||||
}else if(id == SPELL_BOOK){
|
||||
|
||||
if(player.getHeldItemMainhand().getItem() instanceof ItemSpellBook){
|
||||
return new electroblob.wizardry.client.gui.GuiSpellBook(player.getHeldItemMainhand());
|
||||
}else if(player.getHeldItemOffhand().getItem() instanceof ItemSpellBook){
|
||||
return new electroblob.wizardry.client.gui.GuiSpellBook(player.getHeldItemOffhand());
|
||||
}
|
||||
|
||||
}else if(id == PORTABLE_CRAFTING){
|
||||
return new electroblob.wizardry.client.gui.GuiPortableCrafting(player.inventory, world, new BlockPos(x, y, z));
|
||||
|
||||
}else if(id == BOOKSHELF){
|
||||
|
||||
TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z));
|
||||
|
||||
if(tileEntity instanceof TileEntityBookshelf){
|
||||
return new electroblob.wizardry.client.gui.GuiBookshelf(player.inventory,
|
||||
(TileEntityBookshelf)tileEntity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package electroblob.wizardry.block;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.WizardryGuiHandler;
|
||||
import electroblob.wizardry.registry.WizardryTabs;
|
||||
import electroblob.wizardry.tileentity.TileEntityBookshelf;
|
||||
import net.minecraft.block.BlockHorizontal;
|
||||
import net.minecraft.block.ITileEntityProvider;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
import net.minecraft.block.state.BlockFaceShape;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.InventoryHelper;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.Properties;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BlockBookshelf extends BlockHorizontal implements ITileEntityProvider {
|
||||
|
||||
public static final int SLOT_COUNT = 12;
|
||||
|
||||
public static final UnlistedPropertyBool[] BOOKS = new UnlistedPropertyBool[SLOT_COUNT];
|
||||
|
||||
static {
|
||||
for(int i=0; i<SLOT_COUNT; i++){
|
||||
BOOKS[i] = new UnlistedPropertyBool("book" + i);
|
||||
}
|
||||
}
|
||||
|
||||
public BlockBookshelf(){
|
||||
super(Material.WOOD);
|
||||
this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH));
|
||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState(){
|
||||
// IProperty<?>[] properties = { FACING };
|
||||
// return new BlockStateContainer(this, ArrayUtils.addAll(properties, BOOKS));
|
||||
return new BlockStateContainer.Builder(this).add(FACING).add(BOOKS).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube(IBlockState state){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullCube(IBlockState state){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face){
|
||||
return state.getValue(FACING).getAxis() == face.getAxis() ? BlockFaceShape.UNDEFINED : BlockFaceShape.SOLID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer){
|
||||
return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakBlock(World world, BlockPos pos, IBlockState block){
|
||||
|
||||
TileEntity tileentity = world.getTileEntity(pos);
|
||||
|
||||
if(tileentity instanceof TileEntityBookshelf){
|
||||
InventoryHelper.dropInventoryItems(world, pos, (TileEntityBookshelf)tileentity);
|
||||
}
|
||||
|
||||
super.breakBlock(world, pos, block); // For blocks that don't extend BlockContainer, this removes the TE
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta(int meta){
|
||||
EnumFacing enumfacing = EnumFacing.byIndex(meta);
|
||||
if(enumfacing.getAxis() == EnumFacing.Axis.Y) enumfacing = EnumFacing.NORTH;
|
||||
return this.getDefaultState().withProperty(FACING, enumfacing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState(IBlockState state){
|
||||
return state.getValue(FACING).getIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos){
|
||||
|
||||
IExtendedBlockState s = (IExtendedBlockState)super.getExtendedState(state, world, pos);
|
||||
|
||||
if(world.getTileEntity(pos) instanceof TileEntityBookshelf){
|
||||
TileEntityBookshelf tileentity = ((TileEntityBookshelf)world.getTileEntity(pos));
|
||||
for(int i = 0; i < tileentity.getSizeInventory(); i++){
|
||||
s = s.withProperty(BOOKS[i], !tileentity.getStackInSlot(i).isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int meta){
|
||||
return new TileEntityBookshelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, BlockPos pos, IBlockState block, EntityPlayer player, EnumHand hand,
|
||||
EnumFacing side, float hitX, float hitY, float hitZ){
|
||||
|
||||
TileEntity tileEntity = world.getTileEntity(pos);
|
||||
|
||||
if(tileEntity == null || player.isSneaking()){
|
||||
return false;
|
||||
}
|
||||
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.BOOKSHELF, world, pos.getX(), pos.getY(), pos.getZ());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eventReceived(IBlockState state, World world, BlockPos pos, int id, int param){
|
||||
super.eventReceived(state, world, pos, id, param);
|
||||
TileEntity tileentity = world.getTileEntity(pos);
|
||||
return tileentity != null && tileentity.receiveClientEvent(id, param);
|
||||
}
|
||||
|
||||
// Copied from BlockFluidBase, only reason it exists is because of java's weird restrictions on generics
|
||||
private static final class UnlistedPropertyBool extends Properties.PropertyAdapter<Boolean> {
|
||||
|
||||
public UnlistedPropertyBool(String name){
|
||||
super(PropertyBool.create(name));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import electroblob.wizardry.packet.PacketControlInput;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package electroblob.wizardry.client.gui;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.inventory.ContainerBookshelf;
|
||||
import electroblob.wizardry.tileentity.TileEntityBookshelf;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class GuiBookshelf extends GuiContainer {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/bookshelf.png");
|
||||
/** The player inventory bound to this GUI. */
|
||||
private final InventoryPlayer playerInventory;
|
||||
/** The inventory contained within the corresponding bookshelf. */
|
||||
public IInventory bookshelfInventory;
|
||||
|
||||
public GuiBookshelf(InventoryPlayer playerInv, TileEntityBookshelf bookshelfInv){
|
||||
super(new ContainerBookshelf(playerInv, bookshelfInv));
|
||||
this.playerInventory = playerInv;
|
||||
this.bookshelfInventory = bookshelfInv;
|
||||
this.allowUserInput = false;
|
||||
this.ySize = 148;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float partialTicks){
|
||||
this.drawDefaultBackground();
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
this.renderHoveredToolTip(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY){
|
||||
String s = this.bookshelfInventory.getDisplayName().getUnformattedText();
|
||||
this.fontRenderer.drawString(s, 8, 6, 4210752);
|
||||
this.fontRenderer.drawString(this.playerInventory.getDisplayName().getUnformattedText(), 8, this.ySize - 96 + 2, 4210752);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY){
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
this.mc.getTextureManager().bindTexture(TEXTURE);
|
||||
int i = (this.width - this.xSize) / 2;
|
||||
int j = (this.height - this.ySize) / 2;
|
||||
this.drawTexturedModalRect(i, j, 0, 0, this.xSize, this.ySize);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package electroblob.wizardry.client.model;
|
||||
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BakedModelBookshelf implements IBakedModel {
|
||||
|
||||
private final IBakedModel bookshelf;
|
||||
private final IBakedModel[] books;
|
||||
|
||||
public BakedModelBookshelf(IBakedModel bookshelf, IBakedModel... books){
|
||||
this.bookshelf = bookshelf;
|
||||
this.books = books;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand){
|
||||
|
||||
IBakedModel fallback = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getModelManager().getMissingModel();
|
||||
if(state == null) return fallback.getQuads(null, side, rand);
|
||||
|
||||
// It took me waaay too long to realise I needed a new list here
|
||||
List<BakedQuad> quads = new ArrayList<>(bookshelf.getQuads(state, side, rand)); // Lists ain't immutable, chief
|
||||
|
||||
IExtendedBlockState extendedState = (IExtendedBlockState)state;
|
||||
|
||||
for(int i = 0; i<BlockBookshelf.SLOT_COUNT; i++){
|
||||
if(extendedState.getValue(BlockBookshelf.BOOKS[i])) quads.addAll(books[i].getQuads(state, side, rand));
|
||||
}
|
||||
|
||||
return quads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer(){
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delegate everything else to the main bookshelf model
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion(){
|
||||
return bookshelf.isAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d(){
|
||||
return bookshelf.isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture(){
|
||||
return bookshelf.getParticleTexture(); // TESTME: May need to do this manually
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides(){
|
||||
return bookshelf.getOverrides(); // TESTME: Same here
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package electroblob.wizardry.client.model;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ModelBookshelf implements IModel {
|
||||
|
||||
private final ModelResourceLocation bookshelfModelLocation;
|
||||
private final String variant;
|
||||
|
||||
public ModelBookshelf(String bookshelfModelName){
|
||||
String[] args = bookshelfModelName.split("#", 2);
|
||||
String model = args[0];
|
||||
variant = args.length == 2 ? args[1] : null;
|
||||
bookshelfModelLocation = new ModelResourceLocation(new ResourceLocation(Wizardry.MODID, "bookshelf_parts/" + model), variant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter){
|
||||
|
||||
try {
|
||||
|
||||
IModel bookshelfModel = ModelLoaderRegistry.getModel(bookshelfModelLocation);
|
||||
// I don't know why default state works here (surely it ought to be the state param?), but it works so who cares
|
||||
IBakedModel bookshelf = bookshelfModel.bake(bookshelfModel.getDefaultState(), format, bakedTextureGetter);
|
||||
|
||||
IBakedModel[] books = new IBakedModel[BlockBookshelf.SLOT_COUNT];
|
||||
|
||||
for(int i = 0; i < BlockBookshelf.SLOT_COUNT; i++){
|
||||
IModel bookModel = ModelLoaderRegistry.getModel(new ModelResourceLocation(new ResourceLocation(Wizardry.MODID, "bookshelf_parts/books" + i), variant));
|
||||
books[i] = bookModel.bake(bookModel.getDefaultState(), format, bakedTextureGetter); // Same here!
|
||||
}
|
||||
|
||||
return new BakedModelBookshelf(bookshelf, books);
|
||||
|
||||
}catch(Exception exception){
|
||||
Wizardry.logger.error("Error baking bookshelf models: ", exception);
|
||||
return ModelLoaderRegistry.getMissingModel().bake(state, format, bakedTextureGetter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package electroblob.wizardry.client.model;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.ICustomModelLoader;
|
||||
import net.minecraftforge.client.model.IModel;
|
||||
|
||||
public class ModelLoaderBookshelf implements ICustomModelLoader {
|
||||
|
||||
private static final String SMART_MODEL_PREFIX = "models/block/smart_model/";
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(IResourceManager resourceManager){
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accepts(ResourceLocation modelLocation){
|
||||
return modelLocation.getNamespace().equals(Wizardry.MODID) && modelLocation.getPath().startsWith(SMART_MODEL_PREFIX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModel loadModel(ResourceLocation modelLocation){
|
||||
return new ModelBookshelf(modelLocation.getPath().substring(SMART_MODEL_PREFIX.length()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import net.minecraft.util.NonNullList;
|
||||
import net.minecraftforge.client.event.ModelBakeEvent;
|
||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||
import net.minecraftforge.client.model.ModelLoader;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
@@ -69,6 +70,16 @@ public final class WizardryModels {
|
||||
ItemBlockMultiTextured gildedWoodItem = (ItemBlockMultiTextured)Item.getItemFromBlock(WizardryBlocks.gilded_wood);
|
||||
registerMultiTexturedModel(gildedWoodItem);
|
||||
|
||||
// Explanation for all this here -> https://github.com/TheGreyGhost/MinecraftByExample/tree/master/src/main/java/minecraftbyexample/mbe05_block_dynamic_block_model2
|
||||
ModelLoaderRegistry.registerLoader(new ModelLoaderBookshelf());
|
||||
|
||||
registerItemModel(Item.getItemFromBlock(WizardryBlocks.oak_bookshelf));
|
||||
registerItemModel(Item.getItemFromBlock(WizardryBlocks.spruce_bookshelf));
|
||||
registerItemModel(Item.getItemFromBlock(WizardryBlocks.birch_bookshelf));
|
||||
registerItemModel(Item.getItemFromBlock(WizardryBlocks.jungle_bookshelf));
|
||||
registerItemModel(Item.getItemFromBlock(WizardryBlocks.acacia_bookshelf));
|
||||
registerItemModel(Item.getItemFromBlock(WizardryBlocks.dark_oak_bookshelf));
|
||||
|
||||
// Items
|
||||
|
||||
registerMultiTexturedModel((ItemCrystal)WizardryItems.magic_crystal);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package electroblob.wizardry.client.renderer;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package electroblob.wizardry.event;
|
||||
|
||||
import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
|
||||
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
package electroblob.wizardry.inventory;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.event.SpellBindEvent;
|
||||
@@ -6,6 +6,7 @@ import electroblob.wizardry.item.IWorkbenchItem;
|
||||
import electroblob.wizardry.item.ItemSpellBook;
|
||||
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
@@ -161,6 +162,7 @@ public class ContainerArcaneWorkbench extends Container {
|
||||
|
||||
// FIXME: It only seems to be syncing correctly when a stack is put into the slot, not taken out.
|
||||
// This is because markDirty isn't called in the tileentity, I think.
|
||||
// You can simulate this using hoppers!
|
||||
this.tileentity.sync();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package electroblob.wizardry.inventory;
|
||||
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.item.ItemSpellBook;
|
||||
import electroblob.wizardry.tileentity.TileEntityBookshelf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class ContainerBookshelf extends Container {
|
||||
|
||||
/** The bookshelf tile entity associated with this container. */
|
||||
public TileEntityBookshelf tileentity;
|
||||
|
||||
public ContainerBookshelf(IInventory inventory, TileEntityBookshelf tileentity){
|
||||
|
||||
this.tileentity = tileentity;
|
||||
|
||||
for(int y = 0; y < 2; y++){
|
||||
for(int x = 0; x < BlockBookshelf.SLOT_COUNT / 2; x++){
|
||||
this.addSlotToContainer(new SlotBookshelf(tileentity, x + BlockBookshelf.SLOT_COUNT / 2 * y, 35 + x * 18, 17 + y * 18, 64, ItemSpellBook.class));
|
||||
}
|
||||
}
|
||||
|
||||
for(int x = 0; x < 9; x++){
|
||||
this.addSlotToContainer(new Slot(inventory, x, 8 + x * 18, 124));
|
||||
}
|
||||
|
||||
for(int y = 0; y < 3; y++){
|
||||
for(int x = 0; x < 9; x++){
|
||||
this.addSlotToContainer(new Slot(inventory, 9 + x + y * 9, 8 + x * 18, 66 + y * 18));
|
||||
}
|
||||
}
|
||||
|
||||
this.onSlotChanged();
|
||||
|
||||
}
|
||||
|
||||
/** Called from individual slots when their item is changed or removed. */
|
||||
public void onSlotChanged(){
|
||||
this.tileentity.sync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith(EntityPlayer player){
|
||||
return this.tileentity.isUsableByPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot(EntityPlayer player, int clickedSlotId){
|
||||
|
||||
ItemStack remainder = ItemStack.EMPTY;
|
||||
Slot slot = this.inventorySlots.get(clickedSlotId);
|
||||
|
||||
if(slot != null && slot.getHasStack()){
|
||||
|
||||
ItemStack stack = slot.getStack(); // The stack that was there originally
|
||||
remainder = stack.copy(); // A copy of that stack
|
||||
|
||||
// Bookshelf -> inventory
|
||||
if(clickedSlotId < BlockBookshelf.SLOT_COUNT){
|
||||
// Tries to move the stack into the player's inventory. If this fails...
|
||||
if(!this.mergeItemStack(stack, BlockBookshelf.SLOT_COUNT, this.inventorySlots.size(), true)){
|
||||
return ItemStack.EMPTY; // ...nothing else happens.
|
||||
}
|
||||
}
|
||||
// Inventory -> bookshelf
|
||||
else{
|
||||
|
||||
int minSlotId = 0;
|
||||
int maxSlotId = BlockBookshelf.SLOT_COUNT - 1;
|
||||
|
||||
if(!(stack.getItem() instanceof ItemSpellBook)) return ItemStack.EMPTY;
|
||||
|
||||
if(!this.mergeItemStack(stack, minSlotId, maxSlotId + 1, false)){
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
if(stack.getCount() == 0){
|
||||
slot.putStack(ItemStack.EMPTY);
|
||||
}else{
|
||||
slot.onSlotChanged();
|
||||
}
|
||||
|
||||
if(stack.getCount() == remainder.getCount()){
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
slot.onTake(player, stack);
|
||||
}
|
||||
|
||||
return remainder;
|
||||
}
|
||||
|
||||
public class SlotBookshelf extends SlotItemClassList {
|
||||
|
||||
@SafeVarargs
|
||||
public SlotBookshelf(IInventory inventory, int index, int x, int y, int stackLimit, Class<? extends Item>... allowedItemClasses){
|
||||
super(inventory, index, x, y, stackLimit, allowedItemClasses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStack(ItemStack stack){
|
||||
boolean statusChanged = this.getStack().isEmpty() != stack.isEmpty();
|
||||
super.putStack(stack);
|
||||
if(statusChanged) ContainerBookshelf.this.onSlotChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack onTake(EntityPlayer player, ItemStack stack){
|
||||
ItemStack result = super.onTake(player, stack);
|
||||
ContainerBookshelf.this.onSlotChanged();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
package electroblob.wizardry.inventory;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
package electroblob.wizardry.inventory;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
package electroblob.wizardry.inventory;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
+3
-2
@@ -1,4 +1,4 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
package electroblob.wizardry.inventory;
|
||||
|
||||
import electroblob.wizardry.item.IWorkbenchItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -29,8 +29,9 @@ public class SlotWorkbenchItem extends Slot {
|
||||
|
||||
@Override
|
||||
public ItemStack onTake(EntityPlayer player, ItemStack stack){
|
||||
ItemStack result = super.onTake(player, stack);
|
||||
this.container.onSlotChanged(slotNumber, ItemStack.EMPTY, player);
|
||||
return super.onTake(player, stack);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -6,7 +6,7 @@ import electroblob.wizardry.packet.PacketControlInput.Message;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.spell.Possession;
|
||||
import electroblob.wizardry.spell.Resurrection;
|
||||
import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
@@ -58,6 +58,12 @@ public final class WizardryBlocks {
|
||||
public static final Block obsidian_crust = placeholder();
|
||||
public static final Block dry_frosted_ice = placeholder();
|
||||
public static final Block gilded_wood = placeholder();
|
||||
public static final Block oak_bookshelf = placeholder();
|
||||
public static final Block spruce_bookshelf = placeholder();
|
||||
public static final Block birch_bookshelf = placeholder();
|
||||
public static final Block jungle_bookshelf = placeholder();
|
||||
public static final Block acacia_bookshelf = placeholder();
|
||||
public static final Block dark_oak_bookshelf = placeholder();
|
||||
|
||||
/**
|
||||
* Sets both the registry and unlocalised names of the given block, then registers it with the given registry. Use
|
||||
@@ -98,6 +104,12 @@ public final class WizardryBlocks {
|
||||
registerBlock(registry, "obsidian_crust", new BlockObsidianCrust());
|
||||
registerBlock(registry, "dry_frosted_ice", new BlockDryFrostedIce());
|
||||
registerBlock(registry, "gilded_wood", new BlockPlanks().setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "oak_bookshelf", new BlockBookshelf());
|
||||
registerBlock(registry, "spruce_bookshelf", new BlockBookshelf());
|
||||
registerBlock(registry, "birch_bookshelf", new BlockBookshelf());
|
||||
registerBlock(registry, "jungle_bookshelf", new BlockBookshelf());
|
||||
registerBlock(registry, "acacia_bookshelf", new BlockBookshelf());
|
||||
registerBlock(registry, "dark_oak_bookshelf", new BlockBookshelf());
|
||||
|
||||
}
|
||||
|
||||
@@ -111,5 +123,6 @@ public final class WizardryBlocks {
|
||||
GameRegistry.registerTileEntity(TileEntityPlayerSave.class, new ResourceLocation(Wizardry.MODID, "player_save"));
|
||||
GameRegistry.registerTileEntity(TileEntityPlayerSaveTimed.class, new ResourceLocation(Wizardry.MODID, "player_save_timed"));
|
||||
GameRegistry.registerTileEntity(TileEntityShrineCore.class, new ResourceLocation(Wizardry.MODID, "shrine_core"));
|
||||
GameRegistry.registerTileEntity(TileEntityBookshelf.class, new ResourceLocation(Wizardry.MODID, "bookshelf"));
|
||||
}
|
||||
}
|
||||
@@ -400,6 +400,13 @@ public final class WizardryItems {
|
||||
registerMultiTexturedItemBlock(registry, WizardryBlocks.runestone_pedestal, false, elements);
|
||||
registerMultiTexturedItemBlock(registry, WizardryBlocks.gilded_wood, true, woodTypes);
|
||||
|
||||
registerItemBlock(registry, WizardryBlocks.oak_bookshelf);
|
||||
registerItemBlock(registry, WizardryBlocks.spruce_bookshelf);
|
||||
registerItemBlock(registry, WizardryBlocks.birch_bookshelf);
|
||||
registerItemBlock(registry, WizardryBlocks.jungle_bookshelf);
|
||||
registerItemBlock(registry, WizardryBlocks.acacia_bookshelf);
|
||||
registerItemBlock(registry, WizardryBlocks.dark_oak_bookshelf);
|
||||
|
||||
// Items
|
||||
|
||||
registerItem(registry, "magic_crystal", new ItemCrystal());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.IWorkbenchItem;
|
||||
import electroblob.wizardry.item.ItemCrystal;
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.item.ItemSpellBook;
|
||||
import electroblob.wizardry.util.NBTExtras;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
|
||||
public class TileEntityBookshelf extends TileEntity implements IInventory, ITickable {
|
||||
|
||||
/** The inventory of the bookshelf. */
|
||||
private NonNullList<ItemStack> inventory;
|
||||
|
||||
public TileEntityBookshelf(){
|
||||
inventory = NonNullList.withSize(BlockBookshelf.SLOT_COUNT, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
/** Called to manually sync the tile entity with clients. */
|
||||
public void sync(){
|
||||
this.world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
// Nothing here for now
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSizeInventory(){
|
||||
return inventory.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot){
|
||||
return inventory.get(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize(int slot, int amount){
|
||||
|
||||
ItemStack stack = getStackInSlot(slot);
|
||||
|
||||
if(!stack.isEmpty()){
|
||||
if(stack.getCount() <= amount){
|
||||
setInventorySlotContents(slot, ItemStack.EMPTY);
|
||||
}else{
|
||||
stack = stack.splitStack(amount);
|
||||
if(stack.getCount() == 0){
|
||||
setInventorySlotContents(slot, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeStackFromSlot(int slot){
|
||||
|
||||
ItemStack stack = getStackInSlot(slot);
|
||||
|
||||
if(!stack.isEmpty()){
|
||||
setInventorySlotContents(slot, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents(int slot, ItemStack stack){
|
||||
|
||||
inventory.set(slot, stack);
|
||||
|
||||
//ItemStack previous = inventory.set(slot, stack);
|
||||
|
||||
//if(previous.isEmpty() != stack.isEmpty()) this.sync();
|
||||
|
||||
if(!stack.isEmpty() && stack.getCount() > getInventoryStackLimit()){
|
||||
stack.setCount(getInventoryStackLimit());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(){
|
||||
return "container." + Wizardry.MODID + ":bookshelf";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
return this.hasCustomName() ? new TextComponentString(this.getName()) : new TextComponentTranslation(this.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit(){
|
||||
return 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUsableByPlayer(EntityPlayer player){
|
||||
return world.getTileEntity(pos) == this && player.getDistanceSqToCenter(pos) < 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openInventory(EntityPlayer player){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeInventory(EntityPlayer player){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int slotNumber, ItemStack itemstack){
|
||||
return itemstack.isEmpty() || itemstack.getItem() instanceof ItemSpellBook; // TODO: Add a whitelist
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound tagCompound){
|
||||
|
||||
super.readFromNBT(tagCompound);
|
||||
|
||||
NBTTagList tagList = tagCompound.getTagList("Inventory", NBT.TAG_COMPOUND);
|
||||
for(int i = 0; i < tagList.tagCount(); i++){
|
||||
NBTTagCompound tag = tagList.getCompoundTagAt(i);
|
||||
byte slot = tag.getByte("Slot");
|
||||
if(slot >= 0 && slot < getSizeInventory()){
|
||||
setInventorySlotContents(slot, new ItemStack(tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound tagCompound){
|
||||
|
||||
super.writeToNBT(tagCompound);
|
||||
|
||||
NBTTagList itemList = new NBTTagList();
|
||||
for(int i = 0; i < getSizeInventory(); i++){
|
||||
ItemStack stack = getStackInSlot(i);
|
||||
if(!stack.isEmpty()){
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setByte("Slot", (byte)i);
|
||||
stack.writeToNBT(tag);
|
||||
itemList.appendTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
NBTExtras.storeTagSafely(tagCompound, "Inventory", itemList);
|
||||
return tagCompound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final NBTTagCompound getUpdateTag(){
|
||||
return this.writeToNBT(new NBTTagCompound());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SPacketUpdateTileEntity getUpdatePacket(){
|
||||
return new SPacketUpdateTileEntity(pos, getBlockMetadata(), this.getUpdateTag());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt){
|
||||
readFromNBT(pkt.getNbtCompound());
|
||||
}
|
||||
|
||||
// What are all these for?
|
||||
|
||||
@Override
|
||||
public int getField(int id){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setField(int id, int value){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFieldCount(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(){
|
||||
for(int i = 0; i < getSizeInventory(); i++){
|
||||
setInventorySlotContents(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty(){
|
||||
for(int i = 0; i < getSizeInventory(); i++){
|
||||
if(!getStackInSlot(i).isEmpty()){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user