ender crates, part 1

This commit is contained in:
Ellpeck 2019-02-17 22:51:05 +01:00
parent 16997fb8ee
commit 095e5e92cf
13 changed files with 380 additions and 1 deletions

View file

@ -37,6 +37,7 @@ import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.IItemHandlerModifiable;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
@ -315,4 +316,11 @@ public final class Helper {
} }
return false; return false;
} }
public static boolean isEmpty(IItemHandler handler) {
for (int i = 0; i < handler.getSlots(); i++)
if (!handler.getStackInSlot(i).isEmpty())
return false;
return true;
}
} }

View file

@ -4,6 +4,7 @@ import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer; import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
import de.ellpeck.naturesaura.api.aura.item.IAuraRecharge; import de.ellpeck.naturesaura.api.aura.item.IAuraRecharge;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import de.ellpeck.naturesaura.blocks.ModBlocks; import de.ellpeck.naturesaura.blocks.ModBlocks;
import de.ellpeck.naturesaura.blocks.multi.Multiblocks; import de.ellpeck.naturesaura.blocks.multi.Multiblocks;
import de.ellpeck.naturesaura.chunk.effect.DrainSpotEffects; import de.ellpeck.naturesaura.chunk.effect.DrainSpotEffects;
@ -11,6 +12,7 @@ import de.ellpeck.naturesaura.commands.CommandAura;
import de.ellpeck.naturesaura.compat.Compat; import de.ellpeck.naturesaura.compat.Compat;
import de.ellpeck.naturesaura.entities.ModEntities; import de.ellpeck.naturesaura.entities.ModEntities;
import de.ellpeck.naturesaura.events.CommonEvents; import de.ellpeck.naturesaura.events.CommonEvents;
import de.ellpeck.naturesaura.gui.GuiHandler;
import de.ellpeck.naturesaura.items.ModItems; import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.items.OreDict; import de.ellpeck.naturesaura.items.OreDict;
import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketHandler;
@ -62,6 +64,7 @@ public final class NaturesAura {
Helper.registerCap(IAuraContainer.class); Helper.registerCap(IAuraContainer.class);
Helper.registerCap(IAuraRecharge.class); Helper.registerCap(IAuraRecharge.class);
Helper.registerCap(IAuraChunk.class); Helper.registerCap(IAuraChunk.class);
Helper.registerCap(IWorldData.class);
new ModBlocks(); new ModBlocks();
new ModItems(); new ModItems();
@ -85,6 +88,7 @@ public final class NaturesAura {
ModRegistry.init(event); ModRegistry.init(event);
DrainSpotEffects.init(); DrainSpotEffects.init();
OreDict.init(); OreDict.init();
new GuiHandler();
proxy.init(event); proxy.init(event);
} }

View file

