10 Commits
0.2 ... 0.4

Author SHA1 Message Date
Christian Knaapen
1933832c58 Fixed rare crash on ladders.
Added config file with reach, increased mining time and block outline settings.
Mirror size has been renamed to reach.
Mirror and array abide by the new reach settings.
Added reach counter to array UI (reach = count * max offset).
If reach is 0 (as can be set in config), the UI will be disabled.
Added the ability to show the white block outline on the block you place, in addition to blocks placed by mirror/array.
Added the ability to disable increased mining time and to change its percentage in the config.
2018-12-01 18:33:21 +01:00
Christian Knaapen
3891cc349f Mining speed is decreased based on blocks mined (extra blocks count for 50%, which will be configurable).
Tool durability is checked after each block break (no more breaking 5 blocks with 1 durability).
Fortune is taken into account.
Outlines now change to blocks that will be broken when holding tools.
Added indication QuickReplace is on: outline of current block will be white.
Fixed opening Randomizer Bag in offhand.
Fixed placing blocks with Randomizer Bag in offhand.
Fixed mirror block outline showing up outside range.
Fixed outline of QuickReplace not being under replaceables like tall grass.
2018-11-04 18:43:16 +01:00
Christian Knaapen
2ea44f22b5 GUI overhaul. Added +- buttons with shift/ctrl clicking. Rightclick to clear. Tooltips. Scroll to change number.
See empty fields as 0 instead of reset. Images for buttons. Added Toggle 0.5 button.
Can now click "mirror/array enabled" label to toggle.
2018-10-28 19:38:44 +01:00
Christian Knaapen
e2e48a4451 Fixed shiftclicking items into a Randomizer Bag when it is almost full. 2018-10-27 16:04:42 +02:00
Christian Knaapen
c2e29419ca Moved all rendering code to RenderHelper to resolve #3 Crash on stand alone server startup.
Made sure getBuildSettings never returns null to resolve #4 Client Crash W/ OpenBlocks.
Now compatible with block placers and breakers from OpenBlocks (even the Randomizer Bag works in the placer).
Fixed the breakEvent in mirror for array synergy to use the blockstate of the new position. Resolves #5 Crash after destorying blocks with hand.
2018-10-27 14:20:00 +02:00
Christian Knaapen
bb359113f2 Version update and cleanup 2018-10-21 17:05:05 +02:00
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
28 changed files with 1442 additions and 479 deletions

BIN
Logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

BIN
Logo.xcf

Binary file not shown.

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.3.5"
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

@@ -9,13 +9,13 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
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.event.entity.player.PlayerEvent;
import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
public class Array { public class Array {
//TODO config file
public static final int MAX_COUNT = 100;
public static class ArraySettings{ public static class ArraySettings{
public boolean enabled = false; public boolean enabled = false;
@@ -30,67 +30,74 @@ public class Array {
this.offset = offset; this.offset = offset;
this.count = count; this.count = count;
} }
public int getReach() {
//find largest offset
int x = Math.abs(offset.getX());
int y = Math.abs(offset.getY());
int z = Math.abs(offset.getZ());
int largestOffset = Math.max(Math.max(x, y), z);
return largestOffset * count;
}
} }
//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());
//Randomizer bag synergy
IItemHandler bagInventory = null;
if (event.getPlayer().getHeldItemMainhand().getItem() instanceof ItemRandomizerBag) {
bagInventory = ItemRandomizerBag.getBagInventory(event.getPlayer().getHeldItemMainhand());
}
//Get itemstack //Get itemstack
ItemStack itemStack = event.getPlayer().getHeldItem(event.getHand()); ItemStack itemStack = event.getPlayer().getHeldItem(event.getHand());
//Randomizer bag synergy
IItemHandler bagInventory = null;
if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemRandomizerBag) {
bagInventory = ItemRandomizerBag.getBagInventory(itemStack);
}
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, 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, event.getHand());
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()));
}
private static IBlockState getBlockStateFromRandomizerBag(IItemHandler bagInventory, World world, EntityPlayer player, BlockPos pos) { return true;
int randomSlot = ItemRandomizerBag.pickRandomSlot(bagInventory); }
ItemStack stack = bagInventory.getStackInSlot(randomSlot);
private static IBlockState getBlockStateFromRandomizerBag(IItemHandler bagInventory, World world, EntityPlayer player, BlockPos pos, ItemStack itemStack, EnumHand hand) {
//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, hand);
} }
//Called from EventHandler //Called from EventHandler
public static void onBlockBroken(BlockEvent.BreakEvent event) { public static void onBlockBroken(BlockEvent.BreakEvent event) {
if (event.getWorld().isRemote) return; if (event.getWorld().isRemote) return;
//find arraysettings for the player that placed the block //find arraysettings for the player that broke 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;
@@ -100,14 +107,27 @@ 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 //Called from EventHandler
SurvivalHelper.dropBlock(event.getWorld(), pos, event.getPlayer()); public static float getTotalBlockHardness(World world, EntityPlayer player, BlockPos pos) {
float hardness = 0;
event.getWorld().setBlockToAir(pos); //find arraysettings for the player that broke the block
} ArraySettings a = BuildSettingsManager.getBuildSettings(player).getArraySettings();
if (a == null || !a.enabled) return 0;
if (a.offset.getX() == 0 && a.offset.getY() == 0 && a.offset.getZ() == 0) return 0;
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 (SurvivalHelper.canBreak(world, player, pos))
hardness += world.getBlockState(pos).getBlockHardness(world, pos);
} }
return hardness;
} }
} }

View File

@@ -0,0 +1,54 @@
package nl.requios.effortlessbuilding;
import net.minecraftforge.common.config.Config;
import static net.minecraftforge.common.config.Config.*;
@Config(modid = EffortlessBuilding.MODID, name = "EffortlessBuilding", type = Type.INSTANCE, category = "")
public class BuildConfig {
public static Reach reach = new Reach();
public static SurvivalBalancers survivalBalancers = new SurvivalBalancers();
public static Visuals visuals = new Visuals();
public static class Reach {
@Comment({"Reach: how far away the player can place blocks using mirror/array etc.",
"Maximum reach in creative"})
public int maxReachCreative = 200;
@Comment({"Maximum reach in survival without upgrades",
"Reach upgrades are craftable consumables that permanently increase reach.",
"Set to 0 to disable Effortless Building until the player has consumed a reach upgrade."})
public int maxReachLevel0 = 10;
@Comment("Maximum reach in survival with one upgrade")
public int maxReachLevel1 = 20;
@Comment("Maximum reach in survival with two upgrades")
public int maxReachLevel2 = 50;
@Comment("Maximum reach in survival with three upgrades")
public int maxReachLevel3 = 200;
}
public static class SurvivalBalancers {
@Comment({"Increases the time to mine a block when breaking multiple at once.",
"Mining time depends on how many blocks, what type of blocks, and the percentage below.",
"Example: breaking 1 dirt + 1 obsidian takes the time of breaking 1 dirt + 1 obsidian."})
public boolean increasedMiningTime = true;
@Comment({"How much the mining time of each additional block counts towards an increased mining time.",
"A percentage between 0% and 100%, where 0% is the same as disabling it,",
"and 100% takes as much time as breaking each block individually.",
"The block in front of you always counts as 100%."})
@RangeInt(min = 0, max = 100)
public int miningTimePercentage = 50;
}
public static class Visuals {
@Comment({"Shows a white block outline for the block you manually place,",
"in addition to blocks placed by the mirror or array."})
public boolean showOutlineOnCurrentBlock = false;
}
}

View File

