10 Commits
0.1 ... 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
Christian Knaapen
2b4093099f Survival array and mirror. 2018-09-30 18:05:04 +02:00
Christian Knaapen
6f6360ae11 Build works. Added synergy of randomizer bag with mirror/array. Mirror slabs vertically. 2018-09-30 15:32:21 +02:00
Christian Knaapen
cb006c4983 Fixed serverside issues. Hidden randomizer bag. New issue: build does not work with messages. 2018-09-22 00:09:52 +02:00
Christian Knaapen
bf258580d4 Randomizer bag finished (including recipe, placing blocks). Changed default keybinds to ADD and SUBTRACT. QuickReplace now places under replaceable blocks (tall grass). Mirror now happens before array. 2018-09-17 01:17:51 +02:00
Christian Knaapen
efa47851be Working item with inventory 2018-09-16 15:20:01 +02:00
Christian Knaapen
d01fe52aba Some work on randomizerbag 2018-09-16 14:21:05 +02:00
31 changed files with 1019 additions and 372 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.
version = "0.1.1"
version = "0.2"
group = "nl.requios.effortlessbuilding" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "effortlessbuilding"

View File

@@ -1,11 +1,26 @@
package nl.requios.effortlessbuilding;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3i;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent;
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 nl.requios.effortlessbuilding.item.ItemRandomizerBag;
@Mod.EventBusSubscriber
public class Array {
//TODO config file
public static final int MAX_COUNT = 100;
@@ -26,28 +41,54 @@ public class Array {
}
//Called from EventHandler
public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
if (event.getWorld().isRemote) return;
public static boolean onBlockPlaced(BlockEvent.PlaceEvent event) {
if (event.getWorld().isRemote) return false;
//find arraysettings for the player that placed the block
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();
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
//Randomizer bag synergy
IItemHandler bagInventory = null;
if (event.getPlayer().getHeldItemMainhand().getItem() instanceof ItemRandomizerBag) {
bagInventory = ItemRandomizerBag.getBagInventory(event.getPlayer().getHeldItemMainhand());
}
//Get itemstack
ItemStack itemStack = event.getPlayer().getHeldItem(event.getHand());
for (int i = 0; i < a.count; i++) {
pos = pos.add(offset);
if (event.getWorld().isBlockLoaded(pos, true)) {
event.getWorld().setBlockState(pos, event.getPlacedBlock());
if (itemStack.isEmpty()) break;
//Mirror synergy
BlockSnapshot blockSnapshot = new BlockSnapshot(event.getWorld(), pos, event.getPlacedBlock());
BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, event.getPlacedBlock(), event.getPlayer(), EnumHand.MAIN_HAND);
Mirror.onBlockPlaced(placeEvent);
IBlockState blockState = event.getPlacedBlock();
//Randomizer bag synergy
if (bagInventory != null) {
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
SurvivalHelper.placeBlock(event.getWorld(), event.getPlayer(), pos, blockState, itemStack, EnumFacing.NORTH, true, false);
}
}
return true;
}
private static IBlockState getBlockStateFromRandomizerBag(IItemHandler bagInventory, World world, EntityPlayer player, BlockPos pos, ItemStack itemStack) {
//TODO get facing from getPlacedAgainst and getPlacedBlock
return Block.getBlockFromItem(itemStack.getItem()).getStateForPlacement(world, pos, EnumFacing.NORTH, 0, 0, 0, itemStack.getMetadata(), player, EnumHand.MAIN_HAND);
}
//Called from EventHandler
@@ -64,19 +105,46 @@ public class Array {
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
for (int i = 0; i < a.count; i++) {
pos = pos.add(offset);
if (event.getWorld().isBlockLoaded(pos, false)) {
event.getWorld().setBlockToAir(pos);
//Mirror synergy
BlockEvent.BreakEvent breakEvent = new BlockEvent.BreakEvent(event.getWorld(), pos, event.getState(), event.getPlayer());
Mirror.onBlockBroken(breakEvent);
}
SurvivalHelper.breakBlock(event.getWorld(), event.getPlayer(), pos);
}
}
// @SubscribeEvent
// @SideOnly(Side.CLIENT)
// public static void onRender(RenderWorldLastEvent event) {
//
// }
@SubscribeEvent
@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();
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

@@ -16,7 +16,7 @@ import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.capability.*;
import nl.requios.effortlessbuilding.inventory.RandomizerGuiHandler;
import nl.requios.effortlessbuilding.gui.RandomizerBagGuiHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
import nl.requios.effortlessbuilding.network.QuickReplaceMessage;
@@ -29,7 +29,7 @@ public class EffortlessBuilding
{
public static final String MODID = "effortlessbuilding";
public static final String NAME = "Effortless Building";
public static final String VERSION = "0.1.2";
public static final String VERSION = "0.2";
@Mod.Instance(EffortlessBuilding.MODID)
public static EffortlessBuilding instance;
@@ -44,11 +44,13 @@ public class EffortlessBuilding
public static final SimpleNetworkWrapper packetHandler = NetworkRegistry.INSTANCE.newSimpleChannel(EffortlessBuilding.MODID);
public static final ItemRandomizerBag ITEM_RANDOMIZER_BAG = new ItemRandomizerBag();
public static final Block[] BLOCKS = {
};
public static final Item[] ITEMS = {
new ItemRandomizerBag()
ITEM_RANDOMIZER_BAG
};
public static final int RANDOMIZER_BAG_GUI = 0;
@@ -75,7 +77,7 @@ public class EffortlessBuilding
// Register network handlers
public void init(FMLInitializationEvent event)
{
NetworkRegistry.INSTANCE.registerGuiHandler(EffortlessBuilding.instance, new RandomizerGuiHandler());
NetworkRegistry.INSTANCE.registerGuiHandler(EffortlessBuilding.instance, new RandomizerBagGuiHandler());
proxy.init(event);
}

View File

@@ -1,21 +1,31 @@
package nl.requios.effortlessbuilding;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import nl.requios.effortlessbuilding.capability.BuildModifierCapability;
@Mod.EventBusSubscriber
public class EventHandler
{
private static boolean placedBlock = false;
private static BlockEvent.PlaceEvent placeEvent = null;
@SubscribeEvent
public static void registerBlocks(RegistryEvent.Register<Block> event)
{
@@ -40,20 +50,33 @@ public class EventHandler
}
}
@SubscribeEvent
public static void onServerTick(TickEvent.ServerTickEvent event) {
if (placedBlock) {
placedBlock = false;
Mirror.onBlockPlaced(placeEvent);
Array.onBlockPlaced(placeEvent);
}
}
@SubscribeEvent
public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
QuickReplace.onBlockPlaced(event);
if (event.isCanceled()) return;
Array.onBlockPlaced(event);
Mirror.onBlockPlaced(event);
if (QuickReplace.onBlockPlaced(event)) {
event.setCanceled(true);
return;
}
//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
public static void onBlockBroken(BlockEvent.BreakEvent event) {
Array.onBlockBroken(event);
Mirror.onBlockBroken(event);
Array.onBlockBroken(event);
}
}

View File

@@ -1,24 +1,29 @@
package nl.requios.effortlessbuilding;
import net.minecraft.block.BlockDirectional;
import net.minecraft.block.BlockDispenser;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.common.util.BlockSnapshot;
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 nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Color;
@@ -59,14 +64,14 @@ public class Mirror {
}
//Called from EventHandler
public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
if (event.getWorld().isRemote) return;
public static boolean onBlockPlaced(BlockEvent.PlaceEvent event) {
if (event.getWorld().isRemote) return false;
//find mirrorsettings for the player that placed the block
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
BlockPos oldBlockPos = event.getPos();
@@ -74,63 +79,111 @@ public class Mirror {
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.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
IItemHandler bagInventory = null;
if (event.getPlayer().getHeldItem(event.getHand()).getItem() == EffortlessBuilding.ITEM_RANDOMIZER_BAG) {
bagInventory = ItemRandomizerBag.getBagInventory(event.getPlayer().getHeldItem(EnumHand.MAIN_HAND));
}
if (m.mirrorX) {
placeMirrorX(event.getWorld(), m, oldBlockPos, event.getPlacedBlock());
placeMirrorX(event.getWorld(), event.getPlayer(), m, event.getPos(), event.getPlacedBlock(), bagInventory, itemStack);
}
if (m.mirrorY) {
placeMirrorY(event.getWorld(), m, oldBlockPos, event.getPlacedBlock());
placeMirrorY(event.getWorld(), event.getPlayer(), m, oldBlockPos, event.getPlacedBlock(), bagInventory, itemStack);
}
if (m.mirrorZ) {
placeMirrorZ(event.getWorld(), m, oldBlockPos, event.getPlacedBlock());
}
placeMirrorZ(event.getWorld(), event.getPlayer(), m, oldBlockPos, event.getPlacedBlock(), bagInventory, itemStack);
}
private static void placeMirrorX(World world, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState) {
return true;
}
private static void placeMirrorX(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState, IItemHandler bagInventory, ItemStack itemStack) {
//find mirror position
double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5);
BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ());
IBlockState newBlockState = oldBlockState;
//Randomizer bag synergy
if (bagInventory != null) {
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);
//place block
if (world.isBlockLoaded(newBlockPos, true)) {
newBlockState = oldBlockState.withMirror(net.minecraft.util.Mirror.FRONT_BACK);
world.setBlockState(newBlockPos, newBlockState);
placeBlock(world, player, newBlockPos, newBlockState, itemStack);
}
if (m.mirrorY) placeMirrorY(world, m, newBlockPos, newBlockState);
if (m.mirrorZ) placeMirrorZ(world, m, newBlockPos, newBlockState);
if (m.mirrorY) placeMirrorY(world, player, m, newBlockPos, newBlockState, bagInventory, itemStack);
if (m.mirrorZ) placeMirrorZ(world, player, m, newBlockPos, newBlockState, bagInventory, itemStack);
}
private static void placeMirrorY(World world, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState) {
private static void placeMirrorY(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState, IItemHandler bagInventory, ItemStack itemStack) {
//find mirror position
double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5);
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ());
IBlockState newBlockState = oldBlockState;
//Randomizer bag synergy
if (bagInventory != null) {
itemStack = ItemRandomizerBag.pickRandomStack(bagInventory);
if (itemStack.isEmpty()) return;
oldBlockState = getBlockStateFromRandomizerBag(bagInventory, world, player, oldBlockPos, itemStack);
if (oldBlockState == null) return;
}
IBlockState newBlockState = getVerticalMirror(oldBlockState);
//place block
if (world.isBlockLoaded(newBlockPos, true)) {
newBlockState = getVerticalMirror(oldBlockState);
world.setBlockState(newBlockPos, newBlockState);
placeBlock(world, player, newBlockPos, newBlockState, itemStack);
}
if (m.mirrorZ) placeMirrorZ(world, m, newBlockPos, newBlockState);
if (m.mirrorZ) placeMirrorZ(world, player, m, newBlockPos, newBlockState, bagInventory, itemStack);
}
private static void placeMirrorZ(World world, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState) {
private static void placeMirrorZ(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState, IItemHandler bagInventory, ItemStack itemStack) {
//find mirror position
double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5);
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z);
IBlockState newBlockState = oldBlockState;
//Randomizer bag synergy
if (bagInventory != null) {
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);
//place block
if (world.isBlockLoaded(newBlockPos, true)) {
newBlockState = oldBlockState.withMirror(net.minecraft.util.Mirror.LEFT_RIGHT);
world.setBlockState(newBlockPos, newBlockState);
placeBlock(world, player, newBlockPos, newBlockState, itemStack);
}
}
private static IBlockState getBlockStateFromRandomizerBag(IItemHandler bagInventory, World world, EntityPlayer player, BlockPos pos, ItemStack itemStack) {
//TODO get facing from getPlacedAgainst and getPlacedBlock
return Block.getBlockFromItem(itemStack.getItem()).getStateForPlacement(world, pos, EnumFacing.NORTH, 0, 0, 0, itemStack.getMetadata(), player, EnumHand.MAIN_HAND);
}
private static void placeBlock(World world, EntityPlayer player, BlockPos newBlockPos, IBlockState newBlockState, ItemStack itemStack) {
//TODO check if can place
//TODO check if can break
SurvivalHelper.placeBlock(world, player, newBlockPos, newBlockState, itemStack, EnumFacing.NORTH, true, false);
//Array synergy
BlockSnapshot blockSnapshot = new BlockSnapshot(world, newBlockPos, newBlockState);
BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, newBlockState, player, EnumHand.MAIN_HAND);
Array.onBlockPlaced(placeEvent);
}
private static IBlockState getVerticalMirror(IBlockState blockState) {
//Stairs
if (blockState.getBlock() instanceof BlockStairs) {
@@ -141,6 +194,16 @@ public class Mirror {
}
}
//Slabs
if (blockState.getBlock() instanceof BlockSlab) {
if (((BlockSlab) blockState.getBlock()).isDouble()) return blockState;
if (blockState.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) {
return blockState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP);
} else {
return blockState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.BOTTOM);
}
}
//Buttons, endrod, observer, piston
if (blockState.getBlock() instanceof BlockDirectional) {
if (blockState.getValue(BlockDirectional.FACING) == EnumFacing.DOWN) {
@@ -198,9 +261,7 @@ public class Mirror {
double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5);
BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ());
//break block
if (event.getWorld().isBlockLoaded(newBlockPos, true)) {
event.getWorld().setBlockToAir(newBlockPos);
}
breakBlock(event, newBlockPos);
if (m.mirrorY) breakMirrorY(event, m, newBlockPos);
if (m.mirrorZ) breakMirrorZ(event, m, newBlockPos);
}
@@ -209,10 +270,8 @@ public class Mirror {
//find mirror position
double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5);
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ());
//place block
if (event.getWorld().isBlockLoaded(newBlockPos, true)) {
event.getWorld().setBlockToAir(newBlockPos);
}
//break block
breakBlock(event, newBlockPos);
if (m.mirrorZ) breakMirrorZ(event, m, newBlockPos);
}
@@ -220,23 +279,32 @@ public class Mirror {
//find mirror position
double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5);
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z);
//place block
if (event.getWorld().isBlockLoaded(newBlockPos, true)) {
event.getWorld().setBlockToAir(newBlockPos);
//break block
breakBlock(event, newBlockPos);
}
private static void breakBlock(BlockEvent.BreakEvent event, BlockPos newBlockPos) {
if (!event.getWorld().isBlockLoaded(newBlockPos, false)) return;
SurvivalHelper.breakBlock(event.getWorld(), event.getPlayer(), newBlockPos);
//Array synergy
BlockEvent.BreakEvent breakEvent = new BlockEvent.BreakEvent(event.getWorld(), newBlockPos, event.getState(), event.getPlayer());
Array.onBlockBroken(breakEvent);
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public static void onRender(RenderWorldLastEvent event) {
EntityPlayerSP player = Minecraft.getMinecraft().player;
EntityPlayer player = Minecraft.getMinecraft().player;
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
if (buildSettings == null) return;
MirrorSettings m = buildSettings.getMirrorSettings();
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);
int radius = m.radius;
@@ -244,44 +312,47 @@ public class Mirror {
Vec3d posA = 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) {
Vec3d posA = 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) {
Vec3d posA = 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
//(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))) {
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)
public static void drawMirrorPlane(Vec3d playerPos, 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);
public static void drawMirrorPlane(Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) {
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha);
GL11.glLineWidth(2);
GL11.glDepthMask(false);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
@@ -307,28 +378,12 @@ public class Mirror {
tessellator.draw();
}
GL11.glDepthMask(true);
GL11.glPopMatrix();
GL11.glPopAttrib();
}
@SideOnly(Side.CLIENT)
public static void drawMirrorPlaneY(Vec3d playerPos, 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);
public static void drawMirrorPlaneY(Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) {
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
GL11.glLineWidth(2);
GL11.glDepthMask(false);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
@@ -354,30 +409,15 @@ public class Mirror {
tessellator.draw();
}
GL11.glDepthMask(true);
GL11.glPopMatrix();
GL11.glPopAttrib();
}
@SideOnly(Side.CLIENT)
public static void drawMirrorLines(Vec3d playerPos, MirrorSettings m) {
public static void drawMirrorLines(MirrorSettings m) {
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.glLineWidth(2);
GL11.glDepthMask(false);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
@@ -391,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();
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

@@ -3,6 +3,7 @@ package nl.requios.effortlessbuilding;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.util.BlockSnapshot;
@@ -17,26 +18,28 @@ public class QuickReplace {
//Dilemma in getting blockstate from event to when message is received:
// 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.
//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.
private static Dictionary<UUID, IBlockState> blockStates = new Hashtable<>();
private static Dictionary<UUID, ItemStack> itemStacks = new Hashtable<>();
public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
if (event.getWorld().isRemote) return;
public static boolean onBlockPlaced(BlockEvent.PlaceEvent event) {
if (event.getWorld().isRemote) return true;
//Only serverside
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)
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());
EffortlessBuilding.packetHandler.sendTo(new QuickReplaceMessage(), (EntityPlayerMP) event.getPlayer());
event.setCanceled(true);
return true;
}
public static void onMessageReceived(EntityPlayer player, QuickReplaceMessage message) {
@@ -48,14 +51,21 @@ public class QuickReplace {
if (!message.isBlockHit() || message.getBlockPos() == null) return;
BlockPos placedAgainstBlockPos = message.getBlockPos();
//placedAgainstBlockPos = placedAgainstBlockPos.down();
//Get under tall grass and other replaceable blocks
if (player.world.getBlockState(placedAgainstBlockPos).getBlock().isReplaceable(player.world, placedAgainstBlockPos)) {
placedAgainstBlockPos = placedAgainstBlockPos.down();
}
IBlockState blockState = blockStates.get(player.getUniqueID());
player.world.setBlockState(placedAgainstBlockPos, blockState);
ItemStack itemStack = itemStacks.get(player.getUniqueID());
SurvivalHelper.placeBlock(player.world, player, placedAgainstBlockPos, blockState, itemStack, message.getSideHit(), true, false);
//Mirror and Array synergy
BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, placedAgainstBlockPos, blockState);
BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, EnumHand.MAIN_HAND);
Array.onBlockPlaced(placeEvent);
Mirror.onBlockPlaced(placeEvent);
Array.onBlockPlaced(placeEvent);
}
}

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

