4 Commits
0.2 ... 0.3

Author SHA1 Message Date
Christian Knaapen
bda53e4b08 Check if can break and replace blocks. Breaking only works if your current held tool can break it. Replace only works with blocks that can be harvested with your hand.
Damages used tool appropriately.
Added block outlines to mirror and array.
2018-10-20 16:15:14 +02:00
Christian Knaapen
821b46a253 Fixed shrinking itemstack with mirror/array when not using quickreplace.
Fixed replacing same blocks dropping extra.
2018-10-18 16:50:39 +02:00
Christian Knaapen
0e7d08438d Fixed randomizer bag not working with quickreplace. 2018-10-14 15:46:06 +02:00
Christian Knaapen
483d6cc53e Checks if placeBlock is allowed. Fixed stutter on line rendering. Added toggle for creative/survival mode. 2018-10-06 20:20:10 +02:00
11 changed files with 480 additions and 186 deletions

View File

@@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
version = "0.1.3" version = "0.2"
group = "nl.requios.effortlessbuilding" // http://maven.apache.org/guides/mini/guide-naming-conventions.html group = "nl.requios.effortlessbuilding" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "effortlessbuilding" archivesBaseName = "effortlessbuilding"

View File

@@ -2,17 +2,25 @@ package nl.requios.effortlessbuilding;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
@Mod.EventBusSubscriber
public class Array { public class Array {
//TODO config file //TODO config file
public static final int MAX_COUNT = 100; public static final int MAX_COUNT = 100;
@@ -22,7 +30,7 @@ public class Array {
public BlockPos offset = BlockPos.ORIGIN; public BlockPos offset = BlockPos.ORIGIN;
public int count = 5; public int count = 5;
public ArraySettings(){ public ArraySettings() {
} }
public ArraySettings(boolean enabled, BlockPos offset, int count) { public ArraySettings(boolean enabled, BlockPos offset, int count) {
@@ -33,14 +41,14 @@ public class Array {
} }
//Called from EventHandler //Called from EventHandler
public static void onBlockPlaced(BlockEvent.PlaceEvent event) { public static boolean onBlockPlaced(BlockEvent.PlaceEvent event) {
if (event.getWorld().isRemote) return; if (event.getWorld().isRemote) return false;
//find arraysettings for the player that placed the block //find arraysettings for the player that placed the block
ArraySettings a = BuildSettingsManager.getBuildSettings(event.getPlayer()).getArraySettings(); ArraySettings a = BuildSettingsManager.getBuildSettings(event.getPlayer()).getArraySettings();
if (a == null || !a.enabled) return; if (a == null || !a.enabled) return false;
if (a.offset.getX() == 0 && a.offset.getY() == 0 && a.offset.getZ() == 0) return; if (a.offset.getX() == 0 && a.offset.getY() == 0 && a.offset.getZ() == 0) return false;
BlockPos pos = event.getPos(); BlockPos pos = event.getPos();
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ()); Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
@@ -59,31 +67,28 @@ public class Array {
if (event.getWorld().isBlockLoaded(pos, true)) { if (event.getWorld().isBlockLoaded(pos, true)) {
if (itemStack.isEmpty()) break; if (itemStack.isEmpty()) break;
//Check if held block = placed block (otherwise its a bag or wand) IBlockState blockState = event.getPlacedBlock();
if (!event.getPlayer().isCreative() && Block.getBlockFromItem(itemStack.getItem()) == event.getPlacedBlock().getBlock()) {
itemStack.shrink(1);
}
//Randomizer bag synergy //Randomizer bag synergy
IBlockState blockState = bagInventory == null ? event.getPlacedBlock() : if (bagInventory != null) {
getBlockStateFromRandomizerBag(bagInventory, event.getWorld(), event.getPlayer(), event.getPos()); itemStack = ItemRandomizerBag.pickRandomStack(bagInventory);
if (itemStack.isEmpty()) continue;
blockState = getBlockStateFromRandomizerBag(bagInventory, event.getWorld(), event.getPlayer(), event.getPos(), itemStack);
if (blockState == null) continue;
}
//TODO check if can place (ItemBlock) and if can break replaced //TODO check if can place (ItemBlock) and if can break replaced
//Drop existing block SurvivalHelper.placeBlock(event.getWorld(), event.getPlayer(), pos, blockState, itemStack, EnumFacing.NORTH, true, false);
SurvivalHelper.dropBlock(event.getWorld(), pos, event.getPlayer());
event.getWorld().setBlockState(pos, blockState);
} }
} }
//EffortlessBuilding.log(event.getPlayer(), String.valueOf(event.getPlayer().getHeldItem(event.getHand()).getCount()));
return true;
} }
private static IBlockState getBlockStateFromRandomizerBag(IItemHandler bagInventory, World world, EntityPlayer player, BlockPos pos) { private static IBlockState getBlockStateFromRandomizerBag(IItemHandler bagInventory, World world, EntityPlayer player, BlockPos pos, ItemStack itemStack) {
int randomSlot = ItemRandomizerBag.pickRandomSlot(bagInventory);
ItemStack stack = bagInventory.getStackInSlot(randomSlot);
//TODO get facing from getPlacedAgainst and getPlacedBlock //TODO get facing from getPlacedAgainst and getPlacedBlock
return Block.getBlockFromItem(stack.getItem()).getStateForPlacement(world, pos, EnumFacing.NORTH, 0, 0, 0, stack.getMetadata(), player, EnumHand.MAIN_HAND); return Block.getBlockFromItem(itemStack.getItem()).getStateForPlacement(world, pos, EnumFacing.NORTH, 0, 0, 0, itemStack.getMetadata(), player, EnumHand.MAIN_HAND);
} }
//Called from EventHandler //Called from EventHandler
@@ -100,14 +105,46 @@ public class Array {
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ()); Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
for (int i = 0; i < a.count; i++) { for (int i = 0; i < a.count; i++) {
pos = pos.add(offset); pos = pos.add(offset);
if (event.getWorld().isBlockLoaded(pos, false)) { SurvivalHelper.breakBlock(event.getWorld(), event.getPlayer(), pos);
//TODO check if can break }
}
//Drop existing block @SubscribeEvent
SurvivalHelper.dropBlock(event.getWorld(), pos, event.getPlayer()); @SideOnly(Side.CLIENT)
public static void onRender(RenderWorldLastEvent event) {
EntityPlayer player = Minecraft.getMinecraft().player;
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
if (buildSettings == null) return;
ArraySettings a = buildSettings.getArraySettings();
event.getWorld().setBlockToAir(pos); if (a == null || !a.enabled || (a.offset.getX() == 0 && a.offset.getY() == 0 && a.offset.getZ() == 0)) return;
}
RenderHelper.begin(event.getPartialTicks());
//Render block outlines
RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver;
if (objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK)
{
BlockPos blockPos = objectMouseOver.getBlockPos();
if (!buildSettings.doQuickReplace()) blockPos = blockPos.offset(objectMouseOver.sideHit);
drawBlockOutlines(a, blockPos);
}
RenderHelper.end();
}
@SideOnly(Side.CLIENT)
public static void drawBlockOutlines(ArraySettings a, BlockPos pos) {
if (a == null || !a.enabled || (a.offset.getX() == 0 && a.offset.getY() == 0 && a.offset.getZ() == 0)) return;
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
//RenderHelper.renderBlockOutline(blockPos);
for (int i = 0; i < a.count; i++)
{
pos = pos.add(offset);
RenderHelper.renderBlockOutline(pos);
} }
} }
} }