@@ -2,6 +2,7 @@ package nl.requios.effortlessbuilding;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.text.TextFormatting;
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.PlayerEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent;
@@ -11,18 +12,22 @@ import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class BuildSettingsManager { public class BuildSettingsManager {
//Retrieves the buildsettings of a player through the buildModifier capability
//Never returns null
public static BuildSettings getBuildSettings(EntityPlayer player){ public static BuildSettings getBuildSettings(EntityPlayer player){
if (player.hasCapability(BuildModifierCapability.buildModifier, null)) { if (player.hasCapability(BuildModifierCapability.buildModifier, null)) {
BuildModifierCapability.IBuildModifier capability = player.getCapability(BuildModifierCapability.buildModifier, null); BuildModifierCapability.IBuildModifier capability = player.getCapability(BuildModifierCapability.buildModifier, null);
if (capability.getBuildModifierData() == null) {
capability.setBuildModifierData(new BuildSettings());
}
return capability.getBuildModifierData(); return capability.getBuildModifierData();
} }
EffortlessBuilding.log("buildsettings is null"); throw new IllegalArgumentException("Player does not have buildModifier capability");
return null;
} }
public static void setBuildSettings(EntityPlayer player, BuildSettings buildSettings) { public static void setBuildSettings(EntityPlayer player, BuildSettings buildSettings) {
if (player == null) { if (player == null) {
EffortlessBuilding.log("cannot set buildsettings, player is null"); EffortlessBuilding.log("Cannot set buildsettings, player is null");
return; return;
} }
if (player.hasCapability(BuildModifierCapability.buildModifier, null)) { if (player.hasCapability(BuildModifierCapability.buildModifier, null)) {
@@ -33,20 +38,74 @@ public class BuildSettingsManager {
} }
} }
public static String sanitize(BuildSettings buildSettings, EntityPlayer player) {
int maxReach = getMaxReach(player);
String error = "";
//Mirror settings
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
if (m.radius < 1) {
m.radius = 1;
error += "Mirror size is too small. Size has been reset to 1. ";
}
if (m.getReach() > maxReach) {
m.radius = maxReach / 2;
error += "Mirror exceeds your maximum reach. Reach has been reset to max. ";
}
//Array settings
Array.ArraySettings a = buildSettings.getArraySettings();
if (a.count < 0) {
a.count = 0;
error += "Array count cannot be negative. Count has been reset to 0. ";
}
if (a.getReach() > maxReach) {
a.count = 0;
error += "Array exceeds your maximum reach. Count has been reset to 0. ";
}
//Other
if (buildSettings.reachUpgrade < 0) {
buildSettings.reachUpgrade = 0;
}
if (buildSettings.reachUpgrade > 3) {
buildSettings.reachUpgrade = 3;
}
return error;
}
public static int getMaxReach(EntityPlayer player) {
if (player.isCreative()) return BuildConfig.reach.maxReachCreative;
//Check buildsettings for reachUpgrade
int reachUpgrade = getBuildSettings(player).getReachUpgrade();
switch (reachUpgrade) {
case 0: return BuildConfig.reach.maxReachLevel0;
case 1: return BuildConfig.reach.maxReachLevel1;
case 2: return BuildConfig.reach.maxReachLevel2;
case 3: return BuildConfig.reach.maxReachLevel3;
}
return BuildConfig.reach.maxReachLevel0;
}
public static class BuildSettings { public static class BuildSettings {
private Mirror.MirrorSettings mirrorSettings; private Mirror.MirrorSettings mirrorSettings;
private Array.ArraySettings arraySettings; private Array.ArraySettings arraySettings;
private boolean quickReplace = false; private boolean quickReplace = false;
private int reachUpgrade = 0;
public BuildSettings() { public BuildSettings() {
mirrorSettings = new Mirror.MirrorSettings(); mirrorSettings = new Mirror.MirrorSettings();
arraySettings = new Array.ArraySettings(); arraySettings = new Array.ArraySettings();
} }
public BuildSettings(Mirror.MirrorSettings mirrorSettings, Array.ArraySettings arraySettings, boolean quickReplace) { public BuildSettings(Mirror.MirrorSettings mirrorSettings, Array.ArraySettings arraySettings, boolean quickReplace, int reachUpgrade) {
this.mirrorSettings = mirrorSettings; this.mirrorSettings = mirrorSettings;
this.arraySettings = arraySettings; this.arraySettings = arraySettings;
this.quickReplace = quickReplace; this.quickReplace = quickReplace;
this.reachUpgrade = reachUpgrade;
} }
public Mirror.MirrorSettings getMirrorSettings() { public Mirror.MirrorSettings getMirrorSettings() {
@@ -72,6 +131,14 @@ public class BuildSettingsManager {
public void setQuickReplace(boolean quickReplace) { public void setQuickReplace(boolean quickReplace) {
this.quickReplace = quickReplace; this.quickReplace = quickReplace;
} }
public int getReachUpgrade() {
return reachUpgrade;
}
public void setReachUpgrade(int reachUpgrade) {
this.reachUpgrade = reachUpgrade;
}
} }
@SubscribeEvent @SubscribeEvent

View File

@@ -5,6 +5,8 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.SidedProxy;
@@ -29,7 +31,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.3.5";
@Mod.Instance(EffortlessBuilding.MODID) @Mod.Instance(EffortlessBuilding.MODID)
public static EffortlessBuilding instance; public static EffortlessBuilding instance;
@@ -77,6 +79,7 @@ public class EffortlessBuilding
// Register network handlers // Register network handlers
public void init(FMLInitializationEvent event) public void init(FMLInitializationEvent event)
{ {
ConfigManager.sync(MODID, Config.Type.INSTANCE);
NetworkRegistry.INSTANCE.registerGuiHandler(EffortlessBuilding.instance, new RandomizerBagGuiHandler()); NetworkRegistry.INSTANCE.registerGuiHandler(EffortlessBuilding.instance, new RandomizerBagGuiHandler());
proxy.init(event); proxy.init(event);
} }

View File

@@ -1,23 +1,38 @@
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.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager;
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.PlayerEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
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 +57,37 @@ public class EventHandler
} }
} }
@SubscribeEvent
public void onConfigChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event)
{
if (event.getModID().equals(EffortlessBuilding.MODID))
{
ConfigManager.sync(EffortlessBuilding.MODID, Config.Type.INSTANCE);
}
}
@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) {
@@ -58,4 +95,31 @@ public class EventHandler
Array.onBlockBroken(event); Array.onBlockBroken(event);
} }
@SubscribeEvent
public static void breakSpeed(PlayerEvent.BreakSpeed event) {
//Disable if config says so
if (!BuildConfig.survivalBalancers.increasedMiningTime) return;
EntityPlayer player = event.getEntityPlayer();
World world = player.world;
BlockPos pos = event.getPos();
//EffortlessBuilding.log(player, String.valueOf(event.getNewSpeed()));
float originalBlockHardness = event.getState().getBlockHardness(world, pos);
float totalBlockHardness = 0;
totalBlockHardness += Mirror.getTotalBlockHardness(world, player, pos);
totalBlockHardness += Array.getTotalBlockHardness(world, player, pos);
//Grabbing percentage from config
float percentage = (float) BuildConfig.survivalBalancers.miningTimePercentage / 100;
totalBlockHardness *= percentage;
totalBlockHardness += originalBlockHardness;
float newSpeed = event.getOriginalSpeed() / totalBlockHardness * originalBlockHardness;
if (Float.isNaN(newSpeed) || newSpeed == 0f) newSpeed = 1f;
event.setNewSpeed(newSpeed);
//EffortlessBuilding.log(player, String.valueOf(event.getNewSpeed()));
}
} }

View File