@@ -0,0 +1,179 @@
package nl.requios.effortlessbuilding;
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.entity.Entity;
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.util.EnumFacing;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import javax.annotation.Nullable;
import java.util.List;
public class SurvivalHelper {
//Used for all placing of blocks in this mod.
//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;
}
//Used for all breaking of blocks in this mod.
//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
public static void dropBlock(World world, EntityPlayer player, BlockPos pos){
if (player.isCreative()) return;
IBlockState blockState = world.getBlockState(pos);
List<ItemStack> drops = blockState.getBlock().getDrops(world, pos, blockState, 0);
for (ItemStack drop : drops)
{
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

@@ -0,0 +1,42 @@
package nl.requios.effortlessbuilding.capability;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ItemHandlerCapabilityProvider implements ICapabilitySerializable<NBTTagCompound> {
IItemHandler itemHandler = new ItemStackHandler(ItemRandomizerBag.INV_SIZE);
@Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
return true;
return false;
}
@Nullable
@Override
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) {
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
return (T) itemHandler;
return null;
}
@Override
public NBTTagCompound serializeNBT() {
return ((ItemStackHandler) itemHandler).serializeNBT();
}
@Override
public void deserializeNBT(NBTTagCompound nbt) {
((ItemStackHandler) itemHandler).deserializeNBT(nbt);
}
}

