finish the ender crates

This commit is contained in:
Ellpeck 2019-02-18 19:30:35 +01:00
parent 1502348da8
commit c97a13f737
13 changed files with 235 additions and 17 deletions

View file

@ -140,7 +140,7 @@ public final class NaturesAuraAPI {
/**
* 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()}.
* {@link IWorldData#getWorldData(World)} or {@link IWorldData#getOverworldData(World)}.
*/
@CapabilityInject(IWorldData.class)
public static Capability<IWorldData> capWorldData;

View file

@ -24,4 +24,6 @@ public interface IWorldData extends ICapabilityProvider, INBTSerializable<NBTTag
}
IItemHandlerModifiable getEnderStorage(String name);
boolean isEnderStorageLocked(String name);
}

View file

@ -1,32 +1,107 @@
package de.ellpeck.naturesaura.blocks;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityEnderCrate;
import de.ellpeck.naturesaura.blocks.tiles.render.RenderEnderCrate;
import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.reg.ITESRProvider;
import net.minecraft.block.BlockAnvil;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.AnvilUpdateEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Random;
public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider {
// This is terrible but I can't see a better solution right now so oh well
private static final ThreadLocal<WeakReference<World>> CACHED_WORLD = new ThreadLocal<>();
public BlockEnderCrate() {
super(Material.ROCK, "ender_crate", TileEntityEnderCrate.class, "ender_crate");
this.setSoundType(SoundType.STONE);
this.setHardness(5F);
this.setLightLevel(0.75F);
MinecraftForge.EVENT_BUS.register(this);
}
public static String getEnderName(ItemStack stack) {
if (!stack.hasTagCompound())
return "";
NBTTagCompound compound = stack.getTagCompound();
return compound.getString(NaturesAura.MOD_ID + ":ender_name");
}
@SideOnly(Side.CLIENT)
public static void addEnderNameInfo(ItemStack stack, List<String> tooltip) {
String name = getEnderName(stack);
if (name != null && !name.isEmpty())
tooltip.add(TextFormatting.DARK_PURPLE + I18n.format("info." + NaturesAura.MOD_ID + ".ender_name",
TextFormatting.ITALIC + name + TextFormatting.RESET));
else
tooltip.add(TextFormatting.DARK_PURPLE + I18n.format("info." + NaturesAura.MOD_ID + ".ender_name.missing"));
}
@SubscribeEvent
public void onRightClick(PlayerInteractEvent.RightClickBlock event) {
World world = event.getWorld();
BlockPos pos = event.getPos();
IBlockState state = world.getBlockState(pos);
if (state.getBlock() instanceof BlockAnvil) {
CACHED_WORLD.set(new WeakReference<>(world));
}
}
@SubscribeEvent
public void onAnvilUpdate(AnvilUpdateEvent event) {
WeakReference<World> world = CACHED_WORLD.get();
if (world == null || world.get() == null)
return;
ItemStack stack = event.getLeft();
if (stack.getItem() != Item.getItemFromBlock(this) && stack.getItem() != ModItems.ENDER_ACCESS)
return;
ItemStack second = event.getRight();
if (second.getItem() != Items.ENDER_EYE || second.getCount() < stack.getCount())
return;
String name = event.getName();
if (name == null || name.isEmpty())
return;
if (IWorldData.getOverworldData(world.get()).isEnderStorageLocked(name))
return;
ItemStack output = stack.copy();
if (!output.hasTagCompound())
output.setTagCompound(new NBTTagCompound());
output.getTagCompound().setString(NaturesAura.MOD_ID + ":ender_name", name);
event.setOutput(output);
event.setMaterialCost(stack.getCount());
event.setCost(1);
}
@Override
@ -36,7 +111,7 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
if (tile instanceof TileEntityEnderCrate) {
TileEntityEnderCrate crate = (TileEntityEnderCrate) tile;
if (crate.canOpen()) {
crate.drainAura(5000);
crate.drainAura(10000);
playerIn.openGui(NaturesAura.MOD_ID, 0, worldIn, pos.getX(), pos.getY(), pos.getZ());
}
}
@ -44,6 +119,12 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
return true;
}
@Override
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack stack, @Nullable World worldIn, List<String> tooltip, ITooltipFlag flagIn) {
addEnderNameInfo(stack, tooltip);
}
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) {

View file

@ -1,7 +1,9 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import de.ellpeck.naturesaura.blocks.BlockEnderCrate;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@ -35,7 +37,7 @@ public class TileEntityEnderCrate extends TileEntityImpl {
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
ItemStack remain = this.getStorage().insertItem(slot, stack, simulate);
if (!simulate)
TileEntityEnderCrate.this.drainAura((stack.getCount() - remain.getCount()) * 200);
TileEntityEnderCrate.this.drainAura((stack.getCount() - remain.getCount()) * 500);
return remain;
}
@ -44,7 +46,7 @@ public class TileEntityEnderCrate extends TileEntityImpl {
public ItemStack extractItem(int slot, int amount, boolean simulate) {
ItemStack extracted = this.getStorage().extractItem(slot, amount, simulate);
if (!simulate)
TileEntityEnderCrate.this.drainAura(extracted.getCount() * 200);
TileEntityEnderCrate.this.drainAura(extracted.getCount() * 500);
return extracted;
}
@ -77,16 +79,22 @@ public class TileEntityEnderCrate extends TileEntityImpl {
@Override
public ItemStack getDrop(IBlockState state, int fortune) {
ItemStack drop = super.getDrop(state, fortune);
if (this.name != null)
drop.setStackDisplayName(this.name);
if (this.name != null) {
if (!drop.hasTagCompound())
drop.setTagCompound(new NBTTagCompound());
drop.getTagCompound().setString(NaturesAura.MOD_ID + ":ender_name", this.name);
}
return drop;
}
@Override
public void loadDataOnPlace(ItemStack stack) {
super.loadDataOnPlace(stack);
if (!this.world.isRemote && stack.hasDisplayName())
this.name = stack.getDisplayName();
if (!this.world.isRemote) {
String name = BlockEnderCrate.getEnderName(stack);
if (name != null && !name.isEmpty())
this.name = name;
}
}
@Override

View file

@ -2,6 +2,7 @@ package de.ellpeck.naturesaura.gui;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import de.ellpeck.naturesaura.blocks.BlockEnderCrate;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityEnderCrate;
import de.ellpeck.naturesaura.items.ModItems;
import net.minecraft.entity.player.EntityPlayer;
@ -32,8 +33,11 @@ public class GuiHandler implements IGuiHandler {
}
} else if (id == 1) {
ItemStack stack = player.getHeldItemMainhand();
if (stack.getItem() == ModItems.ENDER_ACCESS && stack.hasDisplayName())
return new ContainerEnderCrate(player, IWorldData.getOverworldData(world).getEnderStorage(stack.getDisplayName()));
if (stack.getItem() == ModItems.ENDER_ACCESS) {
String name = BlockEnderCrate.getEnderName(stack);
if (name != null && !name.isEmpty())
return new ContainerEnderCrate(player, IWorldData.getOverworldData(world).getEnderStorage(name));
}
}
return null;
}
@ -50,9 +54,10 @@ public class GuiHandler implements IGuiHandler {
}
} else if (id == 1) {
ItemStack stack = player.getHeldItemMainhand();
if (stack.getItem() == ModItems.ENDER_ACCESS && stack.hasDisplayName()) {
String name = stack.getDisplayName();
return new GuiEnderCrate(player, IWorldData.getOverworldData(world).getEnderStorage(name), "ender_access", name);
if (stack.getItem() == ModItems.ENDER_ACCESS) {
String name = BlockEnderCrate.getEnderName(stack);
if (name != null && !name.isEmpty())
return new GuiEnderCrate(player, IWorldData.getOverworldData(world).getEnderStorage(name), "ender_access", name);
}
}
return null;

View file

@ -1,13 +1,21 @@
package de.ellpeck.naturesaura.items;
import com.google.common.base.Strings;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.blocks.BlockEnderCrate;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nullable;
import java.util.List;
public class ItemEnderAccess extends ItemImpl {
public ItemEnderAccess() {
@ -19,12 +27,17 @@ public class ItemEnderAccess extends ItemImpl {
if (handIn != EnumHand.MAIN_HAND)
return new ActionResult<>(EnumActionResult.PASS, playerIn.getHeldItem(handIn));
ItemStack stack = playerIn.getHeldItemMainhand();
if (stack.hasDisplayName()) {
if (!worldIn.isRemote && NaturesAuraAPI.instance().extractAuraFromPlayer(playerIn, 5000, false)) {
if (!Strings.isNullOrEmpty(BlockEnderCrate.getEnderName(stack))) {
if (!worldIn.isRemote && NaturesAuraAPI.instance().extractAuraFromPlayer(playerIn, 10000, false))
playerIn.openGui(NaturesAura.MOD_ID, 1, worldIn, (int) playerIn.posX, (int) playerIn.posY, (int) playerIn.posZ);
}
return new ActionResult<>(EnumActionResult.SUCCESS, stack);
}
return new ActionResult<>(EnumActionResult.FAIL, stack);
}
@Override
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack stack, @Nullable World worldIn, List<String> tooltip, ITooltipFlag flagIn) {
BlockEnderCrate.addEnderNameInfo(stack, tooltip);
}
}

View file

@ -4,6 +4,8 @@ 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 de.ellpeck.naturesaura.items.ModItems;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
@ -68,4 +70,15 @@ public class WorldData implements IWorldData {
public ItemStackHandlerNA getEnderStorage(String name) {
return this.enderStorages.computeIfAbsent(name, n -> new ItemStackHandlerNA(27));
}
@Override
public boolean isEnderStorageLocked(String name) {
ItemStackHandlerNA handler = this.getEnderStorage(name);
for (int i = 0; i < handler.getSlots(); i++) {
ItemStack stack = handler.getStackInSlot(i);
if (!stack.isEmpty() && stack.getItem() == ModItems.TOKEN_TERROR)
return true;
}
return false;
}
}

View file

@ -108,6 +108,8 @@ info.naturesaura.stored_pos_gone=Your notes seem out of date...
info.naturesaura.empty=Empty
info.naturesaura.ender_crate=Ender Crate: %s
info.naturesaura.ender_access=Ender Ocular: %s
info.naturesaura.ender_name.missing=No Ender Name
info.naturesaura.ender_name=Ender Name: %s
advancement.naturesaura.root=Nature's Aura
advancement.naturesaura.root.desc=Becoming a magical botanist

View file

@ -0,0 +1,17 @@
{
"name": "Ender Ocular",
"icon": "naturesaura:ender_access",
"category": "items",
"advancement": "naturesaura:aura_bottle_end",
"pages": [
{
"type": "text",
"text": "The $(item)Ender Ocular$() is, to put it simply, a handheld version of the $(l:using/ender_crate)Ender Crate$(). After giving it an $(thing)Ender Name$() the exact same way, interacting with it while holding it in one's hand will open the storage then and there. For this, an $(l:items/aura_cache)Aura Cache$() is required that some $(aura) will be drained from."
},
{
"type": "crafting",
"text": "Creating the $(item)Ender Ocular$()",
"recipe": "naturesaura:ender_access"
}
]
}

View file

@ -40,7 +40,8 @@
{
"type": "naturesaura:offering",
"text": "Exchanging the $(item)Token of Fear$() for a much stronger version, the $(item)Token of Terror$()",
"recipe": "naturesaura:token_terror"
"recipe": "naturesaura:token_terror",
"anchor": "terror"
},
{
"type": "naturesaura:offering",

View file

@ -0,0 +1,21 @@
{
"name": "Ender Crate",
"icon": "naturesaura:ender_crate",
"category": "using",
"advancement": "naturesaura:aura_bottle_end",
"pages": [
{
"type": "text",
"text": "$(item)Ender Chests$() are great technology for anyone trying to store items safely, however, they don't provide easy means of $(thing)transportation$() for said items. For this, the $(item)Ender Crate$() is perfect: Two or more of these crates which are linked together share the same inventory, even inter-dimensionally, meaning that they create the possibility of easily transporting items around."
},
{
"type": "text",
"text": "Of course, some $(aura) is required for each interaction that takes place with the crate.$(br)To link one or more crates, they have to be given an $(item)Ender Name$() by placing them in an $(thing)anvil$() with an $(item)Ender Eye$() and then writing down the desired name.$(br)If the worry exists that other people might call their crates the same name, any name can be $(thing)locked$() from being given simply by placing a $(l:practices/offering#terror)Token of Terror$() inside a crate with that name."
},
{
"type": "crafting",
"text": "Creating the $(item)Ender Crate$()",
"recipe": "naturesaura:ender_crate"
}
]
}

View file

@ -0,0 +1,26 @@
{
"type": "forge:ore_shaped",
"pattern": [
" Y ",
"DED",
" D "
],
"key": {
"E": {
"item": "minecraft:ender_chest"
},
"Y": {
"item": "minecraft:ender_eye"
},
"D": {
"type": "minecraft:item_nbt",
"item": "naturesaura:aura_bottle",
"nbt": {
"stored_type": "naturesaura:end"
}
}
},
"result": {
"item": "naturesaura:ender_access"
}
}

View file

@ -0,0 +1,29 @@
{
"type": "forge:ore_shaped",
"pattern": [
"OYO",
"DED",
"ODO"
],
"key": {
"E": {
"item": "minecraft:ender_chest"
},
"Y": {
"item": "minecraft:ender_eye"
},
"D": {
"type": "minecraft:item_nbt",
"item": "naturesaura:aura_bottle",
"nbt": {
"stored_type": "naturesaura:end"
}
},
"O": {
"item": "minecraft:obsidian"
}
},
"result": {
"item": "naturesaura:ender_crate"
}
}