@@ -2,43 +2,22 @@ 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.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
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.Vec3d; import net.minecraft.util.math.Vec3d;
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.common.util.BlockSnapshot; import net.minecraftforge.common.util.BlockSnapshot;
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.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Color;
@Mod.EventBusSubscriber
public class Mirror { public class Mirror {
//TODO config file
public static final int MAX_RADIUS = 200;
private static final Color colorX = new Color(255, 72, 52);
private static final Color colorY = new Color(67, 204, 51);
private static final Color colorZ = new Color(52, 247, 255);
private static final int lineAlpha = 200;
private static final int planeAlpha = 75;
private static final Vec3d epsilon = new Vec3d(0.001, 0.001, 0.001); //prevents z-fighting
public static class MirrorSettings { public static class MirrorSettings {
public boolean enabled = false; public boolean enabled = false;
public Vec3d position = new Vec3d(0.5, 64.5, 0.5); public Vec3d position = new Vec3d(0.5, 64.5, 0.5);
@@ -59,17 +38,21 @@ public class Mirror {
this.drawLines = drawLines; this.drawLines = drawLines;
this.drawPlanes = drawPlanes; this.drawPlanes = drawPlanes;
} }
public int getReach() {
return radius * 2;
}
} }
//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,104 +60,112 @@ 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;
//Get itemstack
ItemStack itemStack = event.getPlayer().getHeldItem(event.getHand());
//Randomizer bag synergy //Randomizer bag synergy
IItemHandler bagInventory = null; IItemHandler bagInventory = null;
if (event.getPlayer().getHeldItem(event.getHand()).getItem() == EffortlessBuilding.ITEM_RANDOMIZER_BAG) { if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemRandomizerBag) {
bagInventory = ItemRandomizerBag.getBagInventory(event.getPlayer().getHeldItem(EnumHand.MAIN_HAND)); bagInventory = ItemRandomizerBag.getBagInventory(itemStack);
} }
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, event.getHand());
} }
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, event.getHand());
} }
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, event.getHand());
}
} }
private static IBlockState getBlockStateFromRandomizerBag(IItemHandler bagInventory, World world, EntityPlayer player, BlockPos pos) { return true;
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) { private static void placeMirrorX(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState,
IItemHandler bagInventory, ItemStack itemStack, EnumHand hand) {
//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, hand);
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, hand);
} }
if (m.mirrorY) placeMirrorY(world, player, m, newBlockPos, newBlockState, bagInventory); if (m.mirrorY) placeMirrorY(world, player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand);
if (m.mirrorZ) placeMirrorZ(world, player, m, newBlockPos, newBlockState, bagInventory); if (m.mirrorZ) placeMirrorZ(world, player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand);
} }
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, EnumHand hand) {
//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, hand);
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, hand);
} }
if (m.mirrorZ) placeMirrorZ(world, player, m, newBlockPos, newBlockState, bagInventory); if (m.mirrorZ) placeMirrorZ(world, player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand);
} }
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, EnumHand hand) {
//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, hand);
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, hand);
} }
} }
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, EnumHand hand) {
//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, hand);
if (itemStack.isEmpty()) return; }
private static void placeBlock(World world, EntityPlayer player, BlockPos newBlockPos, IBlockState newBlockState, ItemStack itemStack, EnumHand hand) {
//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);
BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, newBlockState, player, EnumHand.MAIN_HAND); BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, newBlockState, player, hand);
Array.onBlockPlaced(placeEvent); Array.onBlockPlaced(placeEvent);
} }
@@ -255,9 +246,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 +255,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,193 +264,92 @@ 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.getWorld().getBlockState(newBlockPos), event.getPlayer());
Array.onBlockBroken(breakEvent); Array.onBlockBroken(breakEvent);
} }
@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;
MirrorSettings m = buildSettings.getMirrorSettings();
if (m == null || !m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return; //Called from EventHandler
public static float getTotalBlockHardness(World world, EntityPlayer player, BlockPos oldBlockPos) {
float hardness = 0;
Vec3d playerPos = new Vec3d(player.posX, player.posY, player.posZ); //find mirrorsettings for the player that broke the block
Vec3d pos = m.position.add(epsilon); MirrorSettings m = BuildSettingsManager.getBuildSettings(player).getMirrorSettings();
int radius = m.radius; if (m == null) return 0;
if (!m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return 0;
//if within mirror distance, break mirror block
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 0;
if (m.mirrorX) { if (m.mirrorX) {
Vec3d posA = new Vec3d(pos.x, pos.y - radius, pos.z - radius); hardness += getHardnessX(world, player, m, oldBlockPos);
Vec3d posB = new Vec3d(pos.x, pos.y + radius, pos.z + radius);
drawMirrorPlane(playerPos, 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); hardness += getHardnessY(world, player, m, oldBlockPos);
Vec3d posB = new Vec3d(pos.x + radius, pos.y, pos.z + radius);
drawMirrorPlaneY(playerPos, 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); hardness += getHardnessZ(world, player, m, oldBlockPos);
Vec3d posB = new Vec3d(pos.x + radius, pos.y + radius, pos.z); }
return hardness;
drawMirrorPlane(playerPos, posA, posB, colorZ, m.drawLines, m.drawPlanes);
} }
//Draw axis coordinated colors if two or more axes are enabled private static float getHardnessX(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos) {
//(If only one is enabled the lines are that planes color) float hardness = 0;
if (m.drawLines && ((m.mirrorX && m.mirrorY) || (m.mirrorX && m.mirrorZ) || (m.mirrorY && m.mirrorZ))) {
drawMirrorLines(playerPos, m); //find mirror position
} double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5);
BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ());
if (SurvivalHelper.canBreak(world, player, newBlockPos))
hardness += world.getBlockState(newBlockPos).getBlockHardness(world, newBlockPos);
if (m.mirrorY) hardness += getHardnessY(world, player, m, newBlockPos);
if (m.mirrorZ) hardness += getHardnessZ(world, player, m, newBlockPos);
return hardness;
} }
@SideOnly(Side.CLIENT) private static float getHardnessY(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos) {
public static void drawMirrorPlane(Vec3d playerPos, Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) { float hardness = 0;
GL11.glPushAttrib(GL11.GL_ENABLE_BIT); //find mirror position
GL11.glPushMatrix(); double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5);
GL11.glDisable(GL11.GL_CULL_FACE); BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ());
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND); if (SurvivalHelper.canBreak(world, player, newBlockPos))
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); hardness += world.getBlockState(newBlockPos).getBlockHardness(world, newBlockPos);
GL11.glTranslated(-playerPos.x, -playerPos.y, -playerPos.z);
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); if (m.mirrorZ) hardness += getHardnessZ(world, player, m, newBlockPos);
GL11.glLineWidth(2);
GL11.glDepthMask(false);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
if (drawPlanes) { return hardness;
bufferBuilder.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(posA.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posA.x, posB.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posB.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
tessellator.draw();
} }
if (drawLines) { private static float getHardnessZ(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos) {
Vec3d middle = posA.add(posB).scale(0.5); float hardness = 0;
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(posA.x, middle.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); //find mirror position
bufferBuilder.pos(posB.x, middle.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5);
bufferBuilder.pos(middle.x, posA.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z);
bufferBuilder.pos(middle.x, posB.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
tessellator.draw(); if (SurvivalHelper.canBreak(world, player, newBlockPos))
hardness += world.getBlockState(newBlockPos).getBlockHardness(world, newBlockPos);
return hardness;
} }
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);
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
GL11.glLineWidth(2);
GL11.glDepthMask(false);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
if (drawPlanes) {
bufferBuilder.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(posA.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posA.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
tessellator.draw();
}
if (drawLines) {
Vec3d middle = posA.add(posB).scale(0.5);
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(middle.x, middle.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(middle.x, middle.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(posA.x, middle.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(posB.x, middle.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
tessellator.draw();
}
GL11.glDepthMask(true);
GL11.glPopMatrix();
GL11.glPopAttrib();
}
@SideOnly(Side.CLIENT)
public static void drawMirrorLines(Vec3d playerPos, 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();
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(pos.x - m.radius, pos.y, pos.z).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x + m.radius, pos.y, pos.z).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x, pos.y - m.radius, pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x, pos.y + m.radius, pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex();
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();
GL11.glDepthMask(true);
GL11.glPopMatrix();
GL11.glPopAttrib();
}
} }

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;
@@ -9,6 +8,7 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.util.BlockSnapshot; import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent;
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.network.QuickReplaceMessage; import nl.requios.effortlessbuilding.network.QuickReplaceMessage;
import java.util.Dictionary; import java.util.Dictionary;
@@ -19,34 +19,36 @@ 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<>();
private static Dictionary<UUID, EnumHand> hands = 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()));
hands.put(event.getPlayer().getUniqueID(), 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) {
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player); BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
if (!buildSettings.doQuickReplace()) return; if (!buildSettings.doQuickReplace()) return;
//TODO check for bedrock, end portal etc in survival
if (!message.isBlockHit() || message.getBlockPos() == null) return; if (!message.isBlockHit() || message.getBlockPos() == null) return;
BlockPos placedAgainstBlockPos = message.getBlockPos(); BlockPos placedAgainstBlockPos = message.getBlockPos();
@@ -57,19 +59,15 @@ public class QuickReplace {
} }
IBlockState blockState = blockStates.get(player.getUniqueID()); IBlockState blockState = blockStates.get(player.getUniqueID());
ItemStack itemStack = itemStacks.get(player.getUniqueID());
EnumHand hand = hands.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
blockState = player.world.getBlockState(placedAgainstBlockPos);
BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, placedAgainstBlockPos, blockState); BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, placedAgainstBlockPos, blockState);
BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, EnumHand.MAIN_HAND); BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, hand);
Mirror.onBlockPlaced(placeEvent); Mirror.onBlockPlaced(placeEvent);
Array.onBlockPlaced(placeEvent); Array.onBlockPlaced(placeEvent);
} }

View File

@@ -1,35 +0,0 @@
package nl.requios.effortlessbuilding;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.ItemHandlerHelper;
import java.util.List;
public class SurvivalHelper {
public static boolean canBreak(){
return true;
}
public static boolean canPlace(){
return true;
}
//Gives items directly to player
public static void dropBlock(World world, BlockPos pos, EntityPlayer player){
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);
}
}
}

View File

@@ -49,6 +49,7 @@ public class BuildModifierCapability {
public NBTBase writeNBT(Capability<IBuildModifier> capability, IBuildModifier instance, EnumFacing side) { public NBTBase writeNBT(Capability<IBuildModifier> capability, IBuildModifier instance, EnumFacing side) {
NBTTagCompound compound = new NBTTagCompound(); NBTTagCompound compound = new NBTTagCompound();
BuildSettings buildSettings = instance.getBuildModifierData(); BuildSettings buildSettings = instance.getBuildModifierData();
if (buildSettings == null) buildSettings = new BuildSettings();
//MIRROR //MIRROR
Mirror.MirrorSettings m = buildSettings.getMirrorSettings(); Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
@@ -71,6 +72,8 @@ public class BuildModifierCapability {
compound.setInteger("arrayOffsetZ", a.offset.getZ()); compound.setInteger("arrayOffsetZ", a.offset.getZ());
compound.setInteger("arrayCount", a.count); compound.setInteger("arrayCount", a.count);
compound.setInteger("reachUpgrade", buildSettings.getReachUpgrade());
//compound.setBoolean("quickReplace", buildSettings.doQuickReplace()); dont save quickreplace //compound.setBoolean("quickReplace", buildSettings.doQuickReplace()); dont save quickreplace
return compound; return compound;
} }
@@ -96,9 +99,11 @@ public class BuildModifierCapability {
int arrayCount = compound.getInteger("arrayCount"); int arrayCount = compound.getInteger("arrayCount");
Array.ArraySettings arraySettings = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount); Array.ArraySettings arraySettings = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount);
int reachUpgrade = compound.getInteger("reachUpgrade");
//boolean quickReplace = compound.getBoolean("quickReplace"); //dont load quickreplace //boolean quickReplace = compound.getBoolean("quickReplace"); //dont load quickreplace
BuildSettings buildSettings = new BuildSettings(mirrorSettings, arraySettings, false); BuildSettings buildSettings = new BuildSettings(mirrorSettings, arraySettings, false, reachUpgrade);
instance.setBuildModifierData(buildSettings); instance.setBuildModifierData(buildSettings);
} }
} }

View File

@@ -0,0 +1,75 @@
package nl.requios.effortlessbuilding.gui;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GuiIconButton extends GuiButton {
private final ResourceLocation resourceLocation;
private final int iconX, iconY, iconWidth, iconHeight, iconAltX, iconAltY;
List<String> tooltip = new ArrayList<>();
private boolean useAltIcon = false;
public GuiIconButton(int buttonId, int x, int y, int iconX, int iconY, ResourceLocation resourceLocation) {
this(buttonId, x, y, 20, 20, iconX, iconY, 20, 20, 20, 0, resourceLocation);
}
public GuiIconButton(int buttonId, int x, int y, int width, int height, int iconX, int iconY, int iconWidth, int iconHeight, int iconAltX, int iconAltY, ResourceLocation resourceLocation) {
super(buttonId, x, y, width, height, "");
this.iconX = iconX;
this.iconY = iconY;
this.iconWidth = iconWidth;
this.iconHeight = iconHeight;
this.iconAltX = iconAltX;
this.iconAltY = iconAltY;
this.resourceLocation = resourceLocation;
}
public void setTooltip(String tooltip) {
setTooltip(Arrays.asList(tooltip));
}
public void setTooltip(List<String> tooltip) {
this.tooltip = tooltip;
}
public void setUseAlternateIcon(boolean useAlternateIcon) {
this.useAltIcon = useAlternateIcon;
}
@Override
public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) {
super.drawButton(mc, mouseX, mouseY, partialTicks);
if (this.visible)
{
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
mc.getTextureManager().bindTexture(this.resourceLocation);
int currentIconX = this.iconX;
int currentIconY = this.iconY;
if (useAltIcon)
{
currentIconX += iconAltX;
currentIconY += iconAltY;
}
this.drawTexturedModalRect(this.x, this.y, currentIconX, currentIconY, this.iconWidth, this.iconHeight);
}
}
public void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY) {
boolean flag = mouseX >= x && mouseX < x + width && mouseY >= y && mouseY < y + height;
if (flag) {
List<String> textLines = new ArrayList<>();
textLines.addAll(tooltip);
guiScreen.drawHoveringText(textLines, mouseX - 10, mouseY + 25);
}
}
}