View File

@@ -0,0 +1,110 @@
package nl.requios.effortlessbuilding.gui;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ClickType;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
public class RandomizerBagContainer extends Container {
private final IItemHandler bagInventory;
private final int sizeInventory;
private static final int INV_START = ItemRandomizerBag.INV_SIZE, INV_END = INV_START + 26,
HOTBAR_START = INV_END + 1, HOTBAR_END = HOTBAR_START + 8;
public RandomizerBagContainer(InventoryPlayer parInventoryPlayer, IItemHandler parIInventory) {
bagInventory = parIInventory;
sizeInventory = bagInventory.getSlots();
for (int i = 0; i < sizeInventory; ++i) {
this.addSlotToContainer(new SlotItemHandler(bagInventory, i, 44 + (18 * i), 20));
}
// add player inventory slots
int i;
for (i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
addSlotToContainer(new Slot(parInventoryPlayer, j + i * 9 + 9, 8 + j * 18, 51 + i * 18));
}
}
// add hotbar slots
for (i = 0; i < 9; ++i) {
addSlotToContainer(new Slot(parInventoryPlayer, i, 8 + i * 18, 109));
}
}
@Override
public boolean canInteractWith(EntityPlayer playerIn) {
return true;
}
@Override
public ItemStack transferStackInSlot(EntityPlayer playerIn, int slotIndex) {
ItemStack itemstack = null;
Slot slot = this.inventorySlots.get(slotIndex);
if (slot != null && slot.getHasStack()) {
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
// If item is in our custom inventory
if (slotIndex < INV_START) {
// try to place in player inventory / action bar
if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true)) {
return null;
}
slot.onSlotChange(itemstack1, itemstack);
}
// Item is in inventory / hotbar, try to place in custom inventory or armor slots
else {
/**
* Implementation number 1: Shift-click into your custom inventory
*/
if (slotIndex >= INV_START) {
// place in custom inventory
if (!this.mergeItemStack(itemstack1, 0, INV_START, false)) {
return null;
}
}
}
if (itemstack1.getCount() == 0) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
if (itemstack1.getCount() == itemstack.getCount()) {
return null;
}
slot.onTake(playerIn, itemstack1);
}
return itemstack;
}
/**
* You should override this method to prevent the player from moving the stack that
* opened the inventory, otherwise if the player moves it, the inventory will not
* be able to save properly
*/
@Override
public ItemStack slotClick(int slot, int dragType, ClickType clickTypeIn, EntityPlayer player) {
// this will prevent the player from interacting with the item that opened the inventory:
if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getStack() == player.getHeldItem(EnumHand.MAIN_HAND)) {
return null;
}
return super.slotClick(slot, dragType, clickTypeIn, player);
}
}