@ -9,6 +9,7 @@ import de.ellpeck.naturesaura.api.aura.item.IAuraRecharge;
import de.ellpeck.naturesaura.api.aura.type.BasicAuraType; import de.ellpeck.naturesaura.api.aura.type.BasicAuraType;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.api.internal.StubHooks; import de.ellpeck.naturesaura.api.internal.StubHooks;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import de.ellpeck.naturesaura.api.multiblock.IMultiblock; import de.ellpeck.naturesaura.api.multiblock.IMultiblock;
import de.ellpeck.naturesaura.api.multiblock.Matcher; import de.ellpeck.naturesaura.api.multiblock.Matcher;
import de.ellpeck.naturesaura.api.recipes.AltarRecipe; import de.ellpeck.naturesaura.api.recipes.AltarRecipe;
@ -136,6 +137,13 @@ public final class NaturesAuraAPI {
*/ */
@CapabilityInject(IAuraChunk.class) @CapabilityInject(IAuraChunk.class)
public static Capability<IAuraChunk> capAuraChunk; public static Capability<IAuraChunk> capAuraChunk;
/**
* The capability that any world has to store Nature's Aura specific data in
* it. To retrieve this capability from any world, use the helper methods
* {@link IWorldData#getWorldData(World)} or {@link IWorldData#getOverworldData()}.
*/
@CapabilityInject(IWorldData.class)
public static Capability<IWorldData> capWorldData;
/** /**
* This method returns the active {@link IInternalHooks} instance which can * This method returns the active {@link IInternalHooks} instance which can

View file

@ -0,0 +1,27 @@
package de.ellpeck.naturesaura.api.misc;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.DimensionType;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.items.IItemHandlerModifiable;
public interface IWorldData extends ICapabilityProvider, INBTSerializable<NBTTagCompound> {
static IWorldData getWorldData(World world) {
if (world.hasCapability(NaturesAuraAPI.capWorldData, null))
return world.getCapability(NaturesAuraAPI.capWorldData, null);
return null;
}
static IWorldData getOverworldData(World world) {
if (!world.isRemote)
return getWorldData(DimensionManager.getWorld(DimensionType.OVERWORLD.getId()));
return getWorldData(world);
}
IItemHandlerModifiable getEnderStorage(String name);
}

View file

@ -0,0 +1,34 @@
package de.ellpeck.naturesaura.blocks;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityEnderCrate;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
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.World;
public class BlockEnderCrate extends BlockContainerImpl {
public BlockEnderCrate() {
super(Material.ROCK, "ender_crate", TileEntityEnderCrate.class, "ender_crate");
this.setSoundType(SoundType.STONE);
this.setHardness(5F);
}
@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
if (!worldIn.isRemote) {
TileEntity tile = worldIn.getTileEntity(pos);
if (tile instanceof TileEntityEnderCrate) {
TileEntityEnderCrate crate = (TileEntityEnderCrate) tile;
if (crate.canOpen())
playerIn.openGui(NaturesAura.MOD_ID, 0, worldIn, pos.getX(), pos.getY(), pos.getZ());
}
}
return true;
}
}

View file

@ -49,4 +49,5 @@ public final class ModBlocks {
public static final Block MOSS_GENERATOR = new BlockMossGenerator(); public static final Block MOSS_GENERATOR = new BlockMossGenerator();
public static final Block TIME_CHANGER = new BlockTimeChanger(); public static final Block TIME_CHANGER = new BlockTimeChanger();
public static final Block GENERATOR_LIMIT_REMOVER = new BlockImpl("generator_limit_remover", Material.ROCK).setSoundType(SoundType.STONE).setHardness(2F); public static final Block GENERATOR_LIMIT_REMOVER = new BlockImpl("generator_limit_remover", Material.ROCK).setSoundType(SoundType.STONE).setHardness(2F);
public static final Block ENDER_CRATE = new BlockEnderCrate();
} }

View file

@ -0,0 +1,61 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.items.IItemHandlerModifiable;
public class TileEntityEnderCrate extends TileEntityImpl {
public String name;
@Override
public IItemHandlerModifiable getItemHandler(EnumFacing facing) {
if (this.canOpen())
return IWorldData.getOverworldData(this.world).getEnderStorage(this.name);
return null;
}
public boolean canOpen() {
return this.name != null;
}
@Override
public void dropInventory() {
}
@Override
public ItemStack getDrop(IBlockState state, int fortune) {
ItemStack drop = super.getDrop(state, fortune);
if (this.name != null)
drop.setStackDisplayName(this.name);
return drop;
}
@Override
public void loadDataOnPlace(ItemStack stack) {
super.loadDataOnPlace(stack);
if (!this.world.isRemote && stack.hasDisplayName())
this.name = stack.getDisplayName();
}
@Override
public void writeNBT(NBTTagCompound compound, SaveType type) {
super.writeNBT(compound, type);
if (type != SaveType.BLOCK) {
if (this.name != null)
compound.setString("name", this.name);
}
}
@Override
public void readNBT(NBTTagCompound compound, SaveType type) {
super.readNBT(compound, type);
if (type != SaveType.BLOCK) {
if (compound.hasKey("name"))
this.name = compound.getString("name");
}
}
}

View file

@ -7,8 +7,10 @@ import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk; import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.misc.WorldData;
import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketHandler;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.common.config.Config; import net.minecraftforge.common.config.Config;
@ -30,6 +32,12 @@ public class CommonEvents {
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "aura"), new AuraChunk(chunk, type)); event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "aura"), new AuraChunk(chunk, type));
} }
@SubscribeEvent
public void onWorldCapsAttach(AttachCapabilitiesEvent<World> event) {
World world = event.getObject();
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new WorldData(world));
}
@SubscribeEvent @SubscribeEvent
public void onWorldTick(TickEvent.WorldTickEvent event) { public void onWorldTick(TickEvent.WorldTickEvent event) {
if (!event.world.isRemote && event.phase == TickEvent.Phase.END) { if (!event.world.isRemote && event.phase == TickEvent.Phase.END) {

View file

@ -0,0 +1,57 @@
package de.ellpeck.naturesaura.gui;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityEnderCrate;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
public class ContainerEnderCrate extends Container {
private final TileEntityEnderCrate crate;
public ContainerEnderCrate(EntityPlayer player, TileEntityEnderCrate crate) {
this.crate = crate;
IItemHandler handler = this.crate.getItemHandler(null);
int i = (3 - 4) * 18;
for (int j = 0; j < 3; ++j)
for (int k = 0; k < 9; ++k)
this.addSlotToContainer(new SlotItemHandler(handler, k + j * 9, 8 + k * 18, 18 + j * 18));
for (int l = 0; l < 3; ++l)
for (int j1 = 0; j1 < 9; ++j1)
this.addSlotToContainer(new Slot(player.inventory, j1 + l * 9 + 9, 8 + j1 * 18, 103 + l * 18 + i));
for (int i1 = 0; i1 < 9; ++i1)
this.addSlotToContainer(new Slot(player.inventory, i1, 8 + i1 * 18, 161 + i));
}
@Override
public boolean canInteractWith(EntityPlayer playerIn) {
return !this.crate.isInvalid();
}
@Override
public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
ItemStack itemstack = ItemStack.EMPTY;
Slot slot = this.inventorySlots.get(index);
if (slot != null && slot.getHasStack()) {
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
if (index < 3 * 9) {
if (!this.mergeItemStack(itemstack1, 3 * 9, this.inventorySlots.size(), true))
return ItemStack.EMPTY;
} else if (!this.mergeItemStack(itemstack1, 0, 3 * 9, false))
return ItemStack.EMPTY;
if (itemstack1.isEmpty())
slot.putStack(ItemStack.EMPTY);
else
slot.onSlotChanged();
}
return itemstack;
}
}

View file

@ -0,0 +1,51 @@
package de.ellpeck.naturesaura.gui;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityEnderCrate;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class GuiEnderCrate extends GuiContainer {
private static final ResourceLocation CHEST_GUI_TEXTURE = new ResourceLocation("textures/gui/container/generic_54.png");
private final EntityPlayer player;
private final TileEntityEnderCrate crate;
public GuiEnderCrate(EntityPlayer player, TileEntityEnderCrate crate) {
super(new ContainerEnderCrate(player, crate));
this.player = player;
this.crate = crate;
this.allowUserInput = false;
this.ySize = 114 + 3 * 18;
}
@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 display = I18n.format("info." + NaturesAura.MOD_ID + ".ender_crate", TextFormatting.ITALIC + this.crate.name + TextFormatting.RESET);
this.fontRenderer.drawString(display, 8, 6, 4210752);
this.fontRenderer.drawString(this.player.inventory.getDisplayName().getFormattedText(), 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(CHEST_GUI_TEXTURE);
int i = (this.width - this.xSize) / 2;
int j = (this.height - this.ySize) / 2;
this.drawTexturedModalRect(i, j, 0, 0, this.xSize, 3 * 18 + 17);
this.drawTexturedModalRect(i, j + 3 * 18 + 17, 0, 126, this.xSize, 96);
}
}

View file

@ -0,0 +1,47 @@
package de.ellpeck.naturesaura.gui;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityEnderCrate;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import javax.annotation.Nullable;
public class GuiHandler implements IGuiHandler {
public GuiHandler() {
NetworkRegistry.INSTANCE.registerGuiHandler(NaturesAura.MOD_ID, this);
}
@Nullable
@Override
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
if (id == 0) {
TileEntity tile = world.getTileEntity(new BlockPos(x, y, z));
if (tile instanceof TileEntityEnderCrate) {
TileEntityEnderCrate crate = (TileEntityEnderCrate) tile;
if (crate.canOpen())
return new ContainerEnderCrate(player, crate);
}
}
return null;
}
@Nullable
@Override
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
if (id == 0) {
TileEntity tile = world.getTileEntity(new BlockPos(x, y, z));
if (tile instanceof TileEntityEnderCrate) {
TileEntityEnderCrate crate = (TileEntityEnderCrate) tile;
if (crate.canOpen())
return new GuiEnderCrate(player, crate);
}
}
return null;
}
}

View file

@ -0,0 +1,71 @@
package de.ellpeck.naturesaura.misc;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import de.ellpeck.naturesaura.blocks.tiles.ItemStackHandlerNA;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
public class WorldData implements IWorldData {
private final World world;
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();
public WorldData(World world) {
this.world = world;
}
@Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
return capability == NaturesAuraAPI.capWorldData;
}
@Nullable
@Override
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) {
return capability == NaturesAuraAPI.capWorldData ? (T) this : null;
}
@Override
public NBTTagCompound serializeNBT() {
NBTTagCompound compound = new NBTTagCompound();
NBTTagList storages = new NBTTagList();
for (Map.Entry<String, ItemStackHandlerNA> entry : this.enderStorages.entrySet()) {
ItemStackHandlerNA handler = entry.getValue();
if (Helper.isEmpty(handler))
continue;
NBTTagCompound storageComp = handler.serializeNBT();
storageComp.setString("name", entry.getKey());
storages.appendTag(storageComp);
}
compound.setTag("storages", storages);
return compound;
}
@Override
public void deserializeNBT(NBTTagCompound compound) {
this.enderStorages.clear();
NBTTagList storages = compound.getTagList("storages", 10);
for (NBTBase base : storages) {
NBTTagCompound storageComp = (NBTTagCompound) base;
ItemStackHandlerNA storage = this.getEnderStorage(storageComp.getString("name"));
storage.deserializeNBT(storageComp);
}
}
@Override
public ItemStackHandlerNA getEnderStorage(String name) {
return this.enderStorages.computeIfAbsent(name, n -> new ItemStackHandlerNA(27));
}
}

View file

@ -45,6 +45,7 @@ tile.naturesaura.rf_converter.name=Energetic Aura Forge
tile.naturesaura.moss_generator.name=Swamp Homi tile.naturesaura.moss_generator.name=Swamp Homi
tile.naturesaura.time_changer.name=Shifting Sundial tile.naturesaura.time_changer.name=Shifting Sundial
tile.naturesaura.generator_limit_remover.name=Creational Catalyst tile.naturesaura.generator_limit_remover.name=Creational Catalyst
tile.naturesaura.ender_crate.name=Ender Crate
item.naturesaura.eye.name=Environmental Eye item.naturesaura.eye.name=Environmental Eye
item.naturesaura.eye_improved.name=Environmental Ocular item.naturesaura.eye_improved.name=Environmental Ocular
@ -104,6 +105,7 @@ info.naturesaura.same_position=This seems to be the position from your notes...
info.naturesaura.too_far=The distance seems too great... info.naturesaura.too_far=The distance seems too great...
info.naturesaura.stored_pos_gone=Your notes seem out of date... info.naturesaura.stored_pos_gone=Your notes seem out of date...
info.naturesaura.empty=Empty info.naturesaura.empty=Empty
info.naturesaura.ender_crate=Ender Crate (%s)
advancement.naturesaura.root=Nature's Aura advancement.naturesaura.root=Nature's Aura
advancement.naturesaura.root.desc=Becoming a magical botanist advancement.naturesaura.root.desc=Becoming a magical botanist