mirror of
https://github.com/Ellpeck/NaturesAura.git
synced 2024-11-22 11:53:29 +01:00
add the placer
This commit is contained in:
parent
7f5c054f0a
commit
6eeebb1e2a
10 changed files with 207 additions and 10 deletions
|
@ -9,6 +9,7 @@ import net.minecraft.client.Minecraft;
|
|||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.entity.item.EntityItemFrame;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -16,6 +17,7 @@ import net.minecraft.tileentity.TileEntity;
|
|||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
|
@ -48,6 +50,17 @@ public final class Helper {
|
|||
}
|
||||
}
|
||||
|
||||
public static List<EntityItemFrame> getAttachedItemFrames(World world, BlockPos pos) {
|
||||
List<EntityItemFrame> frames = world.getEntitiesWithinAABB(EntityItemFrame.class, new AxisAlignedBB(pos).grow(0.25));
|
||||
for (int i = frames.size() - 1; i >= 0; i--) {
|
||||
EntityItemFrame frame = frames.get(i);
|
||||
BlockPos framePos = frame.getHangingPosition().offset(frame.facingDirection.getOpposite());
|
||||
if (!pos.equals(framePos))
|
||||
frames.remove(i);
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
|
||||
// For some reason this method isn't public in World, but I also don't want to have to make a new BlockPos
|
||||
// or use the messy MutableBlockPos system just to see if a chunk is loaded, so this will have to do I guess
|
||||
public static boolean isChunkLoaded(World world, int x, int z) {
|
||||
|
|
14
src/main/java/de/ellpeck/naturesaura/blocks/BlockPlacer.java
Normal file
14
src/main/java/de/ellpeck/naturesaura/blocks/BlockPlacer.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
package de.ellpeck.naturesaura.blocks;
|
||||
|
||||
import de.ellpeck.naturesaura.blocks.tiles.TileEntityPlacer;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.Material;
|
||||
|
||||
public class BlockPlacer extends BlockContainerImpl {
|
||||
|
||||
public BlockPlacer() {
|
||||
super(Material.ROCK, "placer", TileEntityPlacer.class, "placer");
|
||||
this.setSoundType(SoundType.STONE);
|
||||
this.setHardness(2.5F);
|
||||
}
|
||||
}
|
|
@ -29,4 +29,5 @@ public final class ModBlocks {
|
|||
public static final Block AURA_DETECTOR = new BlockAuraDetector();
|
||||
public static final Block CONVERSION_CATALYST = new BlockImpl("conversion_catalyst", Material.ROCK).setSoundType(SoundType.STONE).setHardness(2.5F);
|
||||
public static final Block FLOWER_GENERATOR = new BlockFlowerGenerator();
|
||||
public static final Block PLACER = new BlockPlacer();
|
||||
}
|
||||
|
|
|
@ -188,10 +188,11 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable {
|
|||
@Override
|
||||
public void writeNBT(NBTTagCompound compound, SaveType type) {
|
||||
super.writeNBT(compound, type);
|
||||
compound.setTag("items", this.items.serializeNBT());
|
||||
compound.setBoolean("fine", this.structureFine);
|
||||
this.container.writeNBT(compound);
|
||||
|
||||
if (type != SaveType.BLOCK) {
|
||||
compound.setTag("items", this.items.serializeNBT());
|
||||
compound.setBoolean("fine", this.structureFine);
|
||||
this.container.writeNBT(compound);
|
||||
}
|
||||
if (type == SaveType.TILE) {
|
||||
if (this.currentRecipe != null) {
|
||||
compound.setString("recipe", this.currentRecipe.name.toString());
|
||||
|
@ -203,10 +204,11 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable {
|
|||
@Override
|
||||
public void readNBT(NBTTagCompound compound, SaveType type) {
|
||||
super.readNBT(compound, type);
|
||||
this.items.deserializeNBT(compound.getCompoundTag("items"));
|
||||
this.structureFine = compound.getBoolean("fine");
|
||||
this.container.readNBT(compound);
|
||||
|
||||
if (type != SaveType.BLOCK) {
|
||||
this.items.deserializeNBT(compound.getCompoundTag("items"));
|
||||
this.structureFine = compound.getBoolean("fine");
|
||||
this.container.readNBT(compound);
|
||||
}
|
||||
if (type == SaveType.TILE) {
|
||||
if (compound.hasKey("recipe")) {
|
||||
this.currentRecipe = AltarRecipe.RECIPES.get(new ResourceLocation(compound.getString("recipe")));
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
package de.ellpeck.naturesaura.blocks.tiles;
|
||||
|
||||
import de.ellpeck.naturesaura.Helper;
|
||||
import de.ellpeck.naturesaura.aura.chunk.AuraChunk;
|
||||
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.item.EntityItemFrame;
|
||||
import net.minecraft.init.Blocks;
|
||||
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.ITickable;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.IPlantable;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TileEntityPlacer extends TileEntityImpl implements ITickable {
|
||||
|
||||
private final ItemStackHandlerNA handler = new ItemStackHandlerNA(1, this, true);
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (!this.world.isRemote && this.world.getTotalWorldTime() % 15 == 0) {
|
||||
TileEntity tileUp = this.world.getTileEntity(this.pos.up());
|
||||
if (tileUp == null || !tileUp.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN))
|
||||
return;
|
||||
IItemHandler handler = tileUp.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN);
|
||||
if (handler == null)
|
||||
return;
|
||||
List<EntityItemFrame> frames = Helper.getAttachedItemFrames(this.world, this.pos);
|
||||
if (frames.isEmpty())
|
||||
return;
|
||||
|
||||
List<BlockPos> validPositions = new ArrayList<>();
|
||||
int range = 5;
|
||||
for (int x = -range; x <= range; x++)
|
||||
for (int y = -range; y <= range; y++)
|
||||
for (int z = -range; z <= range; z++) {
|
||||
BlockPos pos = this.pos.add(x, y, z);
|
||||
if (!this.framesContain(frames, pos, this.world.getBlockState(pos)))
|
||||
continue;
|
||||
|
||||
BlockPos up = pos.up();
|
||||
IBlockState state = this.world.getBlockState(up);
|
||||
if (state.getBlock().isReplaceable(this.world, up))
|
||||
validPositions.add(up);
|
||||
}
|
||||
if (validPositions.isEmpty())
|
||||
return;
|
||||
|
||||
for (int i = 0; i < handler.getSlots(); i++) {
|
||||
ItemStack stack = handler.extractItem(i, 1, true);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
|
||||
BlockPos pos = validPositions.get(this.world.rand.nextInt(validPositions.size()));
|
||||
ItemStack left = this.tryPlace(stack.copy(), pos);
|
||||
if (ItemStack.areItemStacksEqual(stack, left))
|
||||
continue;
|
||||
|
||||
handler.extractItem(i, 1, false);
|
||||
BlockPos spot = AuraChunk.getHighestSpot(this.world, this.pos, 10, this.pos);
|
||||
AuraChunk.getAuraChunk(this.world, spot).drainAura(spot, 10);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean framesContain(List<EntityItemFrame> frames, BlockPos pos, IBlockState state) {
|
||||
ItemStack stack = state.getBlock().getItem(this.world, pos, state);
|
||||
if (stack.isEmpty())
|
||||
return false;
|
||||
|
||||
for (EntityItemFrame frame : frames) {
|
||||
ItemStack frameStack = frame.getDisplayedItem();
|
||||
if (!frameStack.isEmpty() && stack.isItemEqual(frameStack))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ItemStack tryPlace(ItemStack stack, BlockPos pos) {
|
||||
if (this.handleSpecialCases(stack, pos))
|
||||
return stack;
|
||||
|
||||
if (!(this.world instanceof WorldServer))
|
||||
return stack;
|
||||
|
||||
FakePlayer fake = FakePlayerFactory.getMinecraft((WorldServer) this.world);
|
||||
fake.inventory.mainInventory.set(fake.inventory.currentItem, stack);
|
||||
fake.interactionManager.processRightClickBlock(fake, this.world, fake.getHeldItemMainhand(), EnumHand.MAIN_HAND,
|
||||
pos, EnumFacing.DOWN, 0.5F, 0.5F, 0.5F);
|
||||
return fake.getHeldItemMainhand().copy();
|
||||
}
|
||||
|
||||
private boolean handleSpecialCases(ItemStack stack, BlockPos pos) {
|
||||
if (stack.getItem() == Items.REDSTONE)
|
||||
this.world.setBlockState(pos, Blocks.REDSTONE_WIRE.getDefaultState());
|
||||
else if (stack.getItem() == Item.getItemFromBlock(ModBlocks.GOLD_POWDER))
|
||||
this.world.setBlockState(pos, ModBlocks.GOLD_POWDER.getDefaultState());
|
||||
else if (stack.getItem() instanceof IPlantable) {
|
||||
IPlantable plantable = (IPlantable) stack.getItem();
|
||||
IBlockState plant = plantable.getPlant(this.world, pos);
|
||||
if (!plant.getBlock().canPlaceBlockAt(this.world, pos))
|
||||
return false;
|
||||
this.world.setBlockState(pos, plant);
|
||||
} else
|
||||
return false;
|
||||
|
||||
stack.shrink(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemHandlerModifiable getItemHandler(EnumFacing facing) {
|
||||
return this.handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readNBT(NBTTagCompound compound, SaveType type) {
|
||||
super.readNBT(compound, type);
|
||||
if (type != SaveType.BLOCK)
|
||||
this.handler.deserializeNBT(compound.getCompoundTag("items"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNBT(NBTTagCompound compound, SaveType type) {
|
||||
super.writeNBT(compound, type);
|
||||
if (type != SaveType.BLOCK)
|
||||
compound.setTag("items", this.handler.serializeNBT());
|
||||
}
|
||||
}
|
|
@ -164,7 +164,8 @@ public class TileEntityWoodStand extends TileEntityImpl implements ITickable {
|
|||
@Override
|
||||
public void writeNBT(NBTTagCompound compound, SaveType type) {
|
||||
super.writeNBT(compound, type);
|
||||
compound.setTag("items", this.items.serializeNBT());
|
||||
if (type != SaveType.BLOCK)
|
||||
compound.setTag("items", this.items.serializeNBT());
|
||||
|
||||
if (type == SaveType.TILE) {
|
||||
if (this.ritualPos != null && this.recipe != null) {
|
||||
|
@ -178,7 +179,8 @@ public class TileEntityWoodStand extends TileEntityImpl implements ITickable {
|
|||
@Override
|
||||
public void readNBT(NBTTagCompound compound, SaveType type) {
|
||||
super.readNBT(compound, type);
|
||||
this.items.deserializeNBT(compound.getCompoundTag("items"));
|
||||
if (type != SaveType.BLOCK)
|
||||
this.items.deserializeNBT(compound.getCompoundTag("items"));
|
||||
|
||||
if (type == SaveType.TILE) {
|
||||
if (compound.hasKey("recipe")) {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"model": "minecraft:cube",
|
||||
"textures": {
|
||||
"particle": "naturesaura:blocks/placer",
|
||||
"up": "naturesaura:blocks/placer_top",
|
||||
"down": "naturesaura:blocks/placer_top",
|
||||
"north": "#particle",
|
||||
"east": "#particle",
|
||||
"south": "#particle",
|
||||
"west": "#particle"
|
||||
},
|
||||
"transform": "forge:default-block"
|
||||
},
|
||||
"variants": {
|
||||
"normal": [{}],
|
||||
"inventory": [{}]
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ tile.naturesaura.infused_brick_stairs.name=Infused Brick Stairs
|
|||
tile.naturesaura.infused_brick_slab.name=Infused Brick Slab
|
||||
tile.naturesaura.infused_brick_slab_double.name=Infused Brick Double Slab
|
||||
tile.naturesaura.flower_generator.name=Herbivorous Absorber
|
||||
tile.naturesaura.placer.name=Imperceptible Builder
|
||||
|
||||
item.naturesaura.eye.name=Environmental Eye
|
||||
item.naturesaura.gold_fiber.name=Brilliant Fiber
|
||||
|
|
BIN
src/main/resources/assets/naturesaura/textures/blocks/placer.png
Normal file
BIN
src/main/resources/assets/naturesaura/textures/blocks/placer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 592 B |
Binary file not shown.
After Width: | Height: | Size: 606 B |
Loading…
Reference in a new issue