View File

@@ -0,0 +1,49 @@
package nl.requios.effortlessbuilding.gui;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding;
@SideOnly(Side.CLIENT)
public class RandomizerBagGuiContainer extends GuiContainer {
private static final ResourceLocation guiTextures =
new ResourceLocation(EffortlessBuilding.MODID + ":textures/gui/container/randomizerbag.png");
private final InventoryPlayer inventoryPlayer;
private final IItemHandler inventoryBag;
public RandomizerBagGuiContainer(InventoryPlayer inventoryPlayer, IItemHandler inventoryBag) {
super(new RandomizerBagContainer(inventoryPlayer, inventoryBag));
this.inventoryPlayer = inventoryPlayer;
this.inventoryBag = inventoryBag;
ySize = 134;
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
drawDefaultBackground();
super.drawScreen(mouseX, mouseY, partialTicks);
this.renderHoveredToolTip(mouseX, mouseY);
}
@Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
String s = "Randomizer Bag";
fontRenderer.drawString(s, 8, 6, 0x404040);
fontRenderer.drawString(inventoryPlayer.getDisplayName().getUnformattedText(), 8, ySize - 96 + 2, 0x404040);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
mc.getTextureManager().bindTexture(guiTextures);
int marginHorizontal = (width - xSize) / 2;
int marginVertical = (height - ySize) / 2;
drawTexturedModalRect(marginHorizontal, marginVertical, 0, 0, xSize, ySize);
}
}