View File

@@ -0,0 +1,149 @@
package nl.requios.effortlessbuilding.gui;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
import net.minecraft.util.text.TextFormatting;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GuiNumberField extends Gui {
int x, y, width, height;
int buttonWidth = 10;
protected GuiTextField textField;
protected GuiButton minusButton, plusButton;
List<String> tooltip = new ArrayList<>();
public GuiNumberField(int id1, int id2, int id3, FontRenderer fontRenderer,
List<GuiButton> buttonList, int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
textField = new GuiTextField(id1, fontRenderer, x + buttonWidth + 1, y + 1, width - 2 * buttonWidth - 2, height - 2);
minusButton = new GuiButton(id2, x, y - 1, buttonWidth, height + 2, "-");
plusButton = new GuiButton(id3, x + width - buttonWidth, y - 1, buttonWidth, height + 2, "+");
buttonList.add(minusButton);
buttonList.add(plusButton);
}
public void setNumber(double number) {
DecimalFormat format = new DecimalFormat("0.#");
textField.setText(format.format(number));
}
public double getNumber() {
if (textField.getText().isEmpty()) return 0;
return Double.parseDouble(textField.getText());
}
public void setTooltip(String tooltip) {
setTooltip(Arrays.asList(tooltip));
}
public void setTooltip(List<String> tooltip) {
this.tooltip = tooltip;
}
public boolean mouseClicked(int mouseX, int mouseY, int mouseButton) {
boolean result = textField.mouseClicked(mouseX, mouseY, mouseButton);
//Check if clicked inside textfield
boolean flag = mouseX >= x + buttonWidth && mouseX < x + width - buttonWidth && mouseY >= y && mouseY < y + height;
//Rightclicked inside textfield
if (flag && mouseButton == 1) {
textField.setText("");
textField.setFocused(true);
result = true;
}
return result;
}
public void drawNumberField(Minecraft mc, int mouseX, int mouseY, float partialTicks) {
textField.drawTextBox();
minusButton.drawButton(mc, mouseX, mouseY, partialTicks);
plusButton.drawButton(mc, mouseX, mouseY, partialTicks);
}
public void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY) {
boolean insideTextField = mouseX >= x + buttonWidth && mouseX < x + width - buttonWidth && mouseY >= y && mouseY < y + height;
boolean insideMinusButton = mouseX >= x && mouseX < x + buttonWidth && mouseY >= y && mouseY < y + height;
boolean insidePlusButton = mouseX >= x + width - buttonWidth && mouseX < x + width && mouseY >= y && mouseY < y + height;
List<String> textLines = new ArrayList<>();
if (insideTextField) {
if (!tooltip.isEmpty())
textLines.addAll(tooltip);
// textLines.add(TextFormatting.GRAY + "Tip: try scrolling.");
}
if (insideMinusButton) {
textLines.add("Hold " + TextFormatting.AQUA + "shift " + TextFormatting.RESET + "for " + TextFormatting.RED + "10");
textLines.add("Hold " + TextFormatting.AQUA + "ctrl " + TextFormatting.RESET + "for " + TextFormatting.RED + "5");
}
if (insidePlusButton) {
textLines.add("Hold " + TextFormatting.AQUA + "shift " + TextFormatting.RESET + "for " + TextFormatting.DARK_GREEN + "10");
textLines.add("Hold " + TextFormatting.AQUA + "ctrl " + TextFormatting.RESET + "for " + TextFormatting.DARK_GREEN + "5");
}
guiScreen.drawHoveringText(textLines, mouseX - 10, mouseY + 25);
}
protected void actionPerformed(GuiButton button) {
float valueChanged = 1f;
if (GuiScreen.isCtrlKeyDown()) valueChanged = 5f;
if (GuiScreen.isShiftKeyDown()) valueChanged = 10f;
if (button == minusButton) {
setNumber(getNumber() - valueChanged);
}
if (button == plusButton) {
setNumber(getNumber() + valueChanged);
}
}
public void update() {
textField.updateCursorCounter();
}
protected void keyTyped(char typedChar, int keyCode) throws IOException {
if (!textField.isFocused()) return;
// if (Character.isDigit(typedChar) || typedChar == '.' || typedChar == '-' || keyCode == Keyboard.KEY_BACK
// || keyCode == Keyboard.KEY_DELETE || keyCode == Keyboard.KEY_LEFT || keyCode == Keyboard.KEY_RIGHT
// || keyCode == Keyboard.KEY_UP || keyCode == Keyboard.KEY_DOWN) {
textField.textboxKeyTyped(typedChar, keyCode);
// }
}
public void handleMouseInput(int mouseX, int mouseY) {
boolean insideTextField = mouseX >= x + buttonWidth && mouseX < x + width - buttonWidth && mouseY >= y && mouseY < y + height;
if (insideTextField)
{
int valueChanged = 0;
if (Mouse.getEventDWheel() > 0)
valueChanged = 1;
if (Mouse.getEventDWheel() < 0)
valueChanged = -1;
if (valueChanged != 0)
setNumber(getNumber() + valueChanged);
}
}
}

View File

@@ -46,9 +46,17 @@ public class RandomizerBagContainer extends Container {
return true; return true;
} }
@Override
public Slot getSlot(int parSlotIndex)
{
if(parSlotIndex >= inventorySlots.size())
parSlotIndex = inventorySlots.size() - 1;
return super.getSlot(parSlotIndex);
}
@Override @Override
public ItemStack transferStackInSlot(EntityPlayer playerIn, int slotIndex) { public ItemStack transferStackInSlot(EntityPlayer playerIn, int slotIndex) {
ItemStack itemstack = null; ItemStack itemstack = ItemStack.EMPTY;
Slot slot = this.inventorySlots.get(slotIndex); Slot slot = this.inventorySlots.get(slotIndex);
if (slot != null && slot.getHasStack()) { if (slot != null && slot.getHasStack()) {
@@ -59,7 +67,7 @@ public class RandomizerBagContainer extends Container {
if (slotIndex < INV_START) { if (slotIndex < INV_START) {
// try to place in player inventory / action bar // try to place in player inventory / action bar
if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true)) { if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true)) {
return null; return ItemStack.EMPTY;
} }
slot.onSlotChange(itemstack1, itemstack); slot.onSlotChange(itemstack1, itemstack);
@@ -72,7 +80,7 @@ public class RandomizerBagContainer extends Container {
if (slotIndex >= INV_START) { if (slotIndex >= INV_START) {
// place in custom inventory // place in custom inventory
if (!this.mergeItemStack(itemstack1, 0, INV_START, false)) { if (!this.mergeItemStack(itemstack1, 0, INV_START, false)) {
return null; return ItemStack.EMPTY;
} }
} }
@@ -85,7 +93,7 @@ public class RandomizerBagContainer extends Container {
} }
if (itemstack1.getCount() == itemstack.getCount()) { if (itemstack1.getCount() == itemstack.getCount()) {
return null; return ItemStack.EMPTY;
} }
slot.onTake(playerIn, itemstack1); slot.onTake(playerIn, itemstack1);
@@ -102,9 +110,26 @@ public class RandomizerBagContainer extends Container {
@Override @Override
public ItemStack slotClick(int slot, int dragType, ClickType clickTypeIn, EntityPlayer player) { 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: // this will prevent the player from interacting with the item that opened the inventory:
ItemStack clickItemStack = super.slotClick(slot, dragType, clickTypeIn, player);
if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getStack() == player.getHeldItem(EnumHand.MAIN_HAND)) { if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getStack() == player.getHeldItem(EnumHand.MAIN_HAND)) {
return null; return ItemStack.EMPTY;
} }
return super.slotClick(slot, dragType, clickTypeIn, player); return clickItemStack;
} }
/**
* Callback for when the crafting gui is closed.
*/
// @Override
// public void onContainerClosed(EntityPlayer player)
// {
// if(player.inventory.getItemStack() != null)
// {
// player.entityDropItem(player.inventory.getItemStack(), 0.5f);
// }
// if(!player.world.isRemote)
// {
// detectAndSendChanges();
// }
// }
} }

View File

@@ -7,6 +7,7 @@ import net.minecraftforge.fml.common.network.IGuiHandler;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -17,8 +18,10 @@ public class RandomizerBagGuiHandler implements IGuiHandler {
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) { if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) {
// Use the player's held item to create the container // Use the player's held item to create the container
return new RandomizerBagContainer(player.inventory, IItemHandler capability = player.getHeldItemMainhand().hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) ?
player.getHeldItem(EnumHand.MAIN_HAND).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null)); player.getHeldItemMainhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) :
player.getHeldItemOffhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
return new RandomizerBagContainer(player.inventory, capability);
} }
return null; return null;
} }
@@ -29,8 +32,10 @@ public class RandomizerBagGuiHandler implements IGuiHandler {
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) { if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) {
// Use the player's held item to create the client-side gui container // Use the player's held item to create the client-side gui container
return new RandomizerBagGuiContainer(player.inventory, IItemHandler capability = player.getHeldItemMainhand().hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) ?
player.getHeldItem(EnumHand.MAIN_HAND).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null)); player.getHeldItemMainhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) :
player.getHeldItemOffhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
return new RandomizerBagGuiContainer(player.inventory, capability);
} }
return null; return null;
} }

View File