View File

@@ -29,7 +29,7 @@ public class EffortlessBuilding
{ {
public static final String MODID = "effortlessbuilding"; public static final String MODID = "effortlessbuilding";
public static final String NAME = "Effortless Building"; public static final String NAME = "Effortless Building";
public static final String VERSION = "0.1.3"; public static final String VERSION = "0.2";
@Mod.Instance(EffortlessBuilding.MODID) @Mod.Instance(EffortlessBuilding.MODID)
public static EffortlessBuilding instance; public static EffortlessBuilding instance;

View File

@@ -1,23 +1,31 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import nl.requios.effortlessbuilding.capability.BuildModifierCapability; import nl.requios.effortlessbuilding.capability.BuildModifierCapability;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class EventHandler public class EventHandler
{ {
private static boolean placedBlock = false;
private static BlockEvent.PlaceEvent placeEvent = null;
@SubscribeEvent @SubscribeEvent
public static void registerBlocks(RegistryEvent.Register<Block> event) public static void registerBlocks(RegistryEvent.Register<Block> event)
{ {
@@ -42,15 +50,28 @@ public class EventHandler
} }
} }
@SubscribeEvent
public static void onServerTick(TickEvent.ServerTickEvent event) {
if (placedBlock) {
placedBlock = false;
Mirror.onBlockPlaced(placeEvent);
Array.onBlockPlaced(placeEvent);
}
}
@SubscribeEvent @SubscribeEvent
public static void onBlockPlaced(BlockEvent.PlaceEvent event) { public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
QuickReplace.onBlockPlaced(event); if (QuickReplace.onBlockPlaced(event)) {
if (event.isCanceled()) return; event.setCanceled(true);
Mirror.onBlockPlaced(event); return;
Array.onBlockPlaced(event); }
}
//Delay mirror and array by a tick so we can edit the held itemstack
//Otherwise the itemstack count would be overridden by ItemBlock#onItemUse
placedBlock = true;
placeEvent = event;
}
@SubscribeEvent @SubscribeEvent
public static void onBlockBroken(BlockEvent.BreakEvent event) { public static void onBlockBroken(BlockEvent.BreakEvent event) {

View File

@@ -3,6 +3,7 @@ package nl.requios.effortlessbuilding;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -11,6 +12,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.client.event.RenderWorldLastEvent;
@@ -62,14 +64,14 @@ public class Mirror {
} }
//Called from EventHandler //Called from EventHandler
public static void onBlockPlaced(BlockEvent.PlaceEvent event) { public static boolean onBlockPlaced(BlockEvent.PlaceEvent event) {
if (event.getWorld().isRemote) return; if (event.getWorld().isRemote) return false;
//find mirrorsettings for the player that placed the block //find mirrorsettings for the player that placed the block
MirrorSettings m = BuildSettingsManager.getBuildSettings(event.getPlayer()).getMirrorSettings(); MirrorSettings m = BuildSettingsManager.getBuildSettings(event.getPlayer()).getMirrorSettings();
if (m == null) return; if (m == null) return false;
if (!m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return; if (!m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return false;
//if within mirror distance, mirror //if within mirror distance, mirror
BlockPos oldBlockPos = event.getPos(); BlockPos oldBlockPos = event.getPos();
@@ -77,7 +79,9 @@ public class Mirror {
if (oldBlockPos.getX() + 0.5 < m.position.x - m.radius || oldBlockPos.getX() + 0.5 > m.position.x + m.radius || if (oldBlockPos.getX() + 0.5 < m.position.x - m.radius || oldBlockPos.getX() + 0.5 > m.position.x + m.radius ||
oldBlockPos.getY() + 0.5 < m.position.y - m.radius || oldBlockPos.getY() + 0.5 > m.position.y + m.radius || oldBlockPos.getY() + 0.5 < m.position.y - m.radius || oldBlockPos.getY() + 0.5 > m.position.y + m.radius ||
oldBlockPos.getZ() + 0.5 < m.position.z - m.radius || oldBlockPos.getZ() + 0.5 > m.position.z + m.radius) oldBlockPos.getZ() + 0.5 < m.position.z - m.radius || oldBlockPos.getZ() + 0.5 > m.position.z + m.radius)
return; return false;
ItemStack itemStack = event.getPlayer().getHeldItem(event.getHand());
//Randomizer bag synergy //Randomizer bag synergy
IItemHandler bagInventory = null; IItemHandler bagInventory = null;
@@ -86,91 +90,93 @@ public class Mirror {
} }
if (m.mirrorX) { if (m.mirrorX) {
placeMirrorX(event.getWorld(), event.getPlayer(), m, event.getPos(), event.getPlacedBlock(), bagInventory); placeMirrorX(event.getWorld(), event.getPlayer(), m, event.getPos(), event.getPlacedBlock(), bagInventory, itemStack);
} }
if (m.mirrorY) { if (m.mirrorY) {
placeMirrorY(event.getWorld(), event.getPlayer(), m, oldBlockPos, event.getPlacedBlock(), bagInventory); placeMirrorY(event.getWorld(), event.getPlayer(), m, oldBlockPos, event.getPlacedBlock(), bagInventory, itemStack);
} }
if (m.mirrorZ) { if (m.mirrorZ) {
placeMirrorZ(event.getWorld(), event.getPlayer(), m, oldBlockPos, event.getPlacedBlock(), bagInventory); placeMirrorZ(event.getWorld(), event.getPlayer(), m, oldBlockPos, event.getPlacedBlock(), bagInventory, itemStack);
} }
return true;
} }
private static IBlockState getBlockStateFromRandomizerBag(IItemHandler bagInventory, World world, EntityPlayer player, BlockPos pos) { private static void placeMirrorX(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState, IItemHandler bagInventory, ItemStack itemStack) {
int randomSlot = ItemRandomizerBag.pickRandomSlot(bagInventory);
ItemStack stack = bagInventory.getStackInSlot(randomSlot);
//TODO get facing from getPlacedAgainst and getPlacedBlock
return Block.getBlockFromItem(stack.getItem()).getStateForPlacement(world, pos, EnumFacing.NORTH, 0, 0, 0, stack.getMetadata(), player, EnumHand.MAIN_HAND);
}
private static void placeMirrorX(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState, IItemHandler bagInventory) {
//find mirror position //find mirror position
double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5); double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5);
BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ()); BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ());
//Randomizer bag synergy //Randomizer bag synergy
if (bagInventory != null) if (bagInventory != null) {
oldBlockState = getBlockStateFromRandomizerBag(bagInventory, world, player, oldBlockPos); itemStack = ItemRandomizerBag.pickRandomStack(bagInventory);
if (itemStack.isEmpty()) return;
oldBlockState = getBlockStateFromRandomizerBag(bagInventory, world, player, oldBlockPos, itemStack);
if (oldBlockState == null) return;
}
IBlockState newBlockState = oldBlockState.withMirror(net.minecraft.util.Mirror.FRONT_BACK); IBlockState newBlockState = oldBlockState.withMirror(net.minecraft.util.Mirror.FRONT_BACK);
//place block //place block
if (world.isBlockLoaded(newBlockPos, true)) { if (world.isBlockLoaded(newBlockPos, true)) {
placeBlock(world, player, newBlockPos, newBlockState); placeBlock(world, player, newBlockPos, newBlockState, itemStack);
} }
if (m.mirrorY) placeMirrorY(world, player, m, newBlockPos, newBlockState, bagInventory); if (m.mirrorY) placeMirrorY(world, player, m, newBlockPos, newBlockState, bagInventory, itemStack);
if (m.mirrorZ) placeMirrorZ(world, player, m, newBlockPos, newBlockState, bagInventory); if (m.mirrorZ) placeMirrorZ(world, player, m, newBlockPos, newBlockState, bagInventory, itemStack);
} }
private static void placeMirrorY(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState, IItemHandler bagInventory) { private static void placeMirrorY(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState, IItemHandler bagInventory, ItemStack itemStack) {
//find mirror position //find mirror position
double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5); double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5);
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ()); BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ());
//Randomizer bag synergy //Randomizer bag synergy
if (bagInventory != null) if (bagInventory != null) {
oldBlockState = getBlockStateFromRandomizerBag(bagInventory, world, player, oldBlockPos); itemStack = ItemRandomizerBag.pickRandomStack(bagInventory);
if (itemStack.isEmpty()) return;
oldBlockState = getBlockStateFromRandomizerBag(bagInventory, world, player, oldBlockPos, itemStack);
if (oldBlockState == null) return;
}
IBlockState newBlockState = getVerticalMirror(oldBlockState); IBlockState newBlockState = getVerticalMirror(oldBlockState);
//place block //place block
if (world.isBlockLoaded(newBlockPos, true)) { if (world.isBlockLoaded(newBlockPos, true)) {
placeBlock(world, player, newBlockPos, newBlockState); placeBlock(world, player, newBlockPos, newBlockState, itemStack);
} }
if (m.mirrorZ) placeMirrorZ(world, player, m, newBlockPos, newBlockState, bagInventory); if (m.mirrorZ) placeMirrorZ(world, player, m, newBlockPos, newBlockState, bagInventory, itemStack);
} }
private static void placeMirrorZ(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState, IItemHandler bagInventory) { private static void placeMirrorZ(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState, IItemHandler bagInventory, ItemStack itemStack) {
//find mirror position //find mirror position
double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5); double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5);
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z); BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z);
//Randomizer bag synergy //Randomizer bag synergy
if (bagInventory != null) if (bagInventory != null) {
oldBlockState = getBlockStateFromRandomizerBag(bagInventory, world, player, oldBlockPos); itemStack = ItemRandomizerBag.pickRandomStack(bagInventory);
if (itemStack.isEmpty()) return;
oldBlockState = getBlockStateFromRandomizerBag(bagInventory, world, player, oldBlockPos, itemStack);
if (oldBlockState == null) return;
}
IBlockState newBlockState = oldBlockState.withMirror(net.minecraft.util.Mirror.LEFT_RIGHT); IBlockState newBlockState = oldBlockState.withMirror(net.minecraft.util.Mirror.LEFT_RIGHT);
//place block //place block
if (world.isBlockLoaded(newBlockPos, true)) { if (world.isBlockLoaded(newBlockPos, true)) {
placeBlock(world, player, newBlockPos, newBlockState); placeBlock(world, player, newBlockPos, newBlockState, itemStack);
} }
} }
private static void placeBlock(World world, EntityPlayer player, BlockPos newBlockPos, IBlockState newBlockState) { private static IBlockState getBlockStateFromRandomizerBag(IItemHandler bagInventory, World world, EntityPlayer player, BlockPos pos, ItemStack itemStack) {
//Check itemstack //TODO get facing from getPlacedAgainst and getPlacedBlock
ItemStack itemStack = player.getHeldItem(player.swingingHand); //TODO check hand return Block.getBlockFromItem(itemStack.getItem()).getStateForPlacement(world, pos, EnumFacing.NORTH, 0, 0, 0, itemStack.getMetadata(), player, EnumHand.MAIN_HAND);
if (itemStack.isEmpty()) return; }
private static void placeBlock(World world, EntityPlayer player, BlockPos newBlockPos, IBlockState newBlockState, ItemStack itemStack) {
//TODO check if can place //TODO check if can place
//TODO check if can break //TODO check if can break
SurvivalHelper.dropBlock(world, newBlockPos, player); SurvivalHelper.placeBlock(world, player, newBlockPos, newBlockState, itemStack, EnumFacing.NORTH, true, false);
world.setBlockState(newBlockPos, newBlockState);
//Check if held block = placed block (otherwise its a bag or wand)
if (!player.isCreative() && Block.getBlockFromItem(itemStack.getItem()) == newBlockState.getBlock()) {
itemStack.shrink(1);
}
//Array synergy //Array synergy
BlockSnapshot blockSnapshot = new BlockSnapshot(world, newBlockPos, newBlockState); BlockSnapshot blockSnapshot = new BlockSnapshot(world, newBlockPos, newBlockState);
@@ -255,9 +261,7 @@ public class Mirror {
double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5); double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5);
BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ()); BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ());
//break block //break block
if (event.getWorld().isBlockLoaded(newBlockPos, true)) { breakBlock(event, newBlockPos);
breakBlock(event, newBlockPos);
}
if (m.mirrorY) breakMirrorY(event, m, newBlockPos); if (m.mirrorY) breakMirrorY(event, m, newBlockPos);
if (m.mirrorZ) breakMirrorZ(event, m, newBlockPos); if (m.mirrorZ) breakMirrorZ(event, m, newBlockPos);
} }
@@ -266,10 +270,8 @@ public class Mirror {
//find mirror position //find mirror position
double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5); double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5);
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ()); BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ());
//place block //break block
if (event.getWorld().isBlockLoaded(newBlockPos, true)) { breakBlock(event, newBlockPos);
breakBlock(event, newBlockPos);
}
if (m.mirrorZ) breakMirrorZ(event, m, newBlockPos); if (m.mirrorZ) breakMirrorZ(event, m, newBlockPos);
} }
@@ -277,17 +279,14 @@ public class Mirror {
//find mirror position //find mirror position
double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5); double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5);
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z); BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z);
//place block //break block
if (event.getWorld().isBlockLoaded(newBlockPos, true)) { breakBlock(event, newBlockPos);
breakBlock(event, newBlockPos);
}
} }
private static void breakBlock(BlockEvent.BreakEvent event, BlockPos newBlockPos) { private static void breakBlock(BlockEvent.BreakEvent event, BlockPos newBlockPos) {
//TODO check if can break if (!event.getWorld().isBlockLoaded(newBlockPos, false)) return;
SurvivalHelper.dropBlock(event.getWorld(), newBlockPos, event.getPlayer()); SurvivalHelper.breakBlock(event.getWorld(), event.getPlayer(), newBlockPos);
event.getWorld().setBlockToAir(newBlockPos);
//Array synergy //Array synergy
BlockEvent.BreakEvent breakEvent = new BlockEvent.BreakEvent(event.getWorld(), newBlockPos, event.getState(), event.getPlayer()); BlockEvent.BreakEvent breakEvent = new BlockEvent.BreakEvent(event.getWorld(), newBlockPos, event.getState(), event.getPlayer());
@@ -304,7 +303,8 @@ public class Mirror {
if (m == null || !m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return; if (m == null || !m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return;
Vec3d playerPos = new Vec3d(player.posX, player.posY, player.posZ); RenderHelper.begin(event.getPartialTicks());
Vec3d pos = m.position.add(epsilon); Vec3d pos = m.position.add(epsilon);
int radius = m.radius; int radius = m.radius;
@@ -312,44 +312,47 @@ public class Mirror {
Vec3d posA = new Vec3d(pos.x, pos.y - radius, pos.z - radius); Vec3d posA = new Vec3d(pos.x, pos.y - radius, pos.z - radius);
Vec3d posB = new Vec3d(pos.x, pos.y + radius, pos.z + radius); Vec3d posB = new Vec3d(pos.x, pos.y + radius, pos.z + radius);
drawMirrorPlane(playerPos, posA, posB, colorX, m.drawLines, m.drawPlanes); drawMirrorPlane(posA, posB, colorX, m.drawLines, m.drawPlanes);
} }
if (m.mirrorY) { if (m.mirrorY) {
Vec3d posA = new Vec3d(pos.x - radius, pos.y, pos.z - radius); Vec3d posA = new Vec3d(pos.x - radius, pos.y, pos.z - radius);
Vec3d posB = new Vec3d(pos.x + radius, pos.y, pos.z + radius); Vec3d posB = new Vec3d(pos.x + radius, pos.y, pos.z + radius);
drawMirrorPlaneY(playerPos, posA, posB, colorY, m.drawLines, m.drawPlanes); drawMirrorPlaneY(posA, posB, colorY, m.drawLines, m.drawPlanes);
} }
if (m.mirrorZ) { if (m.mirrorZ) {
Vec3d posA = new Vec3d(pos.x - radius, pos.y - radius, pos.z); Vec3d posA = new Vec3d(pos.x - radius, pos.y - radius, pos.z);
Vec3d posB = new Vec3d(pos.x + radius, pos.y + radius, pos.z); Vec3d posB = new Vec3d(pos.x + radius, pos.y + radius, pos.z);
drawMirrorPlane(playerPos, posA, posB, colorZ, m.drawLines, m.drawPlanes); drawMirrorPlane(posA, posB, colorZ, m.drawLines, m.drawPlanes);
} }
//Draw axis coordinated colors if two or more axes are enabled //Draw axis coordinated colors if two or more axes are enabled
//(If only one is enabled the lines are that planes color) //(If only one is enabled the lines are that planes color)
if (m.drawLines && ((m.mirrorX && m.mirrorY) || (m.mirrorX && m.mirrorZ) || (m.mirrorY && m.mirrorZ))) { if (m.drawLines && ((m.mirrorX && m.mirrorY) || (m.mirrorX && m.mirrorZ) || (m.mirrorY && m.mirrorZ))) {
drawMirrorLines(playerPos, m); drawMirrorLines(m);
} }
//Render block outlines
RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver;
if (objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK)
{
BlockPos blockPos = objectMouseOver.getBlockPos();
if (!buildSettings.doQuickReplace()) blockPos = blockPos.offset(objectMouseOver.sideHit);
//RenderHelper.renderBlockOutline(blockPos);
if (m.mirrorX) drawBlockOutlineX(buildSettings, blockPos);
if (m.mirrorY) drawBlockOutlineY(buildSettings, blockPos);
if (m.mirrorZ) drawBlockOutlineZ(buildSettings, blockPos);
}
RenderHelper.end();
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static void drawMirrorPlane(Vec3d playerPos, Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) { public static void drawMirrorPlane(Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) {
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glTranslated(-playerPos.x, -playerPos.y, -playerPos.z);
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha);
GL11.glLineWidth(2);
GL11.glDepthMask(false);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer(); BufferBuilder bufferBuilder = tessellator.getBuffer();
@@ -375,28 +378,12 @@ public class Mirror {
tessellator.draw(); tessellator.draw();
} }
GL11.glDepthMask(true);
GL11.glPopMatrix();
GL11.glPopAttrib();
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static void drawMirrorPlaneY(Vec3d playerPos, Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) { public static void drawMirrorPlaneY(Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) {
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glTranslated(-playerPos.x, -playerPos.y, -playerPos.z);
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
GL11.glLineWidth(2);
GL11.glDepthMask(false);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer(); BufferBuilder bufferBuilder = tessellator.getBuffer();
@@ -422,30 +409,15 @@ public class Mirror {
tessellator.draw(); tessellator.draw();
} }
GL11.glDepthMask(true);
GL11.glPopMatrix();
GL11.glPopAttrib();
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static void drawMirrorLines(Vec3d playerPos, MirrorSettings m) { public static void drawMirrorLines(MirrorSettings m) {
Vec3d pos = m.position.add(epsilon); Vec3d pos = m.position.add(epsilon);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glTranslated(-playerPos.x, -playerPos.y, -playerPos.z);
GL11.glColor4d(100, 100, 100, 255); GL11.glColor4d(100, 100, 100, 255);
GL11.glLineWidth(2); GL11.glLineWidth(2);
GL11.glDepthMask(false);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer(); BufferBuilder bufferBuilder = tessellator.getBuffer();
@@ -459,11 +431,50 @@ public class Mirror {
bufferBuilder.pos(pos.x, pos.y, pos.z + m.radius).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex(); bufferBuilder.pos(pos.x, pos.y, pos.z + m.radius).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex();
tessellator.draw(); tessellator.draw();
GL11.glDepthMask(true);
GL11.glPopMatrix();
GL11.glPopAttrib();
} }
@SideOnly(Side.CLIENT)
public static void drawBlockOutlineX(BuildSettingsManager.BuildSettings buildSettings, BlockPos oldBlockPos) {
MirrorSettings m = buildSettings.getMirrorSettings();
//find mirror position
double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5);
BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ());
RenderHelper.renderBlockOutline(newBlockPos);
//Array synergy
Array.drawBlockOutlines(buildSettings.getArraySettings(), newBlockPos);
if (m.mirrorY) drawBlockOutlineY(buildSettings, newBlockPos);
if (m.mirrorZ) drawBlockOutlineZ(buildSettings, newBlockPos);
}
@SideOnly(Side.CLIENT)
public static void drawBlockOutlineY(BuildSettingsManager.BuildSettings buildSettings, BlockPos oldBlockPos) {
MirrorSettings m = buildSettings.getMirrorSettings();
//find mirror position
double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5);
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ());
RenderHelper.renderBlockOutline(newBlockPos);
//Array synergy
Array.drawBlockOutlines(buildSettings.getArraySettings(), newBlockPos);
if (m.mirrorZ) drawBlockOutlineZ(buildSettings, newBlockPos);
}
@SideOnly(Side.CLIENT)
public static void drawBlockOutlineZ(BuildSettingsManager.BuildSettings buildSettings, BlockPos oldBlockPos) {
MirrorSettings m = buildSettings.getMirrorSettings();
//find mirror position
double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5);
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z);
RenderHelper.renderBlockOutline(newBlockPos);
//Array synergy
Array.drawBlockOutlines(buildSettings.getArraySettings(), newBlockPos);
}
} }