View File

@@ -0,0 +1,37 @@
package nl.requios.effortlessbuilding.gui;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.CapabilityItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import javax.annotation.Nullable;
public class RandomizerBagGuiHandler implements IGuiHandler {
@Nullable
@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) {
// Use the player's held item to create the container
return new RandomizerBagContainer(player.inventory,
player.getHeldItem(EnumHand.MAIN_HAND).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null));
}
return null;
}
@Nullable
@Override
@SideOnly(Side.CLIENT)
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) {
// Use the player's held item to create the client-side gui container
return new RandomizerBagGuiContainer(player.inventory,
player.getHeldItem(EnumHand.MAIN_HAND).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null));
}
return null;
}
}

View File

@@ -1,11 +0,0 @@
package nl.requios.effortlessbuilding.inventory;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
public class RandomizerBagContainer extends Container {
@Override
public boolean canInteractWith(EntityPlayer playerIn) {
return false;
}
}

View File

@@ -1,15 +0,0 @@
package nl.requios.effortlessbuilding.inventory;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Container;
public class RandomizerBagGuiContainer extends GuiContainer {
public RandomizerBagGuiContainer(Container inventorySlotsIn) {
super(inventorySlotsIn);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
}
}

View File

@@ -1,144 +0,0 @@
package nl.requios.effortlessbuilding.inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
public class RandomizerBagInventory implements IItemHandler {
//Reference to NBT data
private final ItemStack invItem;
public static final int INV_SIZE = 5;
private ItemStack[] inventory = new ItemStack[INV_SIZE];
public RandomizerBagInventory(ItemStack invItem) {
this.invItem = invItem;
if (!invItem.hasTagCompound()) {
invItem.setTagCompound(new NBTTagCompound());
}
readFromNBT(invItem.getTagCompound());
}
@Override
public int getSlots() {
return INV_SIZE;
}
@Nonnull
@Override
public ItemStack getStackInSlot(int slot) {
return inventory[slot];
}
@Nonnull
@Override
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
ItemStack slotStack = getStackInSlot(slot);
if (slotStack.getCount() == 0) {
setInventorySlotContents(slot, stack);
return null;
}
if (getSlotLimit(slot) - slotStack.getCount() < stack.getCount()) {
//Not enough place remaining, split stack
slotStack.setCount(getSlotLimit(slot));
onInventoryChanged();
stack.copy().shrink(getSlotLimit(slot) - slotStack.getCount());
//TODO make proper
return stack;
} else {
slotStack.grow(stack.getCount());
onInventoryChanged();
return null;
}
}
@Nonnull
@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
ItemStack stack = getStackInSlot(slot);
if (stack == null) return stack;
if (stack.getCount() > amount) {
stack = stack.splitStack(amount);
onInventoryChanged();
} else {
setInventorySlotContents(slot, null);
}
return stack;
}
@Override
public int getSlotLimit(int slot) {
return 64;
}
public void onInventoryChanged() {
for (int i = 0; i < getSlotLimit(0); ++i) {
if (getStackInSlot(i) != null && getStackInSlot(i).getCount() == 0) {
inventory[i] = null;
}
}
writeToNBT(invItem.getTagCompound());
}
public void setInventorySlotContents(int slot, ItemStack stack) {
inventory[slot] = stack;
if (stack != null && stack.getCount() > getSlotLimit(slot)) {
stack.setCount(getSlotLimit(slot));
}
// Don't forget this line or your inventory will not be saved!
onInventoryChanged();
}
public void readFromNBT(NBTTagCompound compound) {
// Gets the custom taglist we wrote to this compound, if any
// 1.7.2+ change to compound.getTagList("ItemInventory", Constants.NBT.TAG_COMPOUND);
NBTTagList items = compound.getTagList("ItemInventory", 0);
for (int i = 0; i < items.tagCount(); ++i) {
// 1.7.2+ change to items.getCompoundTagAt(i)
NBTTagCompound item = items.getCompoundTagAt(i);
int slot = item.getInteger("Slot");
// Just double-checking that the saved slot index is within our inventory array bounds
if (slot >= 0 && slot < getSlots()) {
inventory[slot] = new ItemStack(item);
}
}
}
/**
* A custom method to write our inventory to an ItemStack's NBT compound
*/
public void writeToNBT(NBTTagCompound tagcompound) {
// Create a new NBT Tag List to store itemstacks as NBT Tags
NBTTagList items = new NBTTagList();
for (int i = 0; i < getSlots(); ++i) {
// Only write stacks that contain items
if (getStackInSlot(i) != null) {
// Make a new NBT Tag Compound to write the itemstack and slot index to
NBTTagCompound item = new NBTTagCompound();
item.setInteger("Slot", i);
// Writes the itemstack in slot(i) to the Tag Compound we just made
getStackInSlot(i).writeToNBT(item);
// add the tag compound to our tag list
items.appendTag(item);
}
}
// Add the TagList to the ItemStack's Tag Compound with the name "ItemInventory"
tagcompound.setTag("ItemInventory", items);
}
}