@@ -1,11 +1,11 @@
package nl.requios.effortlessbuilding.gui; package nl.requios.effortlessbuilding.gui;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.client.config.GuiCheckBox; import net.minecraftforge.fml.client.config.GuiCheckBox;
import nl.requios.effortlessbuilding.Array; import nl.requios.effortlessbuilding.Array;
import nl.requios.effortlessbuilding.BuildSettingsManager; import nl.requios.effortlessbuilding.BuildSettingsManager;
@@ -13,28 +13,32 @@ import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.Mirror; import nl.requios.effortlessbuilding.Mirror;
import nl.requios.effortlessbuilding.network.BuildSettingsMessage; import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.ClientProxy;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
public class SettingsGui extends GuiScreen { public class SettingsGui extends GuiScreen {
protected List<GuiTextField> textFieldList = new ArrayList<>(); protected static final ResourceLocation BUILDING_ICONS = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/building_icons.png");
protected List<GuiNumberField> numberFieldList = new ArrayList<>();
protected List<GuiButton> mirrorButtonList = new ArrayList<>(); protected List<GuiButton> mirrorButtonList = new ArrayList<>();
protected List<GuiTextField> mirrorTextFieldList = new ArrayList<>(); protected List<GuiIconButton> mirrorIconButtonList = new ArrayList<>();
protected List<GuiTextField> arrayTextFieldList = new ArrayList<>(); protected List<GuiNumberField> mirrorNumberFieldList = new ArrayList<>();
protected List<GuiNumberField> arrayNumberFieldList = new ArrayList<>();
private GuiTextField textMirrorPosX, textMirrorPosY, textMirrorPosZ, textMirrorRadius; private GuiNumberField textMirrorPosX, textMirrorPosY, textMirrorPosZ, textMirrorRadius;
private GuiCheckBox buttonMirrorEnabled, buttonMirrorX, buttonMirrorY, buttonMirrorZ; private GuiCheckBox buttonMirrorEnabled, buttonMirrorX, buttonMirrorY, buttonMirrorZ;
private GuiButton buttonDrawPlanes, buttonDrawLines; private GuiIconButton buttonCurrentPosition, buttonToggleOdd, buttonDrawPlanes, buttonDrawLines;
private boolean drawPlanes, drawLines; private boolean drawPlanes, drawLines, toggleOdd;
private GuiButton buttonCurrentPosition, buttonClose; private GuiButton buttonClose;
private GuiCheckBox buttonArrayEnabled; private GuiCheckBox buttonArrayEnabled;
private GuiTextField textArrayOffsetX, textArrayOffsetY, textArrayOffsetZ, textArrayCount; private GuiNumberField textArrayOffsetX, textArrayOffsetY, textArrayOffsetZ, textArrayCount;
private int left, right, top, bottom; private int left, right, top, bottom;
@@ -53,17 +57,20 @@ public class SettingsGui extends GuiScreen {
buttonList.add(buttonMirrorEnabled); buttonList.add(buttonMirrorEnabled);
y = top + 18; y = top + 18;
textMirrorPosX = new GuiTextField(id++, fontRenderer, left + 70, y, 50, 18); textMirrorPosX = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 58, y, 62, 18);
textMirrorPosX.setText("0.5"); textMirrorPosX.setNumber(0);
mirrorTextFieldList.add(textMirrorPosX); textMirrorPosX.setTooltip(Arrays.asList("The position of the mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5."));
mirrorNumberFieldList.add(textMirrorPosX);
textMirrorPosY = new GuiTextField(id++, fontRenderer, left + 140, y, 50, 18); textMirrorPosY = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 138, y, 62, 18);
textMirrorPosY.setText("64.5"); textMirrorPosY.setNumber(64);
mirrorTextFieldList.add(textMirrorPosY); textMirrorPosY.setTooltip(Arrays.asList("The position of the mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5."));
mirrorNumberFieldList.add(textMirrorPosY);
textMirrorPosZ = new GuiTextField(id++, fontRenderer, left + 210, y, 50, 18); textMirrorPosZ = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 218, y, 62, 18);
textMirrorPosZ.setText("0.5"); textMirrorPosZ.setNumber(0);
mirrorTextFieldList.add(textMirrorPosZ); textMirrorPosZ.setTooltip(Arrays.asList("The position of the mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5."));
mirrorNumberFieldList.add(textMirrorPosZ);
y = top + 50; y = top + 50;
buttonMirrorX = new GuiCheckBox(id++, left + 60, y, " X", true); buttonMirrorX = new GuiCheckBox(id++, left + 60, y, " X", true);
@@ -76,19 +83,30 @@ public class SettingsGui extends GuiScreen {
mirrorButtonList.add(buttonMirrorZ); mirrorButtonList.add(buttonMirrorZ);
y = top + 47; y = top + 47;
textMirrorRadius = new GuiTextField(id++, fontRenderer, left + 220, y, 60, 18); textMirrorRadius = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 218, y, 62, 18);
textMirrorRadius.setText("50"); textMirrorRadius.setNumber(50);
mirrorTextFieldList.add(textMirrorRadius); //TODO change to diameter (remove /2)
textMirrorRadius.setTooltip(Arrays.asList("How far the mirror reaches in any direction.",
TextFormatting.GRAY + "Max: " + TextFormatting.GOLD + BuildSettingsManager.getMaxReach(mc.player) / 2,
TextFormatting.GRAY + "Upgradeable in survival with reach upgrades."));
mirrorNumberFieldList.add(textMirrorRadius);
y = top + 72; y = top + 72;
buttonCurrentPosition = new GuiButton(id++, left + 5, y, 110, 20, "Set to current pos"); buttonCurrentPosition = new GuiIconButton(id++, left + 5, y, 0, 0, BUILDING_ICONS);
mirrorButtonList.add(buttonCurrentPosition); buttonCurrentPosition.setTooltip("Set mirror position to current player position");
mirrorIconButtonList.add(buttonCurrentPosition);
buttonDrawLines = new GuiButton(id++, left + 127, y, 70, 20, "Show lines"); buttonToggleOdd = new GuiIconButton(id++, left + 35, y, 0, 20, BUILDING_ICONS);
mirrorButtonList.add(buttonDrawLines); buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds"));
mirrorIconButtonList.add(buttonToggleOdd);
buttonDrawPlanes = new GuiButton(id++, left + 209, y, 75, 20, "Show area"); buttonDrawLines = new GuiIconButton(id++, left + 65, y, 0, 40, BUILDING_ICONS);
mirrorButtonList.add(buttonDrawPlanes); buttonDrawLines.setTooltip("Show lines");
mirrorIconButtonList.add(buttonDrawLines);
buttonDrawPlanes = new GuiIconButton(id++, left + 95, y, 0, 60, BUILDING_ICONS);
buttonDrawPlanes.setTooltip("Show area");
mirrorIconButtonList.add(buttonDrawPlanes);
//ARRAY //ARRAY
y = top + 100; y = top + 100;
@@ -96,22 +114,26 @@ public class SettingsGui extends GuiScreen {
buttonList.add(buttonArrayEnabled); buttonList.add(buttonArrayEnabled);
y = top + 120; y = top + 120;
textArrayOffsetX = new GuiTextField(id++, fontRenderer, left + 70, y, 50, 18); textArrayOffsetX = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 70, y, 50, 18);
textArrayOffsetX.setText("0"); textArrayOffsetX.setNumber(0);
arrayTextFieldList.add(textArrayOffsetX); textArrayOffsetX.setTooltip("How much each copy is shifted.");
arrayNumberFieldList.add(textArrayOffsetX);
textArrayOffsetY = new GuiTextField(id++, fontRenderer, left + 140, y, 50, 18); textArrayOffsetY = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 140, y, 50, 18);
textArrayOffsetY.setText("0"); textArrayOffsetY.setNumber(0);
arrayTextFieldList.add(textArrayOffsetY); textArrayOffsetY.setTooltip("How much each copy is shifted.");
arrayNumberFieldList.add(textArrayOffsetY);
textArrayOffsetZ = new GuiTextField(id++, fontRenderer, left + 210, y, 50, 18); textArrayOffsetZ = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 210, y, 50, 18);
textArrayOffsetZ.setText("0"); textArrayOffsetZ.setNumber(0);
arrayTextFieldList.add(textArrayOffsetZ); textArrayOffsetZ.setTooltip("How much each copy is shifted.");
arrayNumberFieldList.add(textArrayOffsetZ);
y = top + 150; y = top + 150;
textArrayCount = new GuiTextField(id++, fontRenderer, left + 55, y, 50, 18); textArrayCount = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 55, y, 50, 18);
textArrayCount.setText("5"); textArrayCount.setNumber(5);
arrayTextFieldList.add(textArrayCount); textArrayCount.setTooltip("How many copies should be made.");
arrayNumberFieldList.add(textArrayCount);
//CLOSE //CLOSE
y = height - 40; y = height - 40;
@@ -123,36 +145,47 @@ public class SettingsGui extends GuiScreen {
//MIRROR //MIRROR
Mirror.MirrorSettings m = buildSettings.getMirrorSettings(); Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
buttonMirrorEnabled.setIsChecked(m.enabled); buttonMirrorEnabled.setIsChecked(m.enabled);
textMirrorPosX.setText(String.valueOf(m.position.x)); textMirrorPosX.setNumber(m.position.x);
textMirrorPosY.setText(String.valueOf(m.position.y)); textMirrorPosY.setNumber(m.position.y);
textMirrorPosZ.setText(String.valueOf(m.position.z)); textMirrorPosZ.setNumber(m.position.z);
buttonMirrorX.setIsChecked(m.mirrorX); buttonMirrorX.setIsChecked(m.mirrorX);
buttonMirrorY.setIsChecked(m.mirrorY); buttonMirrorY.setIsChecked(m.mirrorY);
buttonMirrorZ.setIsChecked(m.mirrorZ); buttonMirrorZ.setIsChecked(m.mirrorZ);
textMirrorRadius.setText(String.valueOf(m.radius)); textMirrorRadius.setNumber(m.radius);
drawLines = m.drawLines; drawLines = m.drawLines;
drawPlanes = m.drawPlanes; drawPlanes = m.drawPlanes;
buttonDrawLines.displayString = drawLines ? "Hide lines" : "Show lines"; buttonDrawLines.setUseAlternateIcon(drawLines);
buttonDrawPlanes.displayString = drawPlanes ? "Hide area" : "Show area"; buttonDrawPlanes.setUseAlternateIcon(drawPlanes);
buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines");
buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area");
if (textMirrorPosX.getNumber() == Math.floor(textMirrorPosX.getNumber())) {
toggleOdd = false;
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds"));
} else {
toggleOdd = true;
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to corner of block", "for even numbered builds"));
}
buttonToggleOdd.setUseAlternateIcon(toggleOdd);
//ARRAY //ARRAY
Array.ArraySettings a = buildSettings.getArraySettings(); Array.ArraySettings a = buildSettings.getArraySettings();
buttonArrayEnabled.setIsChecked(a.enabled); buttonArrayEnabled.setIsChecked(a.enabled);
textArrayOffsetX.setText(String.valueOf(a.offset.getX())); textArrayOffsetX.setNumber(a.offset.getX());
textArrayOffsetY.setText(String.valueOf(a.offset.getY())); textArrayOffsetY.setNumber(a.offset.getY());
textArrayOffsetZ.setText(String.valueOf(a.offset.getZ())); textArrayOffsetZ.setNumber(a.offset.getZ());
textArrayCount.setText(String.valueOf(a.count)); textArrayCount.setNumber(a.count);
} }
buttonList.addAll(mirrorButtonList); buttonList.addAll(mirrorButtonList);
textFieldList.addAll(mirrorTextFieldList); buttonList.addAll(mirrorIconButtonList);
textFieldList.addAll(arrayTextFieldList); numberFieldList.addAll(mirrorNumberFieldList);
numberFieldList.addAll(arrayNumberFieldList);
} }
@Override @Override
//Process general logic, i.e. hide buttons //Process general logic, i.e. hide buttons
public void updateScreen() { public void updateScreen() {
textFieldList.forEach(GuiTextField::updateCursorCounter); numberFieldList.forEach(GuiNumberField::update);
} }
@Override @Override
@@ -170,16 +203,17 @@ public class SettingsGui extends GuiScreen {
y = top + 18 + 5; y = top + 18 + 5;
fontRenderer.drawString("Position", left + offset, y, 0xFFFFFF, true); fontRenderer.drawString("Position", left + offset, y, 0xFFFFFF, true);
fontRenderer.drawString("X", left + 50 + offset, y, 0xFFFFFF, true); fontRenderer.drawString("X", left + 40 + offset, y, 0xFFFFFF, true);
fontRenderer.drawString("Y", left + 120 + offset, y, 0xFFFFFF, true); fontRenderer.drawString("Y", left + 120 + offset, y, 0xFFFFFF, true);
fontRenderer.drawString("Z", left + 190 + offset, y, 0xFFFFFF, true); fontRenderer.drawString("Z", left + 200 + offset, y, 0xFFFFFF, true);
y = top + 52; y = top + 52;
fontRenderer.drawString("Direction", left + offset, y, 0xFFFFFF, true); fontRenderer.drawString("Direction", left + offset, y, 0xFFFFFF, true);
fontRenderer.drawString("Size", left + 190, y, 0xFFFFFF, true); fontRenderer.drawString("Reach", left + 176 + offset, y, 0xFFFFFF, true);
mirrorButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks)); mirrorButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks));
mirrorTextFieldList.forEach(textField -> textField.drawTextBox()); mirrorIconButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks));
mirrorNumberFieldList.forEach(numberField -> numberField.drawNumberField(this.mc, mouseX, mouseY, partialTicks));
} else { } else {
fontRenderer.drawString("Mirror disabled", left + offset, y, 0x999999, true); fontRenderer.drawString("Mirror disabled", left + offset, y, 0x999999, true);
} }
@@ -198,33 +232,69 @@ public class SettingsGui extends GuiScreen {
y = top + 150 + 5; y = top + 150 + 5;
fontRenderer.drawString("Count", left + offset, y, 0xFFFFFF, true); fontRenderer.drawString("Count", left + offset, y, 0xFFFFFF, true);
arrayTextFieldList.forEach(textField -> textField.drawTextBox()); int currentReach = Math.max(-1, getArrayReach());
int maxReach = BuildSettingsManager.getMaxReach(mc.player);
TextFormatting reachColor = isCurrentReachValid(currentReach, maxReach) ? TextFormatting.GRAY : TextFormatting.RED;
String reachText = "Reach: " + reachColor + currentReach + TextFormatting.GRAY + "/" + TextFormatting.GRAY + maxReach;
fontRenderer.drawString(reachText, left + 176 + offset, y, 0xFFFFFF, true);
arrayNumberFieldList.forEach(numberField -> numberField.drawNumberField(this.mc, mouseX, mouseY, partialTicks));
} else { } else {
fontRenderer.drawString("Array disabled", left + offset, y, 0x999999, true); fontRenderer.drawString("Array disabled", left + offset, y, 0x999999, true);
} }
buttonClose.drawButton(this.mc, mouseX, mouseY, partialTicks); buttonClose.drawButton(this.mc, mouseX, mouseY, partialTicks);
//Draw tooltips last
if (buttonMirrorEnabled.isChecked())
{
mirrorIconButtonList.forEach(iconButton -> iconButton.drawTooltip(this, mouseX, mouseY));
mirrorNumberFieldList.forEach(numberField -> numberField.drawTooltip(this, mouseX, mouseY));
}
if (buttonArrayEnabled.isChecked())
{
arrayNumberFieldList.forEach(numberField -> numberField.drawTooltip(this, mouseX, mouseY));
}
} }
@Override @Override
protected void keyTyped(char typedChar, int keyCode) throws IOException { protected void keyTyped(char typedChar, int keyCode) throws IOException {
super.keyTyped(typedChar, keyCode); super.keyTyped(typedChar, keyCode);
if (Character.isDigit(typedChar) || typedChar == '.' || typedChar == '-' || keyCode == Keyboard.KEY_BACK || keyCode == Keyboard.KEY_DELETE) { for (GuiNumberField numberField : numberFieldList) {
for (GuiTextField textField : textFieldList) { numberField.keyTyped(typedChar, keyCode);
if (textField.isFocused()) {
textField.textboxKeyTyped(typedChar, keyCode);
}
}
} }
if (keyCode == ClientProxy.keyBindings[0].getKeyCode()) { if (keyCode == ClientProxy.keyBindings[0].getKeyCode()) {
Minecraft.getMinecraft().player.closeScreen(); mc.player.closeScreen();
} }
} }
@Override @Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
super.mouseClicked(mouseX, mouseY, mouseButton); super.mouseClicked(mouseX, mouseY, mouseButton);
textFieldList.forEach(textField -> textField.mouseClicked(mouseX, mouseY, mouseButton)); numberFieldList.forEach(numberField -> numberField.mouseClicked(mouseX, mouseY, mouseButton));
boolean insideMirrorEnabledLabel = mouseX >= left && mouseX < right && mouseY >= top - 2 && mouseY < top + 10;
boolean insideArrayEnabledLabel = mouseX >= left && mouseX < right && mouseY >= top + 100 && mouseY < top + 112;
if (insideMirrorEnabledLabel) {
buttonMirrorEnabled.setIsChecked(!buttonMirrorEnabled.isChecked());
buttonMirrorEnabled.playPressSound(this.mc.getSoundHandler());
actionPerformed(buttonMirrorEnabled);
}
if (insideArrayEnabledLabel) {
buttonArrayEnabled.setIsChecked(!buttonArrayEnabled.isChecked());
buttonArrayEnabled.playPressSound(this.mc.getSoundHandler());
actionPerformed(buttonArrayEnabled);
}
}
@Override
public void handleMouseInput() throws IOException {
super.handleMouseInput();
int mouseX = Mouse.getEventX() * this.width / this.mc.displayWidth;
int mouseY = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1;
numberFieldList.forEach(numberField -> numberField.handleMouseInput(mouseX, mouseY));
} }
@Override @Override
@@ -235,18 +305,36 @@ public class SettingsGui extends GuiScreen {
} }
if (button == buttonCurrentPosition) { if (button == buttonCurrentPosition) {
Vec3d pos = new Vec3d(Math.floor(mc.player.posX) + 0.5, Math.floor(mc.player.posY) + 0.5, Math.floor(mc.player.posZ) + 0.5); Vec3d pos = new Vec3d(Math.floor(mc.player.posX) + 0.5, Math.floor(mc.player.posY) + 0.5, Math.floor(mc.player.posZ) + 0.5);
textMirrorPosX.setText(String.valueOf(pos.x)); textMirrorPosX.setNumber(pos.x);
textMirrorPosY.setText(String.valueOf(pos.y)); textMirrorPosY.setNumber(pos.y);
textMirrorPosZ.setText(String.valueOf(pos.z)); textMirrorPosZ.setNumber(pos.z);
}
if (button == buttonToggleOdd) {
toggleOdd = !toggleOdd;
buttonToggleOdd.setUseAlternateIcon(toggleOdd);
if (toggleOdd) {
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to corner of block", "for even numbered builds"));
textMirrorPosX.setNumber(textMirrorPosX.getNumber() + 0.5);
textMirrorPosY.setNumber(textMirrorPosY.getNumber() + 0.5);
textMirrorPosZ.setNumber(textMirrorPosZ.getNumber() + 0.5);
} else {
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds"));
textMirrorPosX.setNumber(Math.floor(textMirrorPosX.getNumber()));
textMirrorPosY.setNumber(Math.floor(textMirrorPosY.getNumber()));
textMirrorPosZ.setNumber(Math.floor(textMirrorPosZ.getNumber()));
}
} }
if (button == buttonDrawLines) { if (button == buttonDrawLines) {
drawLines = !drawLines; drawLines = !drawLines;
buttonDrawLines.displayString = drawLines ? "Hide lines" : "Show lines"; buttonDrawLines.setUseAlternateIcon(drawLines);
buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines");
} }
if (button == buttonDrawPlanes) { if (button == buttonDrawPlanes) {
drawPlanes = !drawPlanes; drawPlanes = !drawPlanes;
buttonDrawPlanes.displayString = drawPlanes ? "Hide area" : "Show area"; buttonDrawPlanes.setUseAlternateIcon(drawPlanes);
buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area");
} }
numberFieldList.forEach(numberField -> numberField.actionPerformed(button));
} }
@Override @Override
@@ -256,12 +344,11 @@ public class SettingsGui extends GuiScreen {
//MIRROR //MIRROR
boolean mirrorEnabled = buttonMirrorEnabled.isChecked(); boolean mirrorEnabled = buttonMirrorEnabled.isChecked();
Vec3d mirrorPos = new Vec3d(0.5, 64.5, 0.5); Vec3d mirrorPos = new Vec3d(0, 64, 0);
try { try {
mirrorPos = new Vec3d(Double.parseDouble(textMirrorPosX.getText()), Double.parseDouble(textMirrorPosY.getText()), Double.parseDouble(textMirrorPosZ.getText())); mirrorPos = new Vec3d(textMirrorPosX.getNumber(), textMirrorPosY.getNumber(), textMirrorPosZ.getNumber());
} catch (NumberFormatException | NullPointerException ex) { } catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(Minecraft.getMinecraft().player, "Mirror position not valid.", true); EffortlessBuilding.log(mc.player, "Mirror position not valid.");
EffortlessBuilding.log("Mirror position not valid. Resetting to default.");
} }
boolean mirrorX = buttonMirrorX.isChecked(); boolean mirrorX = buttonMirrorX.isChecked();
@@ -270,13 +357,10 @@ public class SettingsGui extends GuiScreen {
int mirrorRadius = 50; int mirrorRadius = 50;
try { try {
mirrorRadius = Math.min(Integer.parseInt(textMirrorRadius.getText()), Mirror.MAX_RADIUS); mirrorRadius = (int) textMirrorRadius.getNumber();
} catch (NumberFormatException | NullPointerException ex) { } catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(Minecraft.getMinecraft().player, "Mirror radius not valid.", true); EffortlessBuilding.log(mc.player, "Mirror radius not valid.");
EffortlessBuilding.log("Mirror radius not valid. Resetting to default.");
} }
mirrorRadius = Math.max(1, mirrorRadius);
mirrorRadius = Math.min(Mirror.MAX_RADIUS, mirrorRadius);
Mirror.MirrorSettings m = new Mirror.MirrorSettings(mirrorEnabled, mirrorPos, mirrorX, mirrorY, mirrorZ, mirrorRadius, drawLines, drawPlanes); Mirror.MirrorSettings m = new Mirror.MirrorSettings(mirrorEnabled, mirrorPos, mirrorX, mirrorY, mirrorZ, mirrorRadius, drawLines, drawPlanes);
@@ -284,21 +368,17 @@ public class SettingsGui extends GuiScreen {
boolean arrayEnabled = buttonArrayEnabled.isChecked(); boolean arrayEnabled = buttonArrayEnabled.isChecked();
BlockPos arrayOffset = new BlockPos(0, 0, 0); BlockPos arrayOffset = new BlockPos(0, 0, 0);
try { try {
arrayOffset = new BlockPos(Integer.parseInt(textArrayOffsetX.getText()), Integer.parseInt(textArrayOffsetY.getText()), Integer.parseInt(textArrayOffsetZ.getText())); arrayOffset = new BlockPos(textArrayOffsetX.getNumber(), textArrayOffsetY.getNumber(), textArrayOffsetZ.getNumber());
} catch (NumberFormatException | NullPointerException ex) { } catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(Minecraft.getMinecraft().player, "Array offset not valid.", true); EffortlessBuilding.log(mc.player, "Array offset not valid.");
EffortlessBuilding.log("Array offset not valid. Resetting to default.");
} }
int arrayCount = 5; int arrayCount = 5;
try { try {
arrayCount = Integer.parseInt(textArrayCount.getText()); arrayCount = (int) textArrayCount.getNumber();
} catch (NumberFormatException | NullPointerException ex) { } catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(Minecraft.getMinecraft().player, "Array count not valid.", true); EffortlessBuilding.log(mc.player, "Array count not valid.");
EffortlessBuilding.log("Array count not valid. Resetting to default.");
} }
arrayCount = Math.max(1, arrayCount);
arrayCount = Math.min(Array.MAX_COUNT, arrayCount);
Array.ArraySettings a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount); Array.ArraySettings a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount);
@@ -306,9 +386,32 @@ public class SettingsGui extends GuiScreen {
if (buildSettings == null) buildSettings = new BuildSettingsManager.BuildSettings(); if (buildSettings == null) buildSettings = new BuildSettingsManager.BuildSettings();
buildSettings.setMirrorSettings(m); buildSettings.setMirrorSettings(m);
buildSettings.setArraySettings(a); buildSettings.setArraySettings(a);
//Sanitize
String error = BuildSettingsManager.sanitize(buildSettings, mc.player);
if (!error.isEmpty()) EffortlessBuilding.log(mc.player, error);
BuildSettingsManager.setBuildSettings(mc.player, buildSettings); BuildSettingsManager.setBuildSettings(mc.player, buildSettings);
//Send to server //Send to server
EffortlessBuilding.packetHandler.sendToServer(new BuildSettingsMessage(buildSettings)); EffortlessBuilding.packetHandler.sendToServer(new BuildSettingsMessage(buildSettings));
} }
private int getArrayReach() {
try
{
//find largest offset
double x = Math.abs(textArrayOffsetX.getNumber());
double y = Math.abs(textArrayOffsetY.getNumber());
double z = Math.abs(textArrayOffsetZ.getNumber());
double largestOffset = Math.max(Math.max(x, y), z);
return (int) (largestOffset * textArrayCount.getNumber());
} catch (NumberFormatException | NullPointerException ex) {
return -1;
}
}
private boolean isCurrentReachValid(int currentReach, int maxReach) {
return currentReach <= maxReach && currentReach > -1;
}
} }

View File

@@ -0,0 +1,307 @@
package nl.requios.effortlessbuilding.helper;
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.item.ItemStack;
import net.minecraft.item.ItemTool;
import net.minecraft.util.math.*;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.*;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Color;
@Mod.EventBusSubscriber(Side.CLIENT)
public class RenderHelper {
private static final Color colorX = new Color(255, 72, 52);
private static final Color colorY = new Color(67, 204, 51);
private static final Color colorZ = new Color(52, 247, 255);
private static final int lineAlpha = 200;
private static final int planeAlpha = 75;
private static final Vec3d epsilon = new Vec3d(0.001, 0.001, 0.001); //prevents z-fighting
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);
}
@SubscribeEvent
public static void onRender(RenderWorldLastEvent event) {
EntityPlayer player = Minecraft.getMinecraft().player;
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
if (buildSettings == null) return;
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
Array.ArraySettings a = buildSettings.getArraySettings();
begin(event.getPartialTicks());
//Mirror
if (m != null && m.enabled && (m.mirrorX || m.mirrorY || m.mirrorZ))
{
Vec3d pos = m.position.add(epsilon);
int radius = m.radius;
if (m.mirrorX)
{
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(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(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(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(m);
}
}
//Render block outlines
RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver;
//Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS)
if (objectMouseOver != null && objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK)
{
BlockPos blockPos = objectMouseOver.getBlockPos();
//Check if tool (or none) in hand
ItemStack mainhand = player.getHeldItemMainhand();
//ItemStack offhand = player.getHeldItemOffhand();
//boolean noneInHand = mainhand.isEmpty() && (offhand.isEmpty() || offhand.getItem() instanceof ItemTool);
boolean toolInHand = !mainhand.isEmpty() && mainhand.getItem() instanceof ItemTool;
if (!buildSettings.doQuickReplace() && !toolInHand) {
blockPos = blockPos.offset(objectMouseOver.sideHit);
}
if (buildSettings.doQuickReplace() && !toolInHand) {
//Get under tall grass and other replaceable blocks
if (player.world.getBlockState(blockPos).getBlock().isReplaceable(player.world, blockPos)) {
blockPos = blockPos.down();
}
}
//Render current block outline based on config, or when QuickReplace is enabled
if (buildSettings.doQuickReplace() || BuildConfig.visuals.showOutlineOnCurrentBlock) {
RenderHelper.renderBlockOutline(blockPos);
}
//Mirror
if (m != null && m.enabled && (m.mirrorX || m.mirrorY || m.mirrorZ) &&
!(blockPos.getX() + 0.5 < m.position.x - m.radius) && !(blockPos.getX() + 0.5 > m.position.x + m.radius) &&
!(blockPos.getY() + 0.5 < m.position.y - m.radius) && !(blockPos.getY() + 0.5 > m.position.y + m.radius) &&
!(blockPos.getZ() + 0.5 < m.position.z - m.radius) && !(blockPos.getZ() + 0.5 > m.position.z + m.radius))
{
if (m.mirrorX) drawMirrorBlockOutlineX(buildSettings, blockPos);
if (m.mirrorY) drawMirrorBlockOutlineY(buildSettings, blockPos);
if (m.mirrorZ) drawMirrorBlockOutlineZ(buildSettings, blockPos);
}
//Array
if (a != null && a.enabled && (a.offset.getX() != 0 || a.offset.getY() != 0 || a.offset.getZ() != 0)) {
drawArrayBlockOutlines(a, blockPos);
}
}
end();
}
//----Mirror----
public static void drawMirrorPlane(Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) {
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
if (drawPlanes) {
bufferBuilder.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(posA.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posA.x, posB.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posB.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
tessellator.draw();
}
if (drawLines) {
Vec3d middle = posA.add(posB).scale(0.5);
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(posA.x, middle.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(posB.x, middle.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(middle.x, posA.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(middle.x, posB.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
tessellator.draw();
}
}
public static void drawMirrorPlaneY(Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) {
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
if (drawPlanes) {
bufferBuilder.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(posA.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posA.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
tessellator.draw();
}
if (drawLines) {
Vec3d middle = posA.add(posB).scale(0.5);
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(middle.x, middle.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(middle.x, middle.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(posA.x, middle.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(posB.x, middle.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
tessellator.draw();
}
}
public static void drawMirrorLines(Mirror.MirrorSettings m) {
Vec3d pos = m.position.add(epsilon);
GL11.glColor4d(100, 100, 100, 255);
GL11.glLineWidth(2);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(pos.x - m.radius, pos.y, pos.z).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x + m.radius, pos.y, pos.z).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x, pos.y - m.radius, pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x, pos.y + m.radius, pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x, pos.y, pos.z - m.radius).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x, pos.y, pos.z + m.radius).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex();
tessellator.draw();
}
public static void drawMirrorBlockOutlineX(BuildSettingsManager.BuildSettings buildSettings, BlockPos oldBlockPos) {
Mirror.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
drawArrayBlockOutlines(buildSettings.getArraySettings(), newBlockPos);
if (m.mirrorY) drawMirrorBlockOutlineY(buildSettings, newBlockPos);
if (m.mirrorZ) drawMirrorBlockOutlineZ(buildSettings, newBlockPos);
}
public static void drawMirrorBlockOutlineY(BuildSettingsManager.BuildSettings buildSettings, BlockPos oldBlockPos) {
Mirror.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
drawArrayBlockOutlines(buildSettings.getArraySettings(), newBlockPos);
if (m.mirrorZ) drawMirrorBlockOutlineZ(buildSettings, newBlockPos);
}
public static void drawMirrorBlockOutlineZ(BuildSettingsManager.BuildSettings buildSettings, BlockPos oldBlockPos) {
Mirror.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
drawArrayBlockOutlines(buildSettings.getArraySettings(), newBlockPos);
}
//----Array----
public static void drawArrayBlockOutlines(Array.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

@@ -0,0 +1,212 @@
package nl.requios.effortlessbuilding.helper;
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.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Enchantments;
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.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import javax.annotation.Nonnull;
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 (re)place 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);
return canHarvestBlock(blockState.getBlock(), player, world, pos);
}
//From ForgeHooks#canHarvestBlock
public static boolean canHarvestBlock(@Nonnull Block block, @Nonnull EntityPlayer player, @Nonnull IBlockAccess world, @Nonnull BlockPos pos)
{
IBlockState state = world.getBlockState(pos);
state = state.getBlock().getActualState(state, world, pos);
if (state.getMaterial().isToolNotRequired())
{
return true;
}
ItemStack stack = player.getHeldItemMainhand();
String tool = block.getHarvestTool(state);
if (stack.isEmpty() || tool == null)
{
return player.canHarvestBlock(state);
}
if (stack.getItemDamage() >= stack.getMaxDamage()) return false;
int toolLevel = stack.getItem().getHarvestLevel(stack, tool, player, state);
if (toolLevel < 0)
{
return player.canHarvestBlock(state);
}
return toolLevel >= block.getHarvestLevel(state);
}
//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);
int fortune = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, player.getHeldItemMainhand());
List<ItemStack> drops = blockState.getBlock().getDrops(world, pos, blockState, fortune);
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

@@ -16,14 +16,11 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.ICapabilityProvider; 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.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.Array;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.Mirror;
import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider; import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider;
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@@ -40,7 +37,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 +56,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,42 +69,40 @@ 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;
} }
@Override @Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) { public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
ItemStack bag = player.getHeldItem(hand);
if (player.isSneaking()) { if (player.isSneaking()) {
if (world.isRemote) return new ActionResult<>(EnumActionResult.SUCCESS, player.getHeldItem(hand)); if (world.isRemote) return new ActionResult<>(EnumActionResult.SUCCESS, bag);
//Open inventory //Open inventory
player.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, world, 0, 0, 0); player.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, world, 0, 0, 0);
} else { } else {
//Use item //Use item
//Get bag inventory //Get bag inventory
ItemStack bag = player.getHeldItem(hand);
IItemHandler bagInventory = getBagInventory(bag); IItemHandler bagInventory = getBagInventory(bag);
if (bagInventory == null) if (bagInventory == null)
return new ActionResult<>(EnumActionResult.FAIL, player.getHeldItem(hand)); return new ActionResult<>(EnumActionResult.FAIL, bag);
int randomSlot = pickRandomSlot(bagInventory); ItemStack toUse = pickRandomStack(bagInventory);
if (randomSlot < 0 || randomSlot > bagInventory.getSlots()) if (toUse.isEmpty()) return new ActionResult<>(EnumActionResult.FAIL, bag);
return new ActionResult<>(EnumActionResult.FAIL, player.getHeldItem(hand));
ItemStack toUse = bagInventory.getStackInSlot(randomSlot);
if (toUse.isEmpty()) return new ActionResult<>(EnumActionResult.FAIL, player.getHeldItem(hand));
return toUse.useItemRightClick(world, player, hand); return toUse.useItemRightClick(world, player, hand);
} }
return new ActionResult<>(EnumActionResult.PASS, player.getHeldItem(hand)); return new ActionResult<>(EnumActionResult.PASS, bag);
} }
/** /**
@@ -131,7 +122,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 +139,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 +177,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,9 +1,7 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.IThreadListener; import net.minecraft.util.IThreadListener;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@@ -51,6 +49,8 @@ public class BuildSettingsMessage implements IMessage {
buf.writeInt(a.count); buf.writeInt(a.count);
buf.writeBoolean(buildSettings.doQuickReplace()); buf.writeBoolean(buildSettings.doQuickReplace());
buf.writeInt(buildSettings.getReachUpgrade());
} }
@Override @Override
@@ -73,7 +73,10 @@ public class BuildSettingsMessage implements IMessage {
Array.ArraySettings a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount); Array.ArraySettings a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount);
boolean quickReplace = buf.readBoolean(); boolean quickReplace = buf.readBoolean();
buildSettings = new BuildSettings(m, a, quickReplace);
int reachUpgrade = buf.readInt();
buildSettings = new BuildSettings(m, a, quickReplace, reachUpgrade);
} }
// The params of the IMessageHandler are <REQ, REPLY> // The params of the IMessageHandler are <REQ, REPLY>
@@ -88,15 +91,9 @@ public class BuildSettingsMessage implements IMessage {
EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
// The value that was sent // The value that was sent
BuildSettings buildSettings = message.buildSettings; BuildSettings buildSettings = message.buildSettings;
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
Array.ArraySettings a = buildSettings.getArraySettings();
// Sanitize // Sanitize
m.radius = Math.min(m.radius, Mirror.MAX_RADIUS); BuildSettingsManager.sanitize(buildSettings, player);
m.radius = Math.max(1, m.radius);
a.count = Math.min(a.count, Array.MAX_COUNT);
a.count = Math.max(0, a.count);
// Execute the action on the main server thread by adding it as a scheduled task // Execute the action on the main server thread by adding it as a scheduled task
IThreadListener threadListener = EffortlessBuilding.proxy.getThreadListenerFromContext(ctx); IThreadListener threadListener = EffortlessBuilding.proxy.getThreadListenerFromContext(ctx);

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) {
@@ -86,25 +88,39 @@ public class ClientProxy implements IProxy {
@SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true) @SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true)
public static void onKeyPress(InputEvent.KeyInputEvent event) { public static void onKeyPress(InputEvent.KeyInputEvent event) {
// check each enumerated key binding type for pressed and take appropriate action
EntityPlayerSP player = Minecraft.getMinecraft().player; EntityPlayerSP player = Minecraft.getMinecraft().player;
//Remember to send packet to server if necessary
//Show HUD
if (keyBindings[0].isPressed()) { if (keyBindings[0].isPressed()) {
// do stuff for this key binding here //Disabled if max reach is 0, might be set in the config that way.
// remember you may need to send packet to server if (BuildSettingsManager.getMaxReach(player) == 0) {
EffortlessBuilding.log(player, "Effortless Building is disabled until your reach has increased. Increase your reach with craftable reach upgrades.");
} else {
if (Minecraft.getMinecraft().currentScreen == null) { if (Minecraft.getMinecraft().currentScreen == null) {
Minecraft.getMinecraft().displayGuiScreen(new SettingsGui()); Minecraft.getMinecraft().displayGuiScreen(new SettingsGui());
} else { } else {
player.closeScreen(); player.closeScreen();
} }
} }
}
//QuickReplace toggle
if (keyBindings[1].isPressed()) { if (keyBindings[1].isPressed()) {
// do stuff for this key binding here
// remember you may need to send packet to server
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player); BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
buildSettings.setQuickReplace(!buildSettings.doQuickReplace()); buildSettings.setQuickReplace(!buildSettings.doQuickReplace());
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));
} }
//Creative/survival mode toggle
if (keyBindings[2].isPressed()) {
if (player.isCreative()) {
player.sendChatMessage("/gamemode 0");
} else {
player.sendChatMessage("/gamemode 1");
}
}
} }
@SubscribeEvent @SubscribeEvent
@@ -112,6 +128,7 @@ public class ClientProxy implements IProxy {
if (event.phase != TickEvent.Phase.START) return; if (event.phase != TickEvent.Phase.START) return;
RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver; RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver;
//Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS)
if (objectMouseOver == null) return; if (objectMouseOver == null) return;
if (currentLookAt == null) { if (currentLookAt == null) {

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -2,7 +2,7 @@
{ {
"modid": "effortlessbuilding", "modid": "effortlessbuilding",
"name": "Effortless Building", "name": "Effortless Building",
"description": "Makes building easier by providing tools like mirrors, arrays, quickreplace and a block randomizer.", "description": "Makes building easier by providing tools like mirrors, arrays, QuickReplace and a block randomizer. For survival and creative mode.",
"version": "${version}", "version": "${version}",
"mcversion": "${mcversion}", "mcversion": "${mcversion}",
"url": "https://minecraft.curseforge.com/projects/effortless-building", "url": "https://minecraft.curseforge.com/projects/effortless-building",