View File

@@ -1,6 +1,5 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
@@ -19,26 +18,28 @@ public class QuickReplace {
//Dilemma in getting blockstate from event to when message is received: //Dilemma in getting blockstate from event to when message is received:
// 1) send via client. Then hacking makes it possible to place any block. // 1) send via client. Then hacking makes it possible to place any block.
// 2) save serverside. Messages may not be received chronologically so data could get switched. // 2) save serverside. Messages may not be received chronologically so data could get switched.
//Solution for now: save blockstate per player. Messages from 1 player will rarely come unchronologically //Solution for now: save data serverside and per player. Messages from 1 player will rarely come unchronologically
//and players will rarely switch between blocks that quickly. //and players will rarely switch between blocks that quickly.
private static Dictionary<UUID, IBlockState> blockStates = new Hashtable<>(); private static Dictionary<UUID, IBlockState> blockStates = new Hashtable<>();
private static Dictionary<UUID, ItemStack> itemStacks = new Hashtable<>();
public static void onBlockPlaced(BlockEvent.PlaceEvent event) { public static boolean onBlockPlaced(BlockEvent.PlaceEvent event) {
if (event.getWorld().isRemote) return; if (event.getWorld().isRemote) return true;
//Only serverside //Only serverside
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(event.getPlayer()); BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(event.getPlayer());
if (!buildSettings.doQuickReplace()) return; if (!buildSettings.doQuickReplace()) return false;
//TODO base on player facing instead, no more messages (or break block clientside) //TODO base on player facing instead, no more messages (or break block clientside)
blockStates.put(event.getPlayer().getUniqueID(), event.getPlacedBlock()); blockStates.put(event.getPlayer().getUniqueID(), event.getPlacedBlock());
itemStacks.put(event.getPlayer().getUniqueID(), event.getPlayer().getHeldItem(event.getHand()));
//RayTraceResult result = event.getWorld().rayTraceBlocks(event.getPlayer().getPositionEyes(1f), event.getPlayer().getLookVec()); //RayTraceResult result = event.getWorld().rayTraceBlocks(event.getPlayer().getPositionEyes(1f), event.getPlayer().getLookVec());
EffortlessBuilding.packetHandler.sendTo(new QuickReplaceMessage(), (EntityPlayerMP) event.getPlayer()); EffortlessBuilding.packetHandler.sendTo(new QuickReplaceMessage(), (EntityPlayerMP) event.getPlayer());
event.setCanceled(true); return true;
} }
public static void onMessageReceived(EntityPlayer player, QuickReplaceMessage message) { public static void onMessageReceived(EntityPlayer player, QuickReplaceMessage message) {
@@ -57,15 +58,9 @@ public class QuickReplace {
} }
IBlockState blockState = blockStates.get(player.getUniqueID()); IBlockState blockState = blockStates.get(player.getUniqueID());
ItemStack itemStack = itemStacks.get(player.getUniqueID());
SurvivalHelper.dropBlock(player.world, placedAgainstBlockPos, player); SurvivalHelper.placeBlock(player.world, player, placedAgainstBlockPos, blockState, itemStack, message.getSideHit(), true, false);
player.world.setBlockState(placedAgainstBlockPos, blockState);
//Shrink itemstack with 1
ItemStack itemStack = player.getHeldItem(player.swingingHand); //TODO check hand
if (!player.isCreative() && Block.getBlockFromItem(itemStack.getItem()) == blockState.getBlock()) {
itemStack.shrink(1);
}
//Mirror and Array synergy //Mirror and Array synergy
BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, placedAgainstBlockPos, blockState); BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, placedAgainstBlockPos, blockState);

View File

@@ -0,0 +1,60 @@
package nl.requios.effortlessbuilding;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Color;
@SideOnly(Side.CLIENT)
public class RenderHelper {
public static void begin(float partialTicks) {
EntityPlayer player = Minecraft.getMinecraft().player;
double playerX = player.prevPosX + (player.posX - player.prevPosX) * partialTicks;
double playerY = player.prevPosY + (player.posY - player.prevPosY) * partialTicks;
double playerZ = player.prevPosZ + (player.posZ - player.prevPosZ) * partialTicks;
Vec3d playerPos = new Vec3d(playerX, playerY, playerZ);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glTranslated(-playerPos.x, -playerPos.y, -playerPos.z);
GL11.glLineWidth(2);
GL11.glDepthMask(false);
}
public static void end() {
GL11.glDepthMask(true);
GL11.glPopMatrix();
GL11.glPopAttrib();
}
public static void renderBlockOutline(BlockPos pos) {
renderBlockOutline(pos, pos);
}
//Renders outline. Pos1 has to be minimal x,y,z and pos2 maximal x,y,z
public static void renderBlockOutline(BlockPos pos1, BlockPos pos2) {
GL11.glLineWidth(2);
AxisAlignedBB aabb = new AxisAlignedBB(pos1, pos2.add(1, 1, 1)).grow(0.0020000000949949026);
RenderGlobal.drawSelectionBoundingBox(aabb, 1f, 1f, 1f, 0.6f);
}
}

View File

@@ -1,27 +1,129 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import javax.annotation.Nullable;
import java.util.List; import java.util.List;
public class SurvivalHelper { public class SurvivalHelper {
public static boolean canBreak(){ //Used for all placing of blocks in this mod.
return true; //Checks if area is loaded, if player has the right permissions, if existing block can be replaced (drops it if so) and consumes an item from the stack.
//Based on ItemBlock#onItemUse
public static boolean placeBlock(World world, EntityPlayer player, BlockPos pos, IBlockState blockState, ItemStack itemstack, EnumFacing facing, boolean skipCollisionCheck, boolean playSound) {
if (!world.isBlockLoaded(pos, true)) return false;
//Randomizer bag synergy
//Find itemstack that belongs to the blockstate
if (itemstack.getItem() == EffortlessBuilding.ITEM_RANDOMIZER_BAG) {
IItemHandler bagInventory = ItemRandomizerBag.getBagInventory(itemstack);
itemstack = ItemRandomizerBag.findStack(bagInventory, Item.getItemFromBlock(blockState.getBlock()));
}
//Check if itemstack is correct
if (!(itemstack.getItem() instanceof ItemBlock) || Block.getBlockFromItem(itemstack.getItem()) != blockState.getBlock()) {
EffortlessBuilding.log(player, "Cannot replace block", true);
EffortlessBuilding.log("SurvivalHelper#placeBlock: itemstack " + itemstack.toString() + " does not match blockstate " + blockState.toString());
return false;
}
Block block = ((ItemBlock) itemstack.getItem()).getBlock();
if (!itemstack.isEmpty() && canPlayerEdit(player, world, pos, itemstack) &&
mayPlace(world, block, blockState, pos, skipCollisionCheck, facing.getOpposite(), player) &&
canReplace(world, player, pos))
{
//Drop existing block
//TODO check if can replace
dropBlock(world, player, pos);
//From ItemBlock#placeBlockAt
if (!world.setBlockState(pos, blockState, 11)) return false;
IBlockState state = world.getBlockState(pos);
if (state.getBlock() == block)
{
((ItemBlock) itemstack.getItem()).setTileEntityNBT(world, player, pos, itemstack);
block.onBlockPlacedBy(world, pos, state, player, itemstack);
// if (player instanceof EntityPlayerMP)
// CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)player, pos, itemstack);
}
if (playSound) {
SoundType soundtype = state.getBlock().getSoundType(state, world, pos, player);
world.playSound(null, pos, soundtype.getPlaceSound(), SoundCategory.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F);
}
if (!player.isCreative() && Block.getBlockFromItem(itemstack.getItem()) == block) {
itemstack.shrink(1);
}
return true;
}
return false;
} }
public static boolean canPlace(){ //Used for all breaking of blocks in this mod.
return true; //Checks if area is loaded, if appropriate tool is used in survival mode, and drops the block directly into the players inventory
public static boolean breakBlock(World world, EntityPlayer player, BlockPos pos) {
if (!world.isBlockLoaded(pos, false)) return false;
//Check if can break
if (canBreak(world, player, pos))
{
//Drop existing block
dropBlock(world, player, pos);
//Damage tool
player.getHeldItemMainhand().onBlockDestroyed(world, world.getBlockState(pos), pos, player);
world.setBlockToAir(pos);
return true;
}
return false;
}
//Can break using held tool? (or in creative)
public static boolean canBreak(World world, EntityPlayer player, BlockPos pos) {
if (player.isCreative()) return true;
IBlockState blockState = world.getBlockState(pos);
if (blockState.getBlock().canHarvestBlock(world, pos, player)) return true;
return false;
}
//Can be harvested with hand? (or in creative)
public static boolean canReplace(World world, EntityPlayer player, BlockPos pos){
if (player.isCreative()) return true;
IBlockState state = world.getBlockState(pos);
state = state.getBlock().getActualState(state, world, pos);
if (state.getMaterial().isToolNotRequired()) return true;
return false;
} }
//Gives items directly to player //Gives items directly to player
public static void dropBlock(World world, BlockPos pos, EntityPlayer player){ public static void dropBlock(World world, EntityPlayer player, BlockPos pos){
if (player.isCreative()) return; if (player.isCreative()) return;
IBlockState blockState = world.getBlockState(pos); IBlockState blockState = world.getBlockState(pos);
@@ -32,4 +134,46 @@ public class SurvivalHelper {
ItemHandlerHelper.giveItemToPlayer(player, drop); ItemHandlerHelper.giveItemToPlayer(player, drop);
} }
} }
//From EntityPlayer#canPlayerEdit
private static boolean canPlayerEdit(EntityPlayer player, World world, BlockPos pos, ItemStack stack)
{
if (player.capabilities.allowEdit)
{
return true;
}
else
{
Block block = world.getBlockState(pos).getBlock();
return stack.canPlaceOn(block) || stack.canEditBlocks();
}
}
//From World#mayPlace
private static boolean mayPlace(World world, Block blockIn, IBlockState newBlockState, BlockPos pos, boolean skipCollisionCheck, EnumFacing sidePlacedOn, @Nullable Entity placer)
{
IBlockState iblockstate1 = world.getBlockState(pos);
AxisAlignedBB axisalignedbb = skipCollisionCheck ? null : blockIn.getDefaultState().getCollisionBoundingBox(world, pos);
if (axisalignedbb != Block.NULL_AABB && !world.checkNoEntityCollision(axisalignedbb.offset(pos), placer))
{
return false;
}
//Check if same block
//Necessary otherwise extra items will be dropped
if (iblockstate1 == newBlockState) {
return false;
}
if (iblockstate1.getMaterial() == Material.CIRCUITS && blockIn == Blocks.ANVIL)
{
return true;
}
//TODO check config for allow to replace
return true;
//TODO fix check canPlaceBlockOnSide
//return /*iblockstate1.getBlock().isReplaceable(world, pos) &&*/ blockIn.canPlaceBlockOnSide(world, pos, sidePlacedOn);
}
} }

View File

@@ -6,6 +6,7 @@ import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs; import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
@@ -20,9 +21,11 @@ import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import nl.requios.effortlessbuilding.Array; import nl.requios.effortlessbuilding.Array;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.Mirror; import nl.requios.effortlessbuilding.Mirror;
import nl.requios.effortlessbuilding.SurvivalHelper;
import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider; import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -40,7 +43,7 @@ public class ItemRandomizerBag extends Item {
this.setUnlocalizedName(this.getRegistryName().toString()); this.setUnlocalizedName(this.getRegistryName().toString());
this.maxStackSize = 1; this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.DECORATIONS); this.setCreativeTab(CreativeTabs.TOOLS);
} }
@Override @Override
@@ -59,11 +62,7 @@ public class ItemRandomizerBag extends Item {
if (bagInventory == null) if (bagInventory == null)
return EnumActionResult.FAIL; return EnumActionResult.FAIL;
int randomSlot = pickRandomSlot(bagInventory); ItemStack toPlace = pickRandomStack(bagInventory);
if (randomSlot < 0 || randomSlot > bagInventory.getSlots()) return EnumActionResult.FAIL;
ItemStack toPlace = bagInventory.getStackInSlot(randomSlot);
if (toPlace.isEmpty()) return EnumActionResult.FAIL; if (toPlace.isEmpty()) return EnumActionResult.FAIL;
//Previously: use onItemUse to place block (no synergy) //Previously: use onItemUse to place block (no synergy)
@@ -76,13 +75,15 @@ public class ItemRandomizerBag extends Item {
IBlockState blockState = Block.getBlockFromItem(toPlace.getItem()).getStateForPlacement(world, pos, facing, IBlockState blockState = Block.getBlockFromItem(toPlace.getItem()).getStateForPlacement(world, pos, facing,
hitX, hitY, hitZ, toPlace.getMetadata(), player, hand); hitX, hitY, hitZ, toPlace.getMetadata(), player, hand);
world.setBlockState(pos, blockState);
SurvivalHelper.placeBlock(world, player, pos, blockState, toPlace, facing, false, true);
//Synergy //Synergy
BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, pos, blockState); //Works without calling
BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, hand); // BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, pos, blockState);
Mirror.onBlockPlaced(placeEvent); // BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, hand);
Array.onBlockPlaced(placeEvent); // Mirror.onBlockPlaced(placeEvent);
// Array.onBlockPlaced(placeEvent);
} }
return EnumActionResult.SUCCESS; return EnumActionResult.SUCCESS;
} }
@@ -102,11 +103,7 @@ public class ItemRandomizerBag extends Item {
if (bagInventory == null) if (bagInventory == null)
return new ActionResult<>(EnumActionResult.FAIL, player.getHeldItem(hand)); return new ActionResult<>(EnumActionResult.FAIL, player.getHeldItem(hand));
int randomSlot = pickRandomSlot(bagInventory); ItemStack toUse = pickRandomStack(bagInventory);
if (randomSlot < 0 || randomSlot > bagInventory.getSlots())
return new ActionResult<>(EnumActionResult.FAIL, player.getHeldItem(hand));
ItemStack toUse = bagInventory.getStackInSlot(randomSlot);
if (toUse.isEmpty()) return new ActionResult<>(EnumActionResult.FAIL, player.getHeldItem(hand)); if (toUse.isEmpty()) return new ActionResult<>(EnumActionResult.FAIL, player.getHeldItem(hand));
return toUse.useItemRightClick(world, player, hand); return toUse.useItemRightClick(world, player, hand);
@@ -131,7 +128,7 @@ public class ItemRandomizerBag extends Item {
* @param bagInventory * @param bagInventory
* @return * @return
*/ */
public static int pickRandomSlot(IItemHandler bagInventory) { public static ItemStack pickRandomStack(IItemHandler bagInventory) {
//Find how many stacks are non-empty, and save them in a list //Find how many stacks are non-empty, and save them in a list
int nonempty = 0; int nonempty = 0;
List<ItemStack> nonEmptyStacks = new ArrayList<>(INV_SIZE); List<ItemStack> nonEmptyStacks = new ArrayList<>(INV_SIZE);
@@ -148,12 +145,26 @@ public class ItemRandomizerBag extends Item {
if (nonEmptyStacks.size() != originalSlots.size()) if (nonEmptyStacks.size() != originalSlots.size())
throw new Error("NonEmptyStacks and OriginalSlots not same size"); throw new Error("NonEmptyStacks and OriginalSlots not same size");
if (nonempty == 0) return -1; if (nonempty == 0) return ItemStack.EMPTY;
//Pick random slot //Pick random slot
int randomSlot = rand.nextInt(nonempty); int randomSlot = rand.nextInt(nonempty);
if (randomSlot < 0 || randomSlot > bagInventory.getSlots()) return ItemStack.EMPTY;
return originalSlots.get(randomSlot); int originalSlot = originalSlots.get(randomSlot);
if (originalSlot < 0 || originalSlot > bagInventory.getSlots()) return ItemStack.EMPTY;
return bagInventory.getStackInSlot(originalSlot);
}
public static ItemStack findStack(IItemHandler bagInventory, Item item) {
for (int i = 0; i < bagInventory.getSlots(); i++) {
ItemStack stack = bagInventory.getStackInSlot(i);
if (!stack.isEmpty() && stack.getItem() == item) {
return stack;
}
}
return ItemStack.EMPTY;
} }
@Override @Override
@@ -172,4 +183,9 @@ public class ItemRandomizerBag extends Item {
tooltip.add(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block"); tooltip.add(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block");
tooltip.add(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory"); tooltip.add(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory");
} }
@Override
public String getUnlocalizedName() {
return super.getUnlocalizedName();
}
} }

View File

@@ -1,6 +1,7 @@
package nl.requios.effortlessbuilding.proxy; package nl.requios.effortlessbuilding.proxy;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.model.ModelResourceLocation;
@@ -41,11 +42,12 @@ public class ClientProxy implements IProxy {
@Override @Override
public void init(FMLInitializationEvent event) { public void init(FMLInitializationEvent event) {
// register key bindings // register key bindings
keyBindings = new KeyBinding[2]; keyBindings = new KeyBinding[3];
// instantiate the key bindings // instantiate the key bindings
keyBindings[0] = new KeyBinding("key.hud.desc", Keyboard.KEY_ADD, "key.effortlessbuilding.category"); keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", Keyboard.KEY_ADD, "key.effortlessbuilding.category");
keyBindings[1] = new KeyBinding("key.replace.desc", Keyboard.KEY_SUBTRACT, "key.effortlessbuilding.category"); keyBindings[1] = new KeyBinding("key.effortlessbuilding.replace.desc", Keyboard.KEY_SUBTRACT, "key.effortlessbuilding.category");
keyBindings[2] = new KeyBinding("key.effortlessbuilding.creative.desc", Keyboard.KEY_F4, "key.effortlessbuilding.category");
// register all the key bindings // register all the key bindings
for (int i = 0; i < keyBindings.length; ++i) { for (int i = 0; i < keyBindings.length; ++i) {
@@ -105,6 +107,13 @@ public class ClientProxy implements IProxy {
EffortlessBuilding.log(player, "Set "+ TextFormatting.GOLD + "Quick Replace " + TextFormatting.RESET + (buildSettings.doQuickReplace() ? "on" : "off")); EffortlessBuilding.log(player, "Set "+ TextFormatting.GOLD + "Quick Replace " + TextFormatting.RESET + (buildSettings.doQuickReplace() ? "on" : "off"));
EffortlessBuilding.packetHandler.sendToServer(new BuildSettingsMessage(buildSettings)); EffortlessBuilding.packetHandler.sendToServer(new BuildSettingsMessage(buildSettings));
} }
if (keyBindings[2].isPressed()) {
if (player.isCreative()) {
player.sendChatMessage("/gamemode 0");
} else {
player.sendChatMessage("/gamemode 1");
}
}
} }
@SubscribeEvent @SubscribeEvent

View File

@@ -1,5 +1,6 @@
key.effortlessbuilding.category=Effortless Building key.effortlessbuilding.category=Effortless Building
key.hud.desc=Open Settings key.effortlessbuilding.hud.desc=Open Settings
key.replace.desc=Switch Replace Mode key.effortlessbuilding.replace.desc=Toggle QuickReplace
key.effortlessbuilding.creative.desc=Toggle Survival/Creative Mode
item.effortlessbuilding:randomizer_bag.name=Randomizer Bag item.effortlessbuilding:randomizer_bag.name=Randomizer Bag