View File

@@ -1,32 +0,0 @@
package nl.requios.effortlessbuilding.inventory;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.inventory.RandomizerBagContainer;
import javax.annotation.Nullable;
public class RandomizerGuiHandler implements IGuiHandler {
@Nullable
@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) {
// Use the player's held item to create the inventory
return new RandomizerBagContainer();
}
return null;
}
@Nullable
@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) {
// We have to cast the new container as our custom class
// and pass in currently held item for the inventory
return new RandomizerBagGuiContainer(new RandomizerBagContainer());
}
return null;
}
}

View File

@@ -1,56 +1,191 @@
package nl.requios.effortlessbuilding.item;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import nl.requios.effortlessbuilding.Array;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.Mirror;
import nl.requios.effortlessbuilding.SurvivalHelper;
import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class ItemRandomizerBag extends Item {
public static final int INV_SIZE = 5;
private static Random rand = new Random(1337);
public ItemRandomizerBag() {
this.setRegistryName(EffortlessBuilding.MODID, "randomizer_bag");
this.setUnlocalizedName(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.DECORATIONS);
this.setCreativeTab(CreativeTabs.TOOLS);
}
@Override
public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
if (worldIn.isRemote) return EnumActionResult.PASS;
EffortlessBuilding.log(player, "onItemUse");
public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
if (player.isSneaking()) {
if (world.isRemote) return EnumActionResult.SUCCESS;
//Open inventory
player.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, worldIn, 0, 0, 0);
player.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, world, 0, 0, 0);
} else {
//Place block
if (world.isRemote) return EnumActionResult.SUCCESS;
//Use item
//Get bag inventory
ItemStack bag = player.getHeldItem(hand);
IItemHandler bagInventory = getBagInventory(bag);
if (bagInventory == null)
return EnumActionResult.FAIL;
ItemStack toPlace = pickRandomStack(bagInventory);
if (toPlace.isEmpty()) return EnumActionResult.FAIL;
//Previously: use onItemUse to place block (no synergy)
//bag.setItemDamage(toPlace.getMetadata());
//toPlace.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ);
if (!world.getBlockState(pos).getBlock().isReplaceable(world, pos)) {
pos = pos.offset(facing);
}
return EnumActionResult.PASS;
IBlockState blockState = Block.getBlockFromItem(toPlace.getItem()).getStateForPlacement(world, pos, facing,
hitX, hitY, hitZ, toPlace.getMetadata(), player, hand);
SurvivalHelper.placeBlock(world, player, pos, blockState, toPlace, facing, false, true);
//Synergy
//Works without calling
// BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, pos, blockState);
// BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, hand);
// Mirror.onBlockPlaced(placeEvent);
// Array.onBlockPlaced(placeEvent);
}
return EnumActionResult.SUCCESS;
}
@Override
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) {
if (worldIn.isRemote) return new ActionResult<>(EnumActionResult.PASS, playerIn.getHeldItem(handIn));
EffortlessBuilding.log(playerIn, "onItemRightClick");
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
if (player.isSneaking()) {
if (world.isRemote) return new ActionResult<>(EnumActionResult.SUCCESS, player.getHeldItem(hand));
//Open inventory
playerIn.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, worldIn, 0, 0, 0);
player.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, world, 0, 0, 0);
} else {
//Use item
//Get bag inventory
ItemStack bag = player.getHeldItem(hand);
IItemHandler bagInventory = getBagInventory(bag);
if (bagInventory == null)
return new ActionResult<>(EnumActionResult.FAIL, player.getHeldItem(hand));
return new ActionResult<>(EnumActionResult.PASS, playerIn.getHeldItem(handIn));
ItemStack toUse = pickRandomStack(bagInventory);
if (toUse.isEmpty()) return new ActionResult<>(EnumActionResult.FAIL, player.getHeldItem(hand));
return toUse.useItemRightClick(world, player, hand);
}
return new ActionResult<>(EnumActionResult.PASS, player.getHeldItem(hand));
}
/**
* Get the inventory of a randomizer bag by checking the capability.
*
* @param bag
* @return
*/
public static IItemHandler getBagInventory(ItemStack bag) {
if (!bag.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null)) return null;
return bag.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
}
/**
* Pick a random slot from the bag. Empty slots will never get chosen.
*
* @param bagInventory
* @return
*/
public static ItemStack pickRandomStack(IItemHandler bagInventory) {
//Find how many stacks are non-empty, and save them in a list
int nonempty = 0;
List<ItemStack> nonEmptyStacks = new ArrayList<>(INV_SIZE);
List<Integer> originalSlots = new ArrayList<>(INV_SIZE);
for (int i = 0; i < bagInventory.getSlots(); i++) {
ItemStack stack = bagInventory.getStackInSlot(i);
if (!stack.isEmpty()) {
nonempty++;
nonEmptyStacks.add(stack);
originalSlots.add(i);
}
}
if (nonEmptyStacks.size() != originalSlots.size())
throw new Error("NonEmptyStacks and OriginalSlots not same size");
if (nonempty == 0) return ItemStack.EMPTY;
//Pick random slot
int randomSlot = rand.nextInt(nonempty);
if (randomSlot < 0 || randomSlot > bagInventory.getSlots()) return ItemStack.EMPTY;
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
public int getMaxItemUseDuration(ItemStack stack) {
return 1;
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable NBTTagCompound nbt) {
return new ItemHandlerCapabilityProvider();
}
@Override
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) {
tooltip.add(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block");
tooltip.add(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory");
}
@Override
public String getUnlocalizedName() {
return super.getUnlocalizedName();
}
}

View File

@@ -13,6 +13,7 @@ import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import nl.requios.effortlessbuilding.Array;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.BuildSettingsManager.BuildSettings;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.Mirror;
public class BuildSettingsMessage implements IMessage {
@@ -84,7 +85,7 @@ public class BuildSettingsMessage implements IMessage {
//EffortlessBuilding.log("message received on " + ctx.side + " side");
// This is the player the packet was sent to the server from
EntityPlayer player = (ctx.side.isClient() ? Minecraft.getMinecraft().player : ctx.getServerHandler().player);
EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
// The value that was sent
BuildSettings buildSettings = message.buildSettings;
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
@@ -98,9 +99,9 @@ public class BuildSettingsMessage implements IMessage {
a.count = Math.max(0, a.count);
// Execute the action on the main server thread by adding it as a scheduled task
IThreadListener threadListener = (ctx.side.isClient() ? Minecraft.getMinecraft() : ((EntityPlayerMP) player).getServerWorld());
IThreadListener threadListener = EffortlessBuilding.proxy.getThreadListenerFromContext(ctx);
threadListener.addScheduledTask(() -> {
EntityPlayer p = (ctx.side.isClient() ? Minecraft.getMinecraft().player : ctx.getServerHandler().player);
EntityPlayer p = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
BuildSettingsManager.setBuildSettings(p, buildSettings);
});
// No response packet

View File

@@ -8,6 +8,7 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.QuickReplace;
import nl.requios.effortlessbuilding.proxy.ClientProxy;
@@ -77,7 +78,7 @@ public class QuickReplaceMessage implements IMessage {
} else {
//Received serverside
ctx.getServerHandler().player.getServerWorld().addScheduledTask(() -> {
EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> {
QuickReplace.onMessageReceived(ctx.getServerHandler().player, message);
});
}

View File

@@ -1,12 +1,15 @@
package nl.requios.effortlessbuilding.proxy;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.util.IThreadListener;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.client.event.ModelRegistryEvent;
@@ -39,11 +42,12 @@ public class ClientProxy implements IProxy {
@Override
public void init(FMLInitializationEvent event) {
// register key bindings
keyBindings = new KeyBinding[2];
keyBindings = new KeyBinding[3];
// instantiate the key bindings
keyBindings[0] = new KeyBinding("key.hud.desc", Keyboard.KEY_NUMPAD0, "key.effortlessbuilding.category");
keyBindings[1] = new KeyBinding("key.replace.desc", Keyboard.KEY_NUMPAD1, "key.effortlessbuilding.category");
keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", Keyboard.KEY_ADD, "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
for (int i = 0; i < keyBindings.length; ++i) {
@@ -58,7 +62,12 @@ public class ClientProxy implements IProxy {
@Override
public EntityPlayer getPlayerEntityFromContext(MessageContext ctx) {
return (ctx.side.isClient() ? Minecraft.getMinecraft().player : EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx));
return (ctx.side.isClient() ? Minecraft.getMinecraft().player : ctx.getServerHandler().player);
}
@Override
public IThreadListener getThreadListenerFromContext(MessageContext ctx) {
return (ctx.side.isClient() ? Minecraft.getMinecraft() : ((EntityPlayerMP) getPlayerEntityFromContext(ctx)).getServerWorld());
}
@Override
@@ -98,6 +107,13 @@ public class ClientProxy implements IProxy {
EffortlessBuilding.log(player, "Set "+ TextFormatting.GOLD + "Quick Replace " + TextFormatting.RESET + (buildSettings.doQuickReplace() ? "on" : "off"));
EffortlessBuilding.packetHandler.sendToServer(new BuildSettingsMessage(buildSettings));
}
if (keyBindings[2].isPressed()) {
if (player.isCreative()) {
player.sendChatMessage("/gamemode 0");
} else {
player.sendChatMessage("/gamemode 1");
}
}
}
@SubscribeEvent

View File

@@ -1,6 +1,7 @@
package nl.requios.effortlessbuilding.proxy;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.IThreadListener;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
@@ -33,8 +34,10 @@ public interface IProxy
/**
* Returns a side-appropriate EntityPlayer for use during message handling.
*
* @param parContext the context
* @param ctx the context
* @return the player entity from context
*/
EntityPlayer getPlayerEntityFromContext(MessageContext parContext);
EntityPlayer getPlayerEntityFromContext(MessageContext ctx);
IThreadListener getThreadListenerFromContext(MessageContext ctx);
}

View File

@@ -1,14 +1,22 @@
package nl.requios.effortlessbuilding.proxy;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.IThreadListener;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
import nl.requios.effortlessbuilding.network.QuickReplaceMessage;
public class ServerProxy implements IProxy
{
//Only physical server! Singleplayer server is seen as clientproxy
@Override
public void preInit(FMLPreInitializationEvent event)
{
@@ -35,4 +43,9 @@ public class ServerProxy implements IProxy
{
return ctx.getServerHandler().player;
}
@Override
public IThreadListener getThreadListenerFromContext(MessageContext ctx) {
return ((EntityPlayerMP) getPlayerEntityFromContext(ctx)).getServerWorld();
}
}

View File

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

View File

@@ -1,6 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "items/fireball"
"layer0": "effortlessbuilding:items/randomizerbag"
}
}

View File

@@ -0,0 +1,20 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
" # ",
"#O#",
" # "
],
"key": {
"#": {
"item": "minecraft:leather"
},
"O": {
"item": "minecraft:planks",
"data": 32767
}
},
"result": {
"item": "effortlessbuilding:randomizer_bag"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -5,7 +5,7 @@
"description": "Makes building easier by providing tools like mirrors, arrays, quickreplace and a block randomizer.",
"version": "${version}",
"mcversion": "${mcversion}",
"url": "https://requios.nl/",
"url": "https://minecraft.curseforge.com/projects/effortless-building",
"updateUrl": "",
"authorList": ["Requios"],
"credits": "",