8 Commits

Author SHA1 Message Date
Christian Knaapen
346fc6d533 Fixed mouse clicks in Modifier Settings sometimes being in the wrong place.
Fixed typing in multiple text fields at once.
2019-02-28 18:25:39 +01:00
Christian Knaapen
6678405c75 Settings are saved across dimensions (including reach upgrades, issue #12).
Fixed silk touch, shearing leaves, dropping bed etc. (issue #15)
Items dont drop directly to inventory anymore because of above fix, might be re-added later.
Can no longer place blocks in entities (including the player).
Added support for changing config ingame.
Added preliminary ArchitectureCraft compatibility (places right type, not rotation yet).
Updated forge.
2019-02-14 14:57:28 +01:00
Christian Knaapen
d07751a01f Fixed issue #8 Craft when activating the menu.
Fixed being able to mine bedrock. Whoops.
Fixed grass and flowers instabreaking other blocks.
2019-01-11 03:01:04 +01:00
Christian Knaapen
f3ad36e6a6 Fixed rotation and various small bugs. 2019-01-10 17:21:56 +01:00
Christian Knaapen
aeb4df6156 Added rotation to blocks placed with radial mirror.
Added alternative mode where every other slice of the radial mirror is mirrored.
Fixed issue #6 Crash when creating new world after first launch.
2019-01-08 18:53:12 +01:00
Christian Knaapen
8230f93b0c Added radial mirror with position, slices, and radius. With GUI, capability and network.
Optimized imports.
2019-01-04 17:06:58 +01:00
Christian Knaapen
3d3a90e76f Message when using reach upgrades in creative.
Sound when placing blocks far away.
2019-01-02 17:05:51 +01:00
Christian Knaapen
36a698cd95 Increased range for placing and breaking blocks (breaking at range only in creative).
Added reach upgrade items.
Added reach command (usage: /reach <level>).
2018-12-23 22:15:05 +01:00
43 changed files with 1484 additions and 231 deletions

View File

@@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
version = "0.5"
version = "1.0.3"
group = "nl.requios.effortlessbuilding" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "effortlessbuilding"
@@ -21,7 +21,7 @@ compileJava {
}
minecraft {
version = "1.12.2-14.23.4.2705"
version = "1.12.2-14.23.5.2768"
runDir = "run"
// the mappings can be changed at any time, and must be in the following format.
@@ -29,7 +29,7 @@ minecraft {
// stable_# stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// simply re-run your setup task after changing the mappings to update your workspace.
mappings = "snapshot_20171003"
mappings = "stable_39"
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
}

View File

@@ -1,6 +1,5 @@
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;
@@ -9,11 +8,7 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import java.util.ArrayList;

View File

@@ -13,7 +13,12 @@ public class BuildConfig {
public static class Reach {
@Comment({"Reach: how far away the player can place blocks using mirror/array etc.",
"Maximum reach in creative"})
"Enable the crafting of reach upgrades to increase reach.",
"If disabled, reach is set to level 3 for survival players."})
public boolean enableReachUpgrades = true;
@Comment({"Maximum reach in creative",
"Keep in mind that chunks need to be loaded to be able to place blocks inside."})
public int maxReachCreative = 200;
@Comment({"Maximum reach in survival without upgrades",
@@ -32,6 +37,9 @@ public class BuildConfig {
}
public static class SurvivalBalancers {
@Comment({"Allows a survival player to break blocks that are far away, in addition to placing blocks.",
"Note: this allows insta-breaking of blocks in survival."})
public boolean breakFar = false;
@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.",

View File

@@ -9,16 +9,17 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import nl.requios.effortlessbuilding.network.BlockBrokenMessage;
import nl.requios.effortlessbuilding.network.BlockPlacedMessage;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
public class BuildModifiers {
@@ -45,6 +46,13 @@ public class BuildModifiers {
startPos = startPos.down();
}
//Check if player reach does not exceed startpos
int maxReach = ReachHelper.getMaxReach(player);
if (player.getPosition().distanceSq(startPos) > maxReach * maxReach) {
EffortlessBuilding.log(player, "Placement exceeds your reach.");
return;
}
//Format hitvec to 0.x
Vec3d hitVec = message.getHitVec();
hitVec = new Vec3d(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)), Math.abs(hitVec.z - ((int) hitVec.z)));
@@ -66,7 +74,7 @@ public class BuildModifiers {
if (world.isBlockLoaded(blockPos, true)) {
//check itemstack empty
if (itemStack.isEmpty()) continue;
SurvivalHelper.placeBlock(world, player, blockPos, blockState, itemStack, EnumFacing.UP, true, false);
SurvivalHelper.placeBlock(world, player, blockPos, blockState, itemStack, EnumFacing.UP, hitVec, false, false);
}
}
}
@@ -77,25 +85,43 @@ public class BuildModifiers {
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(event.getPlayer());
//Only use own place event if anything is enabled
if (isEnabled(buildSettings, event.getPos())) {
EffortlessBuilding.packetHandler.sendTo(new BlockPlacedMessage(), (EntityPlayerMP) event.getPlayer());
//EffortlessBuilding.packetHandler.sendTo(new BlockPlacedMessage(), (EntityPlayerMP) event.getPlayer());
event.setCanceled(true);
}
}
//Use a network message to break blocks in the distance using clientside mouse input
public static void onBlockBrokenMessage(EntityPlayer player, BlockBrokenMessage message) {
BlockPos blockPos = message.getBlockPos();
if (ReachHelper.canBreakFar(player) && message.isBlockHit()) {
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(player.world, blockPos, player.world.getBlockState(blockPos), player);
onBlockBroken(event);
}
}
public static void onBlockBroken(BlockEvent.BreakEvent event) {
if (event.getWorld().isRemote) return;
World world = event.getWorld();
BlockPos pos = event.getPos();
if (world.isRemote) return;
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(event.getPlayer());
//Only use own break event if anything is enabled
if (isEnabled(buildSettings, event.getPos())) {
if (isEnabled(buildSettings, pos)) {
//get coordinates
List<BlockPos> coordinates = findCoordinates(event.getPlayer(), event.getPos());
List<BlockPos> coordinates = findCoordinates(event.getPlayer(), pos);
//If the player is going to instabreak grass or a plant, only break other instabreaking things
boolean onlyInstaBreaking = world.getBlockState(pos).getBlockHardness(
world, pos) == 0f;
//break all those blocks
for (BlockPos coordinate : coordinates) {
if (event.getWorld().isBlockLoaded(coordinate, false)) {
SurvivalHelper.breakBlock(event.getWorld(), event.getPlayer(), coordinate);
if (world.isBlockLoaded(coordinate, false)) {
if (!onlyInstaBreaking || world.getBlockState(coordinate).getBlockHardness(world, coordinate) == 0f) {
SurvivalHelper.breakBlock(world, event.getPlayer(), coordinate);
}
}
}
}
@@ -109,9 +135,11 @@ public class BuildModifiers {
List<BlockPos> arrayCoordinates = Array.findCoordinates(player, startPos);
coordinates.addAll(arrayCoordinates);
coordinates.addAll(Mirror.findCoordinates(player, startPos));
//get array for each coordinate
coordinates.addAll(RadialMirror.findCoordinates(player, startPos));
//get mirror for each array coordinate
for (BlockPos coordinate : arrayCoordinates) {
coordinates.addAll(Mirror.findCoordinates(player, coordinate));
coordinates.addAll(RadialMirror.findCoordinates(player, coordinate));
}
return coordinates;
@@ -144,12 +172,14 @@ public class BuildModifiers {
List<IBlockState> arrayBlockStates = Array.findBlockStates(player, startPos, blockState, itemStack, itemStacks);
blockStates.addAll(arrayBlockStates);
blockStates.addAll(Mirror.findBlockStates(player, startPos, blockState, itemStack, itemStacks));
//add array for each mirror coordinate
blockStates.addAll(RadialMirror.findBlockStates(player, startPos, blockState, itemStack, itemStacks));
//add mirror for each array coordinate
List<BlockPos> arrayCoordinates = Array.findCoordinates(player, startPos);
for (int i = 0; i < arrayCoordinates.size(); i++) {
BlockPos coordinate = arrayCoordinates.get(i);
IBlockState blockState1 = arrayBlockStates.get(i);
blockStates.addAll(Mirror.findBlockStates(player, coordinate, blockState1, itemStack, itemStacks));
blockStates.addAll(RadialMirror.findBlockStates(player, coordinate, blockState1, itemStack, itemStacks));
}
//Adjust blockstates for torches and ladders etc to place on a valid side
@@ -167,6 +197,7 @@ public class BuildModifiers {
public static boolean isEnabled(BuildSettingsManager.BuildSettings buildSettings, BlockPos startPos) {
return Mirror.isEnabled(buildSettings.getMirrorSettings(), startPos) ||
Array.isEnabled(buildSettings.getArraySettings()) ||
RadialMirror.isEnabled(buildSettings.getRadialMirrorSettings(), startPos) ||
buildSettings.doQuickReplace();
}

View File

@@ -6,6 +6,7 @@ import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
import nl.requios.effortlessbuilding.capability.BuildModifierCapabilityManager;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
@Mod.EventBusSubscriber
@@ -40,30 +41,46 @@ public class BuildSettingsManager {
}
public static String sanitize(BuildSettings buildSettings, EntityPlayer player) {
int maxReach = getMaxReach(player);
int maxReach = ReachHelper.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 set to 1. ";
error += "Mirror size has to be at least 1. This has been corrected. ";
}
if (m.getReach() > maxReach) {
m.radius = maxReach / 2;
error += "Mirror exceeds your maximum reach. Reach has been set to max. ";
error += "Mirror exceeds your maximum reach of " + (maxReach / 2) + ". Radius has been set to "+ (maxReach / 2) + ". ";
}
//Array settings
Array.ArraySettings a = buildSettings.getArraySettings();
if (a.count < 0) {
a.count = 0;
error += "Array count cannot be negative. Count has been set to 0. ";
error += "Array count may not be negative. It has been reset to 0.";
}
if (a.getReach() > maxReach) {
a.count = 0;
error += "Array exceeds your maximum reach. Count has been set to 0. ";
error += "Array exceeds your maximum reach of " + maxReach + ". Array count has been reset to 0. ";
}
//Radial mirror settings
RadialMirror.RadialMirrorSettings r = buildSettings.getRadialMirrorSettings();
if (r.slices < 2) {
r.slices = 2;
error += "Radial mirror needs to have at least 2 slices. Slices has been set to 2.";
}
if (r.radius < 1) {
r.radius = 1;
error += "Radial mirror radius has to be at least 1. This has been corrected. ";
}
if (r.getReach() > maxReach) {
r.radius = maxReach / 2;
error += "Radial mirror exceeds your maximum reach of " + (maxReach / 2) + ". Radius has been set to "+ (maxReach / 2) + ". ";
}
//Other
@@ -77,54 +94,58 @@ public class BuildSettingsManager {
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 {
private Mirror.MirrorSettings mirrorSettings;
private Array.ArraySettings arraySettings;
private RadialMirror.RadialMirrorSettings radialMirrorSettings;
private boolean quickReplace = false;
private int reachUpgrade = 0;
public BuildSettings() {
mirrorSettings = new Mirror.MirrorSettings();
arraySettings = new Array.ArraySettings();
radialMirrorSettings = new RadialMirror.RadialMirrorSettings();
}
public BuildSettings(Mirror.MirrorSettings mirrorSettings, Array.ArraySettings arraySettings, boolean quickReplace, int reachUpgrade) {
public BuildSettings(Mirror.MirrorSettings mirrorSettings, Array.ArraySettings arraySettings,
RadialMirror.RadialMirrorSettings radialMirrorSettings, boolean quickReplace, int reachUpgrade) {
this.mirrorSettings = mirrorSettings;
this.arraySettings = arraySettings;
this.radialMirrorSettings = radialMirrorSettings;
this.quickReplace = quickReplace;
this.reachUpgrade = reachUpgrade;
}
public Mirror.MirrorSettings getMirrorSettings() {
return mirrorSettings;
if (this.mirrorSettings == null) this.mirrorSettings = new Mirror.MirrorSettings();
return this.mirrorSettings;
}
public void setMirrorSettings(Mirror.MirrorSettings mirrorSettings) {
if (mirrorSettings == null) return;
this.mirrorSettings = mirrorSettings;
}
public Array.ArraySettings getArraySettings() {
return arraySettings;
if (this.arraySettings == null) this.arraySettings = new Array.ArraySettings();
return this.arraySettings;
}
public void setArraySettings(Array.ArraySettings arraySettings) {
if (arraySettings == null) return;
this.arraySettings = arraySettings;
}
public RadialMirror.RadialMirrorSettings getRadialMirrorSettings() {
if (this.radialMirrorSettings == null) this.radialMirrorSettings = new RadialMirror.RadialMirrorSettings();
return this.radialMirrorSettings;
}
public void setRadialMirrorSettings(RadialMirror.RadialMirrorSettings radialMirrorSettings) {
if (radialMirrorSettings == null) return;
this.radialMirrorSettings = radialMirrorSettings;
}
public boolean doQuickReplace() {
return quickReplace;
}
@@ -154,6 +175,12 @@ public class BuildSettingsManager {
handleNewPlayer(player);
}
@SubscribeEvent
public static void onPlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) {
EntityPlayer player = event.player;
handleNewPlayer(player);
}
private static void handleNewPlayer(EntityPlayer player){
if (getBuildSettings(player) == null) {
setBuildSettings(player, new BuildSettings());

View File

@@ -17,11 +17,16 @@ import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.capability.*;
import nl.requios.effortlessbuilding.capability.BuildModifierCapabilityManager;
import nl.requios.effortlessbuilding.command.CommandReach;
import nl.requios.effortlessbuilding.gui.RandomizerBagGuiHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
import nl.requios.effortlessbuilding.item.ItemReachUpgrade1;
import nl.requios.effortlessbuilding.item.ItemReachUpgrade2;
import nl.requios.effortlessbuilding.item.ItemReachUpgrade3;
import nl.requios.effortlessbuilding.network.BlockBrokenMessage;
import nl.requios.effortlessbuilding.network.BlockPlacedMessage;
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
import nl.requios.effortlessbuilding.proxy.IProxy;
import org.apache.logging.log4j.Logger;
@@ -31,7 +36,7 @@ public class EffortlessBuilding
{
public static final String MODID = "effortlessbuilding";
public static final String NAME = "Effortless Building";
public static final String VERSION = "0.5";
public static final String VERSION = "1.0.3";
@Mod.Instance(EffortlessBuilding.MODID)
public static EffortlessBuilding instance;
@@ -47,12 +52,18 @@ public class EffortlessBuilding
public static final SimpleNetworkWrapper packetHandler = NetworkRegistry.INSTANCE.newSimpleChannel(EffortlessBuilding.MODID);
public static final ItemRandomizerBag ITEM_RANDOMIZER_BAG = new ItemRandomizerBag();
public static final ItemReachUpgrade1 ITEM_REACH_UPGRADE_1 = new ItemReachUpgrade1();
public static final ItemReachUpgrade2 ITEM_REACH_UPGRADE_2 = new ItemReachUpgrade2();
public static final ItemReachUpgrade3 ITEM_REACH_UPGRADE_3 = new ItemReachUpgrade3();
public static final Block[] BLOCKS = {
};
public static final Item[] ITEMS = {
ITEM_RANDOMIZER_BAG
ITEM_RANDOMIZER_BAG,
ITEM_REACH_UPGRADE_1,
ITEM_REACH_UPGRADE_2,
ITEM_REACH_UPGRADE_3
};
public static final int RANDOMIZER_BAG_GUI = 0;
@@ -72,6 +83,8 @@ public class EffortlessBuilding
EffortlessBuilding.packetHandler.registerMessage(BlockPlacedMessage.MessageHandler.class, BlockPlacedMessage.class, 1, Side.SERVER);
EffortlessBuilding.packetHandler.registerMessage(BlockPlacedMessage.MessageHandler.class, BlockPlacedMessage.class, 1, Side.CLIENT);
EffortlessBuilding.packetHandler.registerMessage(BlockBrokenMessage.MessageHandler.class, BlockBrokenMessage.class, 2, Side.SERVER);
proxy.preInit(event);
}
@@ -82,6 +95,7 @@ public class EffortlessBuilding
{
ConfigManager.sync(MODID, Config.Type.INSTANCE);
NetworkRegistry.INSTANCE.registerGuiHandler(EffortlessBuilding.instance, new RandomizerBagGuiHandler());
proxy.init(event);
}
@@ -95,6 +109,7 @@ public class EffortlessBuilding
@EventHandler
public void serverStarting(FMLServerStartingEvent event)
{
event.registerServerCommand(new CommandReach());
proxy.serverStarting(event);
}

View File

@@ -6,11 +6,8 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager;
@@ -21,11 +18,9 @@ import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import nl.requios.effortlessbuilding.capability.BuildModifierCapabilityManager;
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import java.util.ArrayList;
import java.util.List;
@Mod.EventBusSubscriber
@@ -57,7 +52,7 @@ public class EventHandler
}
@SubscribeEvent
public void onConfigChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event)
public static void onConfigChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event)
{
if (event.getModID().equals(EffortlessBuilding.MODID))
{
@@ -72,6 +67,7 @@ public class EventHandler
@SubscribeEvent
public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
//Still call it to cancel event
BuildModifiers.onBlockPlaced(event);
}
@@ -92,6 +88,7 @@ public class EventHandler
//EffortlessBuilding.log(player, String.valueOf(event.getNewSpeed()));
float originalBlockHardness = event.getState().getBlockHardness(world, pos);
if (originalBlockHardness < 0) return; //Dont break bedrock
float totalBlockHardness = 0;
//get coordinates
List<BlockPos> coordinates = BuildModifiers.findCoordinates(player, pos);

View File

@@ -1,6 +1,9 @@
package nl.requios.effortlessbuilding;
import net.minecraft.block.*;
import net.minecraft.block.BlockDirectional;
import net.minecraft.block.BlockDispenser;
import net.minecraft.block.BlockSlab;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
@@ -8,12 +11,7 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import java.util.ArrayList;
@@ -175,7 +173,7 @@ public class Mirror {
public static boolean isEnabled(MirrorSettings m, BlockPos startPos) {
if (m == null || !m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return false;
//if within mirror distance, mirror
//within mirror distance
if (startPos.getX() + 0.5 < m.position.x - m.radius || startPos.getX() + 0.5 > m.position.x + m.radius ||
startPos.getY() + 0.5 < m.position.y - m.radius || startPos.getY() + 0.5 > m.position.y + m.radius ||
startPos.getZ() + 0.5 < m.position.z - m.radius || startPos.getZ() + 0.5 > m.position.z + m.radius)

View File

@@ -0,0 +1,194 @@
package nl.requios.effortlessbuilding;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import java.util.ArrayList;
import java.util.List;
public class RadialMirror {
public static class RadialMirrorSettings {
public boolean enabled = false;
public Vec3d position = new Vec3d(0.5, 64.5, 0.5);
public int slices = 4;
public boolean alternate = false;
public int radius = 20;
public boolean drawLines = true, drawPlanes = false;
public RadialMirrorSettings() {
}
public RadialMirrorSettings(boolean enabled, Vec3d position, int slices, boolean alternate, int radius, boolean drawLines, boolean drawPlanes) {
this.enabled = enabled;
this.position = position;
this.slices = slices;
this.alternate = alternate;
this.radius = radius;
this.drawLines = drawLines;
this.drawPlanes = drawPlanes;
}
public int getReach() {
return radius * 2;
}
}
public static List<BlockPos> findCoordinates(EntityPlayer player, BlockPos startPos) {
List<BlockPos> coordinates = new ArrayList<>();
//find radial mirror settings for the player
RadialMirrorSettings r = BuildSettingsManager.getBuildSettings(player).getRadialMirrorSettings();
if (!isEnabled(r, startPos)) return coordinates;
//get angle between slices
double sliceAngle = 2 * Math.PI / r.slices;
Vec3d startVec = new Vec3d(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f);
Vec3d relStartVec = startVec.subtract(r.position);
double startAngleToCenter = MathHelper.atan2(relStartVec.x, relStartVec.z);
if (startAngleToCenter < 0) startAngleToCenter += Math.PI;
double startAngleInSlice = startAngleToCenter % sliceAngle;
for (int i = 1; i < r.slices; i++) {
double curAngle = sliceAngle * i;
//alternate mirroring of slices
if (r.alternate && i%2 == 1) {
curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice);
}
Vec3d relNewVec = relStartVec.rotateYaw((float) curAngle);
BlockPos newBlockPos = new BlockPos(r.position.add(relNewVec));
if (!coordinates.contains(newBlockPos) && !newBlockPos.equals(startPos)) coordinates.add(newBlockPos);
}
return coordinates;
}
public static List<IBlockState> findBlockStates(EntityPlayer player, BlockPos startPos, IBlockState blockState, ItemStack itemStack, List<ItemStack> itemStacks) {
List<IBlockState> blockStates = new ArrayList<>();
List<BlockPos> coordinates = new ArrayList<>(); //to keep track of duplicates
//find radial mirror settings for the player that placed the block
RadialMirrorSettings r = BuildSettingsManager.getBuildSettings(player).getRadialMirrorSettings();
if (!isEnabled(r, startPos)) return blockStates;
//get angle between slices
double sliceAngle = 2 * Math.PI / r.slices;
Vec3d startVec = new Vec3d(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f);
Vec3d relStartVec = startVec.subtract(r.position);
double startAngleToCenter = MathHelper.atan2(relStartVec.x, relStartVec.z);
double startAngleToCenterMod = startAngleToCenter < 0 ? startAngleToCenter + Math.PI : startAngleToCenter;
double startAngleInSlice = startAngleToCenterMod % sliceAngle;
//Rotate the original blockstate
blockState = rotateOriginalBlockState(startAngleToCenter, blockState);
//Randomizer bag synergy
IItemHandler bagInventory = null;
if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemRandomizerBag) {
bagInventory = ItemRandomizerBag.getBagInventory(itemStack);
}
IBlockState newBlockState;
for (int i = 1; i < r.slices; i++) {
newBlockState = blockState;
double curAngle = sliceAngle * i;
//alternate mirroring of slices
if (r.alternate && i%2 == 1) {
curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice);
}
Vec3d relNewVec = relStartVec.rotateYaw((float) curAngle);
BlockPos newBlockPos = new BlockPos(r.position.add(relNewVec));
if (coordinates.contains(newBlockPos) || newBlockPos.equals(startPos)) continue; //filter out duplicates
coordinates.add(newBlockPos);
//Randomizer bag synergy
if (bagInventory != null) {
itemStack = ItemRandomizerBag.pickRandomStack(bagInventory);
newBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, startPos, EnumFacing.UP, new Vec3d(0, 0, 0), EnumHand.MAIN_HAND);
newBlockState = rotateOriginalBlockState(startAngleToCenter, newBlockState);
}
//rotate
newBlockState = rotateBlockState(relNewVec, newBlockState, r.alternate && i%2 == 1);
blockStates.add(newBlockState);
itemStacks.add(itemStack);
}
return blockStates;
}
private static IBlockState rotateOriginalBlockState(double startAngleToCenter, IBlockState blockState) {
IBlockState newBlockState = blockState;
if (startAngleToCenter < -0.751 * Math.PI || startAngleToCenter > 0.749 * Math.PI) {
newBlockState = blockState.withRotation(Rotation.CLOCKWISE_180);
} else if (startAngleToCenter < -0.251 * Math.PI) {
newBlockState = blockState.withRotation(Rotation.COUNTERCLOCKWISE_90);
} else if (startAngleToCenter > 0.249 * Math.PI) {
newBlockState = blockState.withRotation(Rotation.CLOCKWISE_90);
}
return newBlockState;
}
private static IBlockState rotateBlockState(Vec3d relVec, IBlockState blockState, boolean alternate) {
IBlockState newBlockState;
double angleToCenter = MathHelper.atan2(relVec.x, relVec.z); //between -PI and PI
if (angleToCenter < -0.751 * Math.PI || angleToCenter > 0.749 * Math.PI) {
newBlockState = blockState.withRotation(Rotation.CLOCKWISE_180);
if (alternate) {
newBlockState = newBlockState.withMirror(Mirror.FRONT_BACK);
}
} else if (angleToCenter < -0.251 * Math.PI) {
newBlockState = blockState.withRotation(Rotation.CLOCKWISE_90);
if (alternate) {
newBlockState = newBlockState.withMirror(Mirror.LEFT_RIGHT);
}
} else if (angleToCenter > 0.249 * Math.PI) {
newBlockState = blockState.withRotation(Rotation.COUNTERCLOCKWISE_90);
if (alternate) {
newBlockState = newBlockState.withMirror(Mirror.LEFT_RIGHT);
}
} else {
newBlockState = blockState;
if (alternate) {
newBlockState = newBlockState.withMirror(Mirror.FRONT_BACK);
}
}
return newBlockState;
}
public static boolean isEnabled(RadialMirrorSettings r, BlockPos startPos) {
if (r == null || !r.enabled) return false;
if (new Vec3d(startPos.getX() + 0.5, startPos.getY() + 0.5, startPos.getZ() + 0.5).subtract(r.position).lengthSquared() >
r.radius * r.radius)
return false;
return true;
}
}

View File

@@ -14,6 +14,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import nl.requios.effortlessbuilding.Array;
import nl.requios.effortlessbuilding.BuildSettingsManager.BuildSettings;
import nl.requios.effortlessbuilding.Mirror;
import nl.requios.effortlessbuilding.RadialMirror;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -53,6 +54,7 @@ public class BuildModifierCapabilityManager {
//MIRROR
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
if (m == null) m = new Mirror.MirrorSettings();
compound.setBoolean("mirrorEnabled", m.enabled);
compound.setDouble("mirrorPosX", m.position.x);
compound.setDouble("mirrorPosY", m.position.y);
@@ -66,6 +68,7 @@ public class BuildModifierCapabilityManager {
//ARRAY
Array.ArraySettings a = buildSettings.getArraySettings();
if (a == null) a = new Array.ArraySettings();
compound.setBoolean("arrayEnabled", a.enabled);
compound.setInteger("arrayOffsetX", a.offset.getX());
compound.setInteger("arrayOffsetY", a.offset.getY());
@@ -75,6 +78,20 @@ public class BuildModifierCapabilityManager {
compound.setInteger("reachUpgrade", buildSettings.getReachUpgrade());
//compound.setBoolean("quickReplace", buildSettings.doQuickReplace()); dont save quickreplace
//RADIAL MIRROR
RadialMirror.RadialMirrorSettings r = buildSettings.getRadialMirrorSettings();
if (r == null) r = new RadialMirror.RadialMirrorSettings();
compound.setBoolean("radialMirrorEnabled", r.enabled);
compound.setDouble("radialMirrorPosX", r.position.x);
compound.setDouble("radialMirrorPosY", r.position.y);
compound.setDouble("radialMirrorPosZ", r.position.z);
compound.setInteger("radialMirrorSlices", r.slices);
compound.setBoolean("radialMirrorAlternate", r.alternate);
compound.setInteger("radialMirrorRadius", r.radius);
compound.setBoolean("radialMirrorDrawLines", r.drawLines);
compound.setBoolean("radialMirrorDrawPlanes", r.drawPlanes);
return compound;
}
@@ -103,7 +120,18 @@ public class BuildModifierCapabilityManager {
//boolean quickReplace = compound.getBoolean("quickReplace"); //dont load quickreplace
BuildSettings buildSettings = new BuildSettings(mirrorSettings, arraySettings, false, reachUpgrade);
//RADIAL MIRROR
boolean radialMirrorEnabled = compound.getBoolean("radialMirrorEnabled");
Vec3d radialMirrorPosition = new Vec3d(compound.getDouble("radialMirrorPosX"), compound.getDouble("radialMirrorPosY"), compound.getDouble("radialMirrorPosZ"));
int radialMirrorSlices = compound.getInteger("radialMirrorSlices");
boolean radialMirrorAlternate = compound.getBoolean("radialMirrorAlternate");
int radialMirrorRadius = compound.getInteger("radialMirrorRadius");
boolean radialMirrorDrawLines = compound.getBoolean("radialMirrorDrawLines");
boolean radialMirrorDrawPlanes = compound.getBoolean("radialMirrorDrawPlanes");
RadialMirror.RadialMirrorSettings radialMirrorSettings = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition,
radialMirrorSlices, radialMirrorAlternate, radialMirrorRadius, radialMirrorDrawLines, radialMirrorDrawPlanes);
BuildSettings buildSettings = new BuildSettings(mirrorSettings, arraySettings, radialMirrorSettings, false, reachUpgrade);
instance.setBuildModifierData(buildSettings);
}
}

View File

@@ -0,0 +1,43 @@
package nl.requios.effortlessbuilding.command;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.TextComponentString;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
public class CommandReach extends CommandBase {
@Override
public String getName() {
return "reach";
}
@Override
public String getUsage(ICommandSender sender) {
return "commands.reach.usage";
}
@Override
public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException {
if (args.length != 1) {
throw new WrongUsageException("commands.reach.usage");
}
if (sender instanceof EntityPlayerMP) {
EntityPlayerMP player = (EntityPlayerMP) sender;
//Set reach level to args[0]
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
buildSettings.setReachUpgrade(Integer.valueOf(args[0]));
BuildSettingsManager.setBuildSettings(player, buildSettings);
//Send to client
EffortlessBuilding.packetHandler.sendTo(new BuildSettingsMessage(buildSettings), player);
sender.sendMessage(new TextComponentString("Reach level of " + sender.getName() + " set to " + buildSettings.getReachUpgrade()));
}
}
}

View File

@@ -8,10 +8,10 @@ import net.minecraftforge.fml.client.config.GuiCheckBox;
import nl.requios.effortlessbuilding.Array;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
@@ -103,7 +103,7 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
textArrayCount.y = yy;
int currentReach = Math.max(-1, getArrayReach());
int maxReach = BuildSettingsManager.getMaxReach(mc.player);
int maxReach = ReachHelper.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, yy + 5, 0xFFFFFF, true);
@@ -139,7 +139,7 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
@Override
public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) {
super.mousePressed(slotIndex, mouseX, mouseY, mouseEvent, relativeX, relativeY);
super.mousePressed(slotIndex, mouseX, mouseY, mouseEvent, relativeX, relativeY);
arrayNumberFieldList.forEach(numberField -> numberField.mouseClicked(mouseX, mouseY, mouseEvent));
boolean insideArrayEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12;
@@ -168,14 +168,14 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
try {
arrayOffset = new BlockPos(textArrayOffsetX.getNumber(), textArrayOffsetY.getNumber(), textArrayOffsetZ.getNumber());
} catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(mc.player, "Array offset not valid.");
EffortlessBuilding.log(mc.player, "Array offset not a valid number.");
}
int arrayCount = 5;
try {
arrayCount = (int) textArrayCount.getNumber();
} catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(mc.player, "Array count not valid.");
EffortlessBuilding.log(mc.player, "Array count not a valid number.");
}
return new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount);

View File

@@ -3,9 +3,6 @@ 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;

View File

@@ -73,22 +73,24 @@ public class GuiScrollPane extends GuiListExtended {
int insideLeft = this.left + this.width / 2 - this.getListWidth() / 2 + 2;
int insideTop = this.top + 4 - (int)this.amountScrolled;
if (this.hasListHeader)
{
if (this.hasListHeader) {
this.drawListHeader(insideLeft, insideTop, tessellator);
}
//All entries
this.drawSelectionBox(insideLeft, insideTop, mouseXIn, mouseYIn, partialTicks);
GlStateManager.disableDepth();
//Dirt overlays on top and bottom
// this.overlayBackground(0, this.top, 255, 255);
// this.overlayBackground(this.bottom, this.height, 255, 255);
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE);
GlStateManager.disableAlpha();
GlStateManager.shadeModel(7425);
GlStateManager.disableTexture2D();
// //top fade
// bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
// bufferbuilder.pos((double)this.left, (double)(this.top + 5), 0.0D).tex(0.0D, 1.0D).color(100, 100, 100, 0).endVertex();
@@ -96,6 +98,7 @@ public class GuiScrollPane extends GuiListExtended {
// bufferbuilder.pos((double)this.right, (double)this.top, 0.0D).tex(1.0D, 0.0D).color(100, 100, 100, 100).endVertex();
// bufferbuilder.pos((double)this.left, (double)this.top, 0.0D).tex(0.0D, 0.0D).color(100, 100, 100, 100).endVertex();
// tessellator.draw();
// //top line
// bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
// bufferbuilder.pos((double)this.left, (double)this.top, 0.0D).tex(0.0D, 1.0D).color(20, 20, 20, 255).endVertex();
@@ -103,6 +106,7 @@ public class GuiScrollPane extends GuiListExtended {
// bufferbuilder.pos((double)this.right, (double)(this.top - 1), 0.0D).tex(1.0D, 0.0D).color(20, 20, 20, 255).endVertex();
// bufferbuilder.pos((double)this.left, (double)(this.top - 1), 0.0D).tex(0.0D, 0.0D).color(20, 20, 20, 255).endVertex();
// tessellator.draw();
// //bottom fade
// bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
// bufferbuilder.pos((double)this.left, (double)this.bottom, 0.0D).tex(0.0D, 1.0D).color(10, 10, 10, 100).endVertex();
@@ -110,6 +114,7 @@ public class GuiScrollPane extends GuiListExtended {
// bufferbuilder.pos((double)this.right, (double)(this.bottom - 5), 0.0D).tex(1.0D, 0.0D).color(10, 10, 10, 0).endVertex();
// bufferbuilder.pos((double)this.left, (double)(this.bottom - 5), 0.0D).tex(0.0D, 0.0D).color(10, 10, 10, 0).endVertex();
// tessellator.draw();
// //bottom line
// bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
// bufferbuilder.pos((double)this.left, (double)(this.bottom + 1), 0.0D).tex(0.0D, 1.0D).color(20, 20, 20, 255).endVertex();
@@ -137,12 +142,14 @@ public class GuiScrollPane extends GuiListExtended {
bufferbuilder.pos((double)scrollBarRight, (double)this.top, 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 255).endVertex();
bufferbuilder.pos((double)scrollBarLeft, (double)this.top, 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 255).endVertex();
tessellator.draw();
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
bufferbuilder.pos((double)scrollBarLeft, (double)(l1 + k1), 0.0D).tex(0.0D, 1.0D).color(128, 128, 128, 255).endVertex();
bufferbuilder.pos((double)scrollBarRight, (double)(l1 + k1), 0.0D).tex(1.0D, 1.0D).color(128, 128, 128, 255).endVertex();
bufferbuilder.pos((double)scrollBarRight, (double)l1, 0.0D).tex(1.0D, 0.0D).color(128, 128, 128, 255).endVertex();
bufferbuilder.pos((double)scrollBarLeft, (double)l1, 0.0D).tex(0.0D, 0.0D).color(128, 128, 128, 255).endVertex();
tessellator.draw();
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
bufferbuilder.pos((double)scrollBarLeft, (double)(l1 + k1 - 1), 0.0D).tex(0.0D, 1.0D).color(192, 192, 192, 255).endVertex();
bufferbuilder.pos((double)(scrollBarRight - 1), (double)(l1 + k1 - 1), 0.0D).tex(1.0D, 1.0D).color(192, 192, 192, 255).endVertex();
@@ -184,8 +191,7 @@ public class GuiScrollPane extends GuiListExtended {
public int getSlotIndexFromScreenCoords(int posX, int posY) {
int left = this.left + (this.width - this.getListWidth()) / 2;
int right = this.left + (this.width + this.getListWidth()) / 2;
int relativeMouseY = posY - this.top - this.headerPadding + (int)this.amountScrolled - 4; //click height in content dimensions
//int slotIndex = relativeMouseY / this.slotHeight;
int relativeMouseY = getRelativeMouseY(mouseY, 0);
//Iterate over every entry until relativeMouseY falls within its height
for (int i = 0; i < listEntries.size(); i++) {
@@ -201,25 +207,33 @@ public class GuiScrollPane extends GuiListExtended {
@Override
public boolean mouseClicked(int mouseX, int mouseY, int mouseEvent)
{
if (this.isMouseYWithinSlotBounds(mouseY))
{
int i = this.getSlotIndexFromScreenCoords(mouseX, mouseY);
int selectedSlot = this.getSlotIndexFromScreenCoords(mouseX, mouseY);
int relativeX = getRelativeMouseX(mouseX);
if (i >= 0)
{
int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2;
int k = this.top + 4 - this.getAmountScrolled() + getContentHeight(i) + this.headerPadding;
int relativeX = mouseX - j;
int relativeY = mouseY - k;
if (this.getListEntry(i).mousePressed(i, mouseX, mouseY, mouseEvent, relativeX, relativeY))
{
this.setEnabled(false);
return true;
}
}
//Always pass through mouseclicked, to be able to unfocus textfields
for (int i = 0; i < this.listEntries.size(); i++) {
int relativeY = getRelativeMouseY(mouseY, i);
this.getListEntry(i).mousePressed(selectedSlot, mouseX, mouseY, mouseEvent, relativeX, relativeY);
}
// if (this.isMouseYWithinSlotBounds(mouseY))
// {
// int i = this.getSlotIndexFromScreenCoords(mouseX, mouseY);
//
// if (i >= 0)
// {
// int relativeX = getRelativeMouseX(mouseX);
// int relativeY = getRelativeMouseY(mouseY, i);
//
// if (this.getListEntry(i).mousePressed(i, mouseX, mouseY, mouseEvent, relativeX, relativeY))
// {
// this.setEnabled(false);
// return true;
// }
// }
// }
return false;
}
@@ -228,10 +242,8 @@ public class GuiScrollPane extends GuiListExtended {
{
for (int i = 0; i < this.getSize(); ++i)
{
int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2;
int k = this.top + 4 - this.getAmountScrolled() + getContentHeight(i) + this.headerPadding;
int relativeX = x - j;
int relativeY = y - k;
int relativeX = getRelativeMouseX(mouseX);
int relativeY = getRelativeMouseY(mouseY, i);
this.getListEntry(i).mouseReleased(i, x, y, mouseEvent, relativeX, relativeY);
}
@@ -246,9 +258,8 @@ public class GuiScrollPane extends GuiListExtended {
this.mouseY <= this.bottom) {
int i = this.left + (this.width - this.getListWidth()) / 2;
int j = this.left + (this.width + this.getListWidth()) / 2;
int relativeMouseY = this.mouseY - this.top - this.headerPadding + (int) this.amountScrolled -
4; //click height in content dimensions
int slotIndex = getSlotIndexFromScreenCoords(this.mouseX, this.mouseY);
int relativeMouseY = getRelativeMouseY(mouseY, slotIndex);
if (slotIndex > -1) {
this.elementClicked(slotIndex, false, this.mouseX, this.mouseY);
@@ -265,9 +276,8 @@ public class GuiScrollPane extends GuiListExtended {
if (this.mouseY >= this.top && this.mouseY <= this.bottom) {
int i2 = this.left + (this.width - this.getListWidth()) / 2;
int j2 = this.left + (this.width + this.getListWidth()) / 2;
int relativeMouseY = this.mouseY - this.top - this.headerPadding + (int) this.amountScrolled -
4; //click height in content dimensions
int slotIndex = getSlotIndexFromScreenCoords(this.mouseX, this.mouseY);
int relativeMouseY = getRelativeMouseY(mouseY, slotIndex);
if (slotIndex > -1) {
boolean flag = slotIndex == this.selectedElement &&
@@ -383,6 +393,26 @@ public class GuiScrollPane extends GuiListExtended {
}
}
private int getRelativeMouseX(int mouseX) {
int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2;
return mouseX - j;
}
private int getRelativeMouseY(int mouseY, int contentIndex) {
int k = this.top + 4 - this.getAmountScrolled() + getContentHeight(contentIndex) + this.headerPadding;
int relativeMouseY = mouseY - k;
//Content might be centered, adjust relative mouse y accordingly
int contentHeight = getContentHeight();
int insideHeight = this.bottom - this.top - 4;
if (contentHeight < insideHeight) {
//it fits, so we can center it vertically
relativeMouseY -= (insideHeight - contentHeight) / 2;
}
return relativeMouseY;
}
//PASSTHROUGHS
public int initGui(int id, List<GuiButton> buttonList) {
for (IScrollEntry entry : this.listEntries) {

View File

@@ -9,6 +9,7 @@ import net.minecraftforge.fml.client.config.GuiCheckBox;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.Mirror;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import java.io.IOException;
import java.util.ArrayList;
@@ -72,7 +73,7 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
textMirrorRadius.setNumber(50);
//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 + "Max: " + TextFormatting.GOLD + ReachHelper.getMaxReach(mc.player) / 2,
TextFormatting.GRAY + "Upgradeable in survival with reach upgrades."));
mirrorNumberFieldList.add(textMirrorRadius);
@@ -161,7 +162,7 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
buttonMirrorX.y = yy;
buttonMirrorY.y = yy;
buttonMirrorZ.y = yy;
fontRenderer.drawString("Reach", left + 176 + offset, yy + 2, 0xFFFFFF, true);
fontRenderer.drawString("Radius", left + 176 + offset, yy + 2, 0xFFFFFF, true);
textMirrorRadius.y = yy - 3;
yy = y + 72;
@@ -265,7 +266,7 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
try {
mirrorPos = new Vec3d(textMirrorPosX.getNumber(), textMirrorPosY.getNumber(), textMirrorPosZ.getNumber());
} catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(mc.player, "Mirror position not valid.");
EffortlessBuilding.log(mc.player, "Mirror position not a valid number.");
}
boolean mirrorX = buttonMirrorX.isChecked();
@@ -276,7 +277,7 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
try {
mirrorRadius = (int) textMirrorRadius.getNumber();
} catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(mc.player, "Mirror radius not valid.");
EffortlessBuilding.log(mc.player, "Mirror radius not a valid number.");
}
return new Mirror.MirrorSettings(mirrorEnabled, mirrorPos, mirrorX, mirrorY, mirrorZ, mirrorRadius, drawLines, drawPlanes);

View File

@@ -0,0 +1,302 @@
package nl.requios.effortlessbuilding.gui;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.client.config.GuiCheckBox;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.RadialMirror;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
protected static final ResourceLocation BUILDING_ICONS = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/building_icons.png");
protected List<GuiButton> radialMirrorButtonList = new ArrayList<>();
protected List<GuiIconButton> radialMirrorIconButtonList = new ArrayList<>();
protected List<GuiNumberField> radialMirrorNumberFieldList = new ArrayList<>();
private GuiNumberField textRadialMirrorPosX, textRadialMirrorPosY, textRadialMirrorPosZ, textRadialMirrorSlices, textRadialMirrorRadius;
private GuiCheckBox buttonRadialMirrorEnabled, buttonRadialMirrorAlternate;
private GuiIconButton buttonCurrentPosition, buttonToggleOdd, buttonDrawPlanes, buttonDrawLines;
private boolean drawPlanes, drawLines, toggleOdd;
public RadialMirrorSettingsGui(GuiScrollPane scrollPane) {
super(scrollPane);
}
@Override
public int initGui(int id, List<GuiButton> buttonList) {
id = super.initGui(id, buttonList);
int y = top - 2;
buttonRadialMirrorEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false);
buttonList.add(buttonRadialMirrorEnabled);
y = top + 18;
textRadialMirrorPosX = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 58, y, 62, 18);
textRadialMirrorPosX.setNumber(0);
textRadialMirrorPosX.setTooltip(
Arrays.asList("The position of the radial mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5."));
radialMirrorNumberFieldList.add(textRadialMirrorPosX);
textRadialMirrorPosY = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 138, y, 62, 18);
textRadialMirrorPosY.setNumber(64);
textRadialMirrorPosY.setTooltip(Arrays.asList("The position of the radial mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5."));
radialMirrorNumberFieldList.add(textRadialMirrorPosY);
textRadialMirrorPosZ = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 218, y, 62, 18);
textRadialMirrorPosZ.setNumber(0);
textRadialMirrorPosZ.setTooltip(Arrays.asList("The position of the radial mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5."));
radialMirrorNumberFieldList.add(textRadialMirrorPosZ);
y = top + 47;
textRadialMirrorSlices = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 55, y, 50, 18);
textRadialMirrorSlices.setNumber(4);
textRadialMirrorSlices.setTooltip(Arrays.asList("The number of repeating slices.", TextFormatting.GRAY + "Minimally 2."));
radialMirrorNumberFieldList.add(textRadialMirrorSlices);
textRadialMirrorRadius = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 218, y, 62, 18);
textRadialMirrorRadius.setNumber(50);
//TODO change to diameter (remove /2)
textRadialMirrorRadius.setTooltip(Arrays.asList("How far the radial mirror reaches from its center position.",
TextFormatting.GRAY + "Max: " + TextFormatting.GOLD + ReachHelper.getMaxReach(mc.player) / 2,
TextFormatting.GRAY + "Upgradeable in survival with reach upgrades."));
radialMirrorNumberFieldList.add(textRadialMirrorRadius);
y = top + 72;
buttonCurrentPosition = new GuiIconButton(id++, left + 5, y, 0, 0, BUILDING_ICONS);
buttonCurrentPosition.setTooltip("Set radial mirror position to current player position");
radialMirrorIconButtonList.add(buttonCurrentPosition);
buttonToggleOdd = new GuiIconButton(id++, left + 35, y, 0, 20, BUILDING_ICONS);
buttonToggleOdd.setTooltip(Arrays.asList("Set radial mirror position to middle of block", "for odd numbered builds"));
radialMirrorIconButtonList.add(buttonToggleOdd);
buttonDrawLines = new GuiIconButton(id++, left + 65, y, 0, 40, BUILDING_ICONS);
buttonDrawLines.setTooltip("Show lines");
radialMirrorIconButtonList.add(buttonDrawLines);
buttonDrawPlanes = new GuiIconButton(id++, left + 95, y, 0, 60, BUILDING_ICONS);
buttonDrawPlanes.setTooltip("Show area");
radialMirrorIconButtonList.add(buttonDrawPlanes);
y = top + 76;
buttonRadialMirrorAlternate = new GuiCheckBox(id++, left + 140, y, " Alternate", false);
radialMirrorButtonList.add(buttonRadialMirrorAlternate);
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(mc.player);
if (buildSettings != null) {
RadialMirror.RadialMirrorSettings r = buildSettings.getRadialMirrorSettings();
buttonRadialMirrorEnabled.setIsChecked(r.enabled);
textRadialMirrorPosX.setNumber(r.position.x);
textRadialMirrorPosY.setNumber(r.position.y);
textRadialMirrorPosZ.setNumber(r.position.z);
textRadialMirrorSlices.setNumber(r.slices);
buttonRadialMirrorAlternate.setIsChecked(r.alternate);
textRadialMirrorRadius.setNumber(r.radius);
drawLines = r.drawLines;
drawPlanes = r.drawPlanes;
buttonDrawLines.setUseAlternateIcon(drawLines);
buttonDrawPlanes.setUseAlternateIcon(drawPlanes);
buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines");
buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area");
if (textRadialMirrorPosX.getNumber() == Math.floor(textRadialMirrorPosX.getNumber())) {
toggleOdd = false;
buttonToggleOdd.setTooltip(Arrays.asList("Set radial mirror position to middle of block", "for odd numbered builds"));
} else {
toggleOdd = true;
buttonToggleOdd.setTooltip(Arrays.asList("Set radial mirror position to corner of block", "for even numbered builds"));
}
buttonToggleOdd.setUseAlternateIcon(toggleOdd);
}
buttonList.addAll(radialMirrorButtonList);
buttonList.addAll(radialMirrorIconButtonList);
setCollapsed(!buttonRadialMirrorEnabled.isChecked());
return id;
}
@Override
public void updateScreen() {
super.updateScreen();
radialMirrorNumberFieldList.forEach(GuiNumberField::update);
}
@Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY,
boolean isSelected, float partialTicks) {
super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partialTicks);
int yy = y;
int offset = 8;
buttonRadialMirrorEnabled.drawButton(this.mc, mouseX, mouseY, partialTicks);
if (buttonRadialMirrorEnabled.isChecked()) {
buttonRadialMirrorEnabled.y = yy;
fontRenderer.drawString("Radial mirror enabled", left + offset, yy + 2, 0xFFFFFF, true);
yy = y + 18;
fontRenderer.drawString("Position", left + offset, yy + 5, 0xFFFFFF, true);
fontRenderer.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF, true);
textRadialMirrorPosX.y = yy;
fontRenderer.drawString("Y", left + 120 + offset, yy + 5, 0xFFFFFF, true);
textRadialMirrorPosY.y = yy;
fontRenderer.drawString("Z", left + 200 + offset, yy + 5, 0xFFFFFF, true);
textRadialMirrorPosZ.y = yy;
yy = y + 50;
fontRenderer.drawString("Slices", left + offset, yy + 2, 0xFFFFFF, true);
textRadialMirrorSlices.y = yy - 3;
fontRenderer.drawString("Radius", left + 176 + offset, yy + 2, 0xFFFFFF, true);
textRadialMirrorRadius.y = yy - 3;
yy = y + 72;
buttonCurrentPosition.y = yy;
buttonToggleOdd.y = yy;
buttonDrawLines.y = yy;
buttonDrawPlanes.y = yy;
yy = y + 76;
buttonRadialMirrorAlternate.y = yy;
radialMirrorButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks));
radialMirrorIconButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks));
radialMirrorNumberFieldList
.forEach(numberField -> numberField.drawNumberField(this.mc, mouseX, mouseY, partialTicks));
} else {
buttonRadialMirrorEnabled.y = yy;
fontRenderer.drawString("Radial mirror disabled", left + offset, yy + 2, 0x999999, true);
}
}
public void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY) {
//Draw tooltips last
if (buttonRadialMirrorEnabled.isChecked())
{
radialMirrorIconButtonList.forEach(iconButton -> iconButton.drawTooltip(scrollPane.parent, mouseX, mouseY));
radialMirrorNumberFieldList.forEach(numberField -> numberField.drawTooltip(scrollPane.parent, mouseX, mouseY));
}
}
@Override
public void updatePosition(int slotIndex, int x, int y, float partialTicks) {
super.updatePosition(slotIndex, x, y, partialTicks);
}
@Override
public void keyTyped(char typedChar, int keyCode) throws IOException {
super.keyTyped(typedChar, keyCode);
for (GuiNumberField numberField : radialMirrorNumberFieldList) {
numberField.keyTyped(typedChar, keyCode);
}
}
@Override
public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) {
super.mousePressed(slotIndex, mouseX, mouseY, mouseEvent, relativeX, relativeY);
radialMirrorNumberFieldList.forEach(numberField -> numberField.mouseClicked(mouseX, mouseY, mouseEvent));
boolean insideRadialMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12;
if (insideRadialMirrorEnabledLabel) {
buttonRadialMirrorEnabled.setIsChecked(!buttonRadialMirrorEnabled.isChecked());
buttonRadialMirrorEnabled.playPressSound(this.mc.getSoundHandler());
actionPerformed(buttonRadialMirrorEnabled);
}
return true;
}
@Override
public void actionPerformed(GuiButton button) {
super.actionPerformed(button);
if (button == buttonRadialMirrorEnabled) {
setCollapsed(!buttonRadialMirrorEnabled.isChecked());
}
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);
textRadialMirrorPosX.setNumber(pos.x);
textRadialMirrorPosY.setNumber(pos.y);
textRadialMirrorPosZ.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"));
textRadialMirrorPosX.setNumber(textRadialMirrorPosX.getNumber() + 0.5);
textRadialMirrorPosY.setNumber(textRadialMirrorPosY.getNumber() + 0.5);
textRadialMirrorPosZ.setNumber(textRadialMirrorPosZ.getNumber() + 0.5);
} else {
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds"));
textRadialMirrorPosX.setNumber(Math.floor(textRadialMirrorPosX.getNumber()));
textRadialMirrorPosY.setNumber(Math.floor(textRadialMirrorPosY.getNumber()));
textRadialMirrorPosZ.setNumber(Math.floor(textRadialMirrorPosZ.getNumber()));
}
}
if (button == buttonDrawLines) {
drawLines = !drawLines;
buttonDrawLines.setUseAlternateIcon(drawLines);
buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines");
}
if (button == buttonDrawPlanes) {
drawPlanes = !drawPlanes;
buttonDrawPlanes.setUseAlternateIcon(drawPlanes);
buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area");
}
radialMirrorNumberFieldList.forEach(numberField -> numberField.actionPerformed(button));
}
public RadialMirror.RadialMirrorSettings getRadialMirrorSettings() {
boolean radialMirrorEnabled = buttonRadialMirrorEnabled.isChecked();
Vec3d radialMirrorPos = new Vec3d(0, 64, 0);
try {
radialMirrorPos = new Vec3d(textRadialMirrorPosX.getNumber(), textRadialMirrorPosY.getNumber(), textRadialMirrorPosZ
.getNumber());
} catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(mc.player, "Radial mirror position not a valid number.");
}
int radialMirrorSlices = 4;
try {
radialMirrorSlices = (int) textRadialMirrorSlices.getNumber();
} catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(mc.player, "Radial mirror slices not a valid number.");
}
boolean radialMirrorAlternate = buttonRadialMirrorAlternate.isChecked();
int radialMirrorRadius = 50;
try {
radialMirrorRadius = (int) textRadialMirrorRadius.getNumber();
} catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(mc.player, "Mirror radius not a valid number.");
}
return new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPos, radialMirrorSlices, radialMirrorAlternate, radialMirrorRadius, drawLines, drawPlanes);
}
@Override
protected String getName() {
return "Radial mirror";
}
@Override
protected int getExpandedHeight() {
return 100;
}
}

View File

@@ -4,7 +4,6 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ClickType;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;

View File

@@ -1,7 +1,6 @@
package nl.requios.effortlessbuilding.gui;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
import net.minecraftforge.fml.relauncher.Side;

View File

@@ -2,10 +2,7 @@ package nl.requios.effortlessbuilding.gui;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import nl.requios.effortlessbuilding.Array;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.Mirror;
import nl.requios.effortlessbuilding.*;
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
import nl.requios.effortlessbuilding.proxy.ClientProxy;
@@ -18,6 +15,7 @@ public class SettingsGui extends GuiScreen {
private MirrorSettingsGui mirrorSettingsGui;
private ArraySettingsGui arraySettingsGui;
private RadialMirrorSettingsGui radialMirrorSettingsGui;
@Override
//Create buttons and labels and add them to buttonList/labelList
@@ -32,6 +30,9 @@ public class SettingsGui extends GuiScreen {
arraySettingsGui = new ArraySettingsGui(scrollPane);
scrollPane.listEntries.add(arraySettingsGui);
radialMirrorSettingsGui = new RadialMirrorSettingsGui(scrollPane);
scrollPane.listEntries.add(radialMirrorSettingsGui);
id = scrollPane.initGui(id, buttonList);
//Close button
@@ -110,11 +111,13 @@ public class SettingsGui extends GuiScreen {
//save everything
Mirror.MirrorSettings m = mirrorSettingsGui.getMirrorSettings();
Array.ArraySettings a = arraySettingsGui.getArraySettings();
RadialMirror.RadialMirrorSettings r = radialMirrorSettingsGui.getRadialMirrorSettings();
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(mc.player);
if (buildSettings == null) buildSettings = new BuildSettingsManager.BuildSettings();
buildSettings.setMirrorSettings(m);
buildSettings.setArraySettings(a);
buildSettings.setRadialMirrorSettings(r);
//Sanitize
String error = BuildSettingsManager.sanitize(buildSettings, mc.player);

View File

@@ -0,0 +1,15 @@
package nl.requios.effortlessbuilding.helper;
import com.google.gson.JsonObject;
import net.minecraftforge.common.crafting.IConditionFactory;
import net.minecraftforge.common.crafting.JsonContext;
import nl.requios.effortlessbuilding.BuildConfig;
import java.util.function.BooleanSupplier;
public class ReachConditionFactory implements IConditionFactory {
@Override
public BooleanSupplier parse(JsonContext context, JsonObject json) {
return () -> BuildConfig.reach.enableReachUpgrades;
}
}

View File

@@ -0,0 +1,27 @@
package nl.requios.effortlessbuilding.helper;
import net.minecraft.entity.player.EntityPlayer;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.BuildSettingsManager;
public class ReachHelper {
public static int getMaxReach(EntityPlayer player) {
if (player.isCreative()) return BuildConfig.reach.maxReachCreative;
if (!BuildConfig.reach.enableReachUpgrades) return BuildConfig.reach.maxReachLevel3;
//Check buildsettings for reachUpgrade
int reachUpgrade = BuildSettingsManager.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 boolean canBreakFar(EntityPlayer player) {
return player.isCreative() || BuildConfig.survivalBalancers.breakFar;
}
}

View File

@@ -1,6 +1,5 @@
package nl.requios.effortlessbuilding.helper;
import com.google.common.collect.Maps;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@@ -9,15 +8,12 @@ import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.*;
import net.minecraft.world.IWorldEventListener;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent;
@@ -26,6 +22,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.*;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import nl.requios.effortlessbuilding.proxy.ClientProxy;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.util.Color;
@@ -33,7 +30,6 @@ import org.lwjgl.util.Color;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Mod.EventBusSubscriber(Side.CLIENT)
public class RenderHelper implements IWorldEventListener {
@@ -41,6 +37,7 @@ public class RenderHelper implements IWorldEventListener {
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 Color colorRadial = 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
@@ -127,8 +124,8 @@ public class RenderHelper implements IWorldEventListener {
begin(event.getPartialTicks());
//Mirror lines and areas
beginLines();
//Mirror lines and areas
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
if (m != null && m.enabled && (m.mirrorX || m.mirrorY || m.mirrorZ))
{
@@ -140,7 +137,7 @@ public class RenderHelper implements IWorldEventListener {
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);
drawMirrorPlane(posA, posB, colorX, m.drawLines, m.drawPlanes, true);
}
if (m.mirrorY)
{
@@ -154,7 +151,7 @@ public class RenderHelper implements IWorldEventListener {
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);
drawMirrorPlane(posA, posB, colorZ, m.drawLines, m.drawPlanes, true);
}
//Draw axis coordinated colors if two or more axes are enabled
@@ -164,24 +161,45 @@ public class RenderHelper implements IWorldEventListener {
drawMirrorLines(m);
}
}
//Radial mirror lines and areas
RadialMirror.RadialMirrorSettings r = buildSettings.getRadialMirrorSettings();
if (r != null && r.enabled)
{
Vec3d pos = r.position.add(epsilon);
int radius = r.radius;
float angle = 2f * ((float) Math.PI) / r.slices;
Vec3d relStartVec = new Vec3d(radius, 0, 0);
if (r.slices%4 == 2) relStartVec = relStartVec.rotateYaw(angle / 2f);
for (int i = 0; i < r.slices; i++) {
Vec3d relNewVec = relStartVec.rotateYaw(angle * i);
Vec3d newVec = pos.add(relNewVec);
Vec3d posA = new Vec3d(pos.x, pos.y - radius, pos.z);
Vec3d posB = new Vec3d(newVec.x, pos.y + radius, newVec.z);
drawMirrorPlane(posA, posB, colorRadial, r.drawLines, r.drawPlanes, false);
}
}
endLines();
//Render block previews
RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver;
RayTraceResult lookingAt = ClientProxy.getLookingAt(player);
//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)
if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK)
{
beginBlockPreviews();
BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
BlockPos startPos = objectMouseOver.getBlockPos();
BlockPos startPos = lookingAt.getBlockPos();
//Check if tool (or none) in hand
ItemStack mainhand = player.getHeldItemMainhand();
boolean toolInHand = mainhand.isEmpty() || (!mainhand.isEmpty() && mainhand.getItem() instanceof ItemTool);
boolean toolInHand = !(!mainhand.isEmpty() && (mainhand.getItem() instanceof ItemBlock || mainhand.getItem() instanceof ItemRandomizerBag));
boolean replaceable =
player.world.getBlockState(startPos).getBlock().isReplaceable(player.world, startPos);
if (!buildSettings.doQuickReplace() && !toolInHand && !replaceable) {
startPos = startPos.offset(objectMouseOver.sideHit);
startPos = startPos.offset(lookingAt.sideHit);
}
//Get under tall grass and other replaceable blocks
@@ -189,10 +207,10 @@ public class RenderHelper implements IWorldEventListener {
startPos = startPos.down();
}
//get coordinates
List<BlockPos> newCoordinates = BuildModifiers.findCoordinates(player, startPos);
if (BuildModifiers.isEnabled(buildSettings, startPos) || BuildConfig.visuals.alwaysShowBlockPreview) {
//get coordinates
List<BlockPos> newCoordinates = BuildModifiers.findCoordinates(player, startPos);
//check if they are different from previous
if (!BuildModifiers.compareCoordinates(previousCoordinates, newCoordinates)) {
previousCoordinates = newCoordinates;
@@ -200,11 +218,11 @@ public class RenderHelper implements IWorldEventListener {
ItemRandomizerBag.renewRandomness();
}
Vec3d hitVec = objectMouseOver.hitVec;
Vec3d hitVec = lookingAt.hitVec;
hitVec = new Vec3d(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)),
Math.abs(hitVec.z - ((int) hitVec.z)));
List<ItemStack> itemStacks = new ArrayList<>();
List<IBlockState> blockStates = BuildModifiers.findBlockStates(player, startPos, hitVec, objectMouseOver.sideHit, itemStacks);
List<IBlockState> blockStates = BuildModifiers.findBlockStates(player, startPos, hitVec, lookingAt.sideHit, itemStacks);
//check if valid blockstates
if (blockStates.size() != 0 && newCoordinates.size() == blockStates.size()) {
@@ -214,7 +232,7 @@ public class RenderHelper implements IWorldEventListener {
ItemStack itemstack = itemStacks.get(i);
//Check if can place
if (!itemstack.isEmpty() && SurvivalHelper.canPlayerEdit(player, player.world, blockPos, itemstack) &&
SurvivalHelper.mayPlace(player.world, Block.getBlockFromItem(itemstack.getItem()), blockState, blockPos, true, EnumFacing.UP, player) &&
SurvivalHelper.mayPlace(player.world, Block.getBlockFromItem(itemstack.getItem()), blockState, blockPos, false, EnumFacing.UP, player) &&
SurvivalHelper.canReplace(player.world, player, blockPos)) {
renderBlockPreview(dispatcher, blockPos, blockState);
}
@@ -225,14 +243,22 @@ public class RenderHelper implements IWorldEventListener {
beginLines();
//Draw outlines if tool in hand
if (toolInHand) {
for (int i = 1; i < newCoordinates.size(); i++) {
BlockPos coordinate = newCoordinates.get(i);
//Find proper raytrace: either normal range or increased range depending on canBreakFar
RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver;
RayTraceResult breakingRaytrace = ReachHelper.canBreakFar(player) ? lookingAt : objectMouseOver;
if (toolInHand && breakingRaytrace != null && breakingRaytrace.typeOfHit == RayTraceResult.Type.BLOCK) {
List<BlockPos> breakCoordinates = BuildModifiers.findCoordinates(player, breakingRaytrace.getBlockPos());
//Only render first outline if further than normal reach
boolean excludeFirst = objectMouseOver != null && objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK;
for (int i = excludeFirst ? 1 : 0; i < breakCoordinates.size(); i++) {
BlockPos coordinate = breakCoordinates.get(i);
IBlockState blockState = player.world.getBlockState(coordinate);
if (!blockState.getBlock().isAir(blockState, player.world, coordinate) &&
SurvivalHelper.canBreak(player.world, player, coordinate)) {
renderBlockOutline(coordinate);
if (!blockState.getBlock().isAir(blockState, player.world, coordinate)) {
if (SurvivalHelper.canBreak(player.world, player, coordinate) || i == 0) {
renderBlockOutline(coordinate);
}
}
}
}
@@ -245,7 +271,7 @@ public class RenderHelper implements IWorldEventListener {
//----Mirror----
public static void drawMirrorPlane(Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) {
public static void drawMirrorPlane(Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes, boolean drawVerticalLines) {
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha);
Tessellator tessellator = Tessellator.getInstance();
@@ -268,8 +294,10 @@ public class RenderHelper implements IWorldEventListener {
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();
if (drawVerticalLines) {
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();
}

View File

@@ -13,10 +13,12 @@ import net.minecraft.init.Enchantments;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
@@ -34,7 +36,7 @@ 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) {
public static boolean placeBlock(World world, EntityPlayer player, BlockPos pos, IBlockState blockState, ItemStack itemstack, EnumFacing facing, Vec3d hitVec, boolean skipCollisionCheck, boolean playSound) {
if (!world.isBlockLoaded(pos, true)) return false;
//Randomizer bag synergy
@@ -55,24 +57,26 @@ public class SurvivalHelper {
if (!itemstack.isEmpty() && canPlayerEdit(player, world, pos, itemstack) &&
mayPlace(world, block, blockState, pos, skipCollisionCheck, facing.getOpposite(), player) &&
canReplace(world, player, pos))
{
canReplace(world, player, pos)) {
//Drop existing block
//TODO check if can replace
dropBlock(world, player, pos);
boolean placed = ((ItemBlock) itemstack.getItem()).placeBlockAt(itemstack, player, world, pos, facing, (float) hitVec.x, (float) hitVec.y, (float) hitVec.z, blockState);
if (!placed) return false;
//From ItemBlock#placeBlockAt
if (!world.setBlockState(pos, blockState, 11)) return false;
// 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 (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);
@@ -123,6 +127,12 @@ public class SurvivalHelper {
{
IBlockState state = world.getBlockState(pos);
state = state.getBlock().getActualState(state, world, pos);
//Dont break bedrock
if (state.getBlockHardness((World) world, pos) < 0) {
return false;
}
if (state.getMaterial().isToolNotRequired())
{
return true;
@@ -162,13 +172,16 @@ public class SurvivalHelper {
if (player.isCreative()) return;
IBlockState blockState = world.getBlockState(pos);
Block block = blockState.getBlock();
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);
}
block.harvestBlock(world, player, pos, blockState, world.getTileEntity(pos), player.getHeldItemMainhand());
// 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
@@ -191,9 +204,9 @@ public class SurvivalHelper {
public 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);
AxisAlignedBB axisalignedbb = skipCollisionCheck ? Block.NULL_AABB : blockIn.getDefaultState().getCollisionBoundingBox(world, pos);
if (axisalignedbb != Block.NULL_AABB && !world.checkNoEntityCollision(axisalignedbb.offset(pos), placer))
if (axisalignedbb != Block.NULL_AABB && !world.checkNoEntityCollision(axisalignedbb.offset(pos)))
{
return false;
}

View File

@@ -13,6 +13,7 @@ import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
@@ -36,7 +37,7 @@ public class ItemRandomizerBag extends Item {
public ItemRandomizerBag() {
this.setRegistryName(EffortlessBuilding.MODID, "randomizer_bag");
this.setUnlocalizedName(this.getRegistryName().toString());
this.setTranslationKey(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.TOOLS);
@@ -72,14 +73,8 @@ public class ItemRandomizerBag extends Item {
IBlockState blockState = Block.getBlockFromItem(toPlace.getItem()).getStateForPlacement(world, pos, facing,
hitX, hitY, hitZ, toPlace.getMetadata(), player, hand);
SurvivalHelper.placeBlock(world, player, pos, blockState, toPlace, facing, false, true);
SurvivalHelper.placeBlock(world, player, pos, blockState, toPlace, facing, new Vec3d(hitX, hitY, hitZ), false, true);
//Synergy
//Works without calling
// BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, pos, blockState);
// BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, hand);
// Mirror.onBlockPlaced(placeEvent);
// Array.onBlockPlaced(placeEvent);
}
return EnumActionResult.SUCCESS;
}
@@ -181,8 +176,8 @@ public class ItemRandomizerBag extends Item {
}
@Override
public String getUnlocalizedName() {
return super.getUnlocalizedName();
public String getTranslationKey() {
return super.getTranslationKey();
}
public static void resetRandomness() {

View File

@@ -0,0 +1,73 @@
package nl.requios.effortlessbuilding.item;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import javax.annotation.Nullable;
import java.util.List;
public class ItemReachUpgrade1 extends Item {
public ItemReachUpgrade1() {
this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade1");
this.setTranslationKey(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.TOOLS);
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
if (player.isCreative()) {
if (world.isRemote) EffortlessBuilding.log(player, "Reach upgrades are not necessary in creative.");
if (world.isRemote) EffortlessBuilding.log(player, "Still want increased reach? Use the config.");
return new ActionResult<>(EnumActionResult.PASS, player.getHeldItem(hand));
}
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
int currentLevel = buildSettings.getReachUpgrade();
if (currentLevel == 0) {
buildSettings.setReachUpgrade(1);
if (world.isRemote) EffortlessBuilding.log(player, "Upgraded reach to level " + ReachHelper.getMaxReach(player));
player.setHeldItem(hand, ItemStack.EMPTY);
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("entity.player.levelup"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel > 0) {
if (world.isRemote) EffortlessBuilding.log(player, "Already used this upgrade! Current reach is " + ReachHelper
.getMaxReach(player) + ".");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
}
return new ActionResult<>(EnumActionResult.PASS, player.getHeldItem(hand));
}
@Override
public ItemStack onItemUseFinish(ItemStack stack, World worldIn, EntityLivingBase entityLiving) {
EffortlessBuilding.log("used");
return ItemStack.EMPTY;
}
@Override
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) {
tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel1);
}
@Override
public String getTranslationKey() {
return super.getTranslationKey();
}
}

View File

@@ -0,0 +1,71 @@
package nl.requios.effortlessbuilding.item;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import javax.annotation.Nullable;
import java.util.List;
public class ItemReachUpgrade2 extends Item {
public ItemReachUpgrade2() {
this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade2");
this.setTranslationKey(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.TOOLS);
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
if (player.isCreative()) {
if (world.isRemote) EffortlessBuilding.log(player, "Reach upgrades are not necessary in creative.");
if (world.isRemote) EffortlessBuilding.log(player, "Still want increased reach? Use the config.");
return new ActionResult<>(EnumActionResult.PASS, player.getHeldItem(hand));
}
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
int currentLevel = buildSettings.getReachUpgrade();
if (currentLevel == 1) {
buildSettings.setReachUpgrade(2);
if (world.isRemote) EffortlessBuilding.log(player, "Upgraded reach to level " + ReachHelper.getMaxReach(player));
player.setHeldItem(hand, ItemStack.EMPTY);
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("entity.player.levelup"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel < 1) {
if (world.isRemote) EffortlessBuilding.log(player, "Use Reach Upgrade 1 first.");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel > 1) {
if (world.isRemote) EffortlessBuilding.log(player, "Already used this upgrade! Current reach is " + ReachHelper
.getMaxReach(player) + ".");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
}
return new ActionResult<>(EnumActionResult.PASS, player.getHeldItem(hand));
}
@Override
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) {
tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel2);
tooltip.add(TextFormatting.GRAY + "Previous upgrades need to be consumed first");
}
@Override
public String getTranslationKey() {
return super.getTranslationKey();
}
}

View File

@@ -0,0 +1,74 @@
package nl.requios.effortlessbuilding.item;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import javax.annotation.Nullable;
import java.util.List;
public class ItemReachUpgrade3 extends Item {
public ItemReachUpgrade3() {
this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade3");
this.setTranslationKey(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.TOOLS);
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
if (player.isCreative()) {
if (world.isRemote) EffortlessBuilding.log(player, "Reach upgrades are not necessary in creative.");
if (world.isRemote) EffortlessBuilding.log(player, "Still want increased reach? Use the config.");
return new ActionResult<>(EnumActionResult.PASS, player.getHeldItem(hand));
}
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
int currentLevel = buildSettings.getReachUpgrade();
if (currentLevel == 2) {
buildSettings.setReachUpgrade(3);
if (world.isRemote) EffortlessBuilding.log(player, "Upgraded reach to level " + ReachHelper.getMaxReach(player));
player.setHeldItem(hand, ItemStack.EMPTY);
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("entity.player.levelup"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel < 2) {
if (currentLevel == 0)
if (world.isRemote) EffortlessBuilding.log(player, "Use Reach Upgrade 1 and 2 first.");
if (currentLevel == 1)
if (world.isRemote) EffortlessBuilding.log(player, "Use Reach Upgrade 2 first.");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel > 2) {
if (world.isRemote) EffortlessBuilding.log(player, "Already used this upgrade! Current reach is " + ReachHelper
.getMaxReach(player) + ".");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
}
return new ActionResult<>(EnumActionResult.PASS, player.getHeldItem(hand));
}
@Override
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) {
tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel3);
tooltip.add(TextFormatting.GRAY + "Previous upgrades need to be consumed first");
}
@Override
public String getTranslationKey() {
return super.getTranslationKey();
}
}

View File

@@ -0,0 +1,91 @@
package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.BuildModifiers;
import nl.requios.effortlessbuilding.EffortlessBuilding;
public class BlockBrokenMessage implements IMessage {
private boolean blockHit;
private BlockPos blockPos;
private EnumFacing sideHit;
private Vec3d hitVec;
public BlockBrokenMessage() {
this.blockHit = false;
this.blockPos = BlockPos.ORIGIN;
this.sideHit = EnumFacing.UP;
this.hitVec = new Vec3d(0, 0, 0);
}
public BlockBrokenMessage(RayTraceResult result) {
this.blockHit = result.typeOfHit == RayTraceResult.Type.BLOCK;
this.blockPos = result.getBlockPos();
this.sideHit = result.sideHit;
this.hitVec = result.hitVec;
}
public boolean isBlockHit() {
return blockHit;
}
public BlockPos getBlockPos() {
return blockPos;
}
public EnumFacing getSideHit() {
return sideHit;
}
public Vec3d getHitVec() {
return hitVec;
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeBoolean(blockHit);
buf.writeInt(blockPos.getX());
buf.writeInt(blockPos.getY());
buf.writeInt(blockPos.getZ());
buf.writeInt(sideHit.getIndex());
buf.writeDouble(hitVec.x);
buf.writeDouble(hitVec.y);
buf.writeDouble(hitVec.z);
}
@Override
public void fromBytes(ByteBuf buf) {
blockHit = buf.readBoolean();
blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
sideHit = EnumFacing.byIndex(buf.readInt());
hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
}
// The params of the IMessageHandler are <REQ, REPLY>
public static class MessageHandler implements IMessageHandler<BlockBrokenMessage, IMessage> {
// Do note that the default constructor is required, but implicitly defined in this case
@Override
public IMessage onMessage(BlockBrokenMessage message, MessageContext ctx) {
//EffortlessBuilding.log("message received on " + ctx.side + " side");
if (ctx.side == Side.SERVER) {
//Received serverside
EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> {
BuildModifiers.onBlockBrokenMessage(ctx.getServerHandler().player, message);
});
}
// No response packet
return null;
}
}
}

View File

@@ -66,7 +66,7 @@ public class BlockPlacedMessage implements IMessage {
public void fromBytes(ByteBuf buf) {
blockHit = buf.readBoolean();
blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
sideHit = EnumFacing.getFront(buf.readInt());
sideHit = EnumFacing.byIndex(buf.readInt());
hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
}

View File

@@ -8,11 +8,8 @@ import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import nl.requios.effortlessbuilding.Array;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.*;
import nl.requios.effortlessbuilding.BuildSettingsManager.BuildSettings;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.Mirror;
public class BuildSettingsMessage implements IMessage {
@@ -29,54 +26,96 @@ public class BuildSettingsMessage implements IMessage {
public void toBytes(ByteBuf buf) {
//MIRROR
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
buf.writeBoolean(m.enabled);
buf.writeDouble(m.position.x);
buf.writeDouble(m.position.y);
buf.writeDouble(m.position.z);
buf.writeBoolean(m.mirrorX);
buf.writeBoolean(m.mirrorY);
buf.writeBoolean(m.mirrorZ);
buf.writeInt(m.radius);
buf.writeBoolean(m.drawLines);
buf.writeBoolean(m.drawPlanes);
buf.writeBoolean(m != null);
if (m != null) {
buf.writeBoolean(m.enabled);
buf.writeDouble(m.position.x);
buf.writeDouble(m.position.y);
buf.writeDouble(m.position.z);
buf.writeBoolean(m.mirrorX);
buf.writeBoolean(m.mirrorY);
buf.writeBoolean(m.mirrorZ);
buf.writeInt(m.radius);
buf.writeBoolean(m.drawLines);
buf.writeBoolean(m.drawPlanes);
}
//ARRAY
Array.ArraySettings a = buildSettings.getArraySettings();
buf.writeBoolean(a.enabled);
buf.writeInt(a.offset.getX());
buf.writeInt(a.offset.getY());
buf.writeInt(a.offset.getZ());
buf.writeInt(a.count);
buf.writeBoolean(a != null);
if (a != null) {
buf.writeBoolean(a.enabled);
buf.writeInt(a.offset.getX());
buf.writeInt(a.offset.getY());
buf.writeInt(a.offset.getZ());
buf.writeInt(a.count);
}
buf.writeBoolean(buildSettings.doQuickReplace());
buf.writeInt(buildSettings.getReachUpgrade());
//RADIAL MIRROR
RadialMirror.RadialMirrorSettings r = buildSettings.getRadialMirrorSettings();
buf.writeBoolean(r != null);
if (r != null) {
buf.writeBoolean(r.enabled);
buf.writeDouble(r.position.x);
buf.writeDouble(r.position.y);
buf.writeDouble(r.position.z);
buf.writeInt(r.slices);
buf.writeBoolean(r.alternate);
buf.writeInt(r.radius);
buf.writeBoolean(r.drawLines);
buf.writeBoolean(r.drawPlanes);
}
}
@Override
public void fromBytes(ByteBuf buf) {
//MIRROR
boolean mirrorEnabled = buf.readBoolean();
Vec3d mirrorPosition = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
boolean mirrorX = buf.readBoolean();
boolean mirrorY = buf.readBoolean();
boolean mirrorZ = buf.readBoolean();
int mirrorRadius = buf.readInt();
boolean mirrorDrawLines = buf.readBoolean();
boolean mirrorDrawPlanes = buf.readBoolean();
Mirror.MirrorSettings m = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, mirrorDrawLines, mirrorDrawPlanes);
Mirror.MirrorSettings m = new Mirror.MirrorSettings();
if (buf.readBoolean()) {
boolean mirrorEnabled = buf.readBoolean();
Vec3d mirrorPosition = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
boolean mirrorX = buf.readBoolean();
boolean mirrorY = buf.readBoolean();
boolean mirrorZ = buf.readBoolean();
int mirrorRadius = buf.readInt();
boolean mirrorDrawLines = buf.readBoolean();
boolean mirrorDrawPlanes = buf.readBoolean();
m = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius,
mirrorDrawLines, mirrorDrawPlanes);
}
//ARRAY
boolean arrayEnabled = buf.readBoolean();
BlockPos arrayOffset = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
int arrayCount = buf.readInt();
Array.ArraySettings a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount);
Array.ArraySettings a = new Array.ArraySettings();
if (buf.readBoolean()) {
boolean arrayEnabled = buf.readBoolean();
BlockPos arrayOffset = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
int arrayCount = buf.readInt();
a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount);
}
boolean quickReplace = buf.readBoolean();
int reachUpgrade = buf.readInt();
buildSettings = new BuildSettings(m, a, quickReplace, reachUpgrade);
//RADIAL MIRROR
RadialMirror.RadialMirrorSettings r = new RadialMirror.RadialMirrorSettings();
if (buf.readBoolean()) {
boolean radialMirrorEnabled = buf.readBoolean();
Vec3d radialMirrorPosition = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
int radialMirrorSlices = buf.readInt();
boolean radialMirrorAlternate = buf.readBoolean();
int radialMirrorRadius = buf.readInt();
boolean radialMirrorDrawLines = buf.readBoolean();
boolean radialMirrorDrawPlanes = buf.readBoolean();
r = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition, radialMirrorSlices,
radialMirrorAlternate, radialMirrorRadius, radialMirrorDrawLines, radialMirrorDrawPlanes);
}
buildSettings = new BuildSettings(m, a, r, quickReplace, reachUpgrade);
}
// The params of the IMessageHandler are <REQ, REPLY>
@@ -87,19 +126,18 @@ public class BuildSettingsMessage implements IMessage {
public IMessage onMessage(BuildSettingsMessage message, MessageContext ctx) {
//EffortlessBuilding.log("message received on " + ctx.side + " side");
// This is the player the packet was sent to the server from
EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
// The value that was sent
BuildSettings buildSettings = message.buildSettings;
// Sanitize
BuildSettingsManager.sanitize(buildSettings, player);
// Execute the action on the main server thread by adding it as a scheduled task
IThreadListener threadListener = EffortlessBuilding.proxy.getThreadListenerFromContext(ctx);
threadListener.addScheduledTask(() -> {
EntityPlayer p = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
BuildSettingsManager.setBuildSettings(p, buildSettings);
EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
// Sanitize
BuildSettingsManager.sanitize(buildSettings, player);
BuildSettingsManager.setBuildSettings(player, buildSettings);
});
// No response packet
return null;

View File

@@ -7,46 +7,51 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.IThreadListener;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.IWorldEventListener;
import net.minecraft.world.World;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.*;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.BuildModifiers;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.gui.SettingsGui;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.helper.RenderHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import nl.requios.effortlessbuilding.network.BlockBrokenMessage;
import nl.requios.effortlessbuilding.network.BlockPlacedMessage;
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
import org.lwjgl.input.Keyboard;
import scala.collection.parallel.ParIterableLike;
import javax.annotation.Nullable;
@Mod.EventBusSubscriber(Side.CLIENT)
public class ClientProxy implements IProxy {
public static KeyBinding[] keyBindings;
public static RayTraceResult previousLookAt;
public static RayTraceResult currentLookAt;
private static int breakCooldown = 0;
@Override
public void preInit(FMLPreInitializationEvent event) {
@@ -85,7 +90,7 @@ public class ClientProxy implements IProxy {
@Override
public void serverStarting(FMLServerStartingEvent event) {
// This will never get called on client side
//This will get called clientside
}
@SubscribeEvent
@@ -106,6 +111,66 @@ public class ClientProxy implements IProxy {
}
}
@SubscribeEvent
public static void onMouseInput(InputEvent.MouseInputEvent event) {
Minecraft mc = Minecraft.getMinecraft();
EntityPlayerSP player = mc.player;
if (!BuildModifiers.isEnabled(BuildSettingsManager.getBuildSettings(player), player.getPosition())) return;
if (mc.gameSettings.keyBindUseItem.isPressed()) {
//KeyBinding.setKeyBindState(mc.gameSettings.keyBindUseItem.getKeyCode(), false);
ItemStack currentItemStack = player.getHeldItem(EnumHand.MAIN_HAND);
if (currentItemStack.getItem() instanceof ItemBlock ||
(currentItemStack.getItem() instanceof ItemRandomizerBag && !player.isSneaking())) {
//find position in distance
RayTraceResult lookingAt = getLookingAt(player);
if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK) {
EffortlessBuilding.packetHandler.sendToServer(new BlockPlacedMessage(lookingAt));
//play sound if further than normal
if ((lookingAt.hitVec.subtract(player.getPositionEyes(1f))).lengthSquared() > 25f) {
BlockPos blockPos = lookingAt.getBlockPos();
IBlockState state = player.world.getBlockState(blockPos);
SoundType soundtype = state.getBlock().getSoundType(state, player.world, blockPos, player);
player.world.playSound(player, blockPos, soundtype.getPlaceSound(), SoundCategory.BLOCKS,
(soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F);
player.swingArm(EnumHand.MAIN_HAND);
}
}
}
}
if (mc.gameSettings.keyBindAttack.isKeyDown()) {
//KeyBinding.setKeyBindState(mc.gameSettings.keyBindAttack.getKeyCode(), false);
//Break block in distance in creative (or survival if enabled in config)
if (ReachHelper.canBreakFar(player)) {
if (breakCooldown <= 0) {
breakCooldown = 6;
RayTraceResult lookingAt = getLookingAt(player);
if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK) {
EffortlessBuilding.packetHandler.sendToServer(new BlockBrokenMessage(lookingAt));
//play sound
BlockPos blockPos = lookingAt.getBlockPos();
IBlockState state = player.world.getBlockState(blockPos);
SoundType soundtype = state.getBlock().getSoundType(state, player.world, blockPos, player);
player.world.playSound(player, blockPos, soundtype.getBreakSound(), SoundCategory.BLOCKS,
(soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F);
player.swingArm(EnumHand.MAIN_HAND);
}
} else {
breakCooldown--;
}
}
} else {
breakCooldown = 0;
}
event.setResult(Event.Result.ALLOW);
}
@SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true)
public static void onKeyPress(InputEvent.KeyInputEvent event) {
EntityPlayerSP player = Minecraft.getMinecraft().player;
@@ -114,7 +179,7 @@ public class ClientProxy implements IProxy {
//Show HUD
if (keyBindings[0].isPressed()) {
//Disabled if max reach is 0, might be set in the config that way.
if (BuildSettingsManager.getMaxReach(player) == 0) {
if (ReachHelper.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) {
@@ -147,8 +212,6 @@ public class ClientProxy implements IProxy {
public static void onClientTick(TickEvent.ClientTickEvent event) {
if (event.phase != TickEvent.Phase.START) return;
//TODO increase range using getLookingAt
// Would also need other trigger than onBlockPlaced
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;
@@ -172,12 +235,16 @@ public class ClientProxy implements IProxy {
}
}
private static float rayTraceRange = 32f;
public static RayTraceResult getLookingAt(EntityPlayer player) {
World world = player.world;
Vec3d look = player.getLookVec();
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ);
Vec3d end = new Vec3d(player.posX + look.x * rayTraceRange, player.posY + player.getEyeHeight() + look.y * rayTraceRange, player.posZ + look.z * rayTraceRange);
return world.rayTraceBlocks(start, end, false, false, false);
// World world = player.world;
//base distance off of player ability (config)
float raytraceRange = ReachHelper.getMaxReach(player) / 4f;
// Vec3d look = player.getLookVec();
// Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ);
// Vec3d end = new Vec3d(player.posX + look.x * raytraceRange, player.posY + player.getEyeHeight() + look.y * raytraceRange, player.posZ + look.z * raytraceRange);
return player.rayTrace(raytraceRange, 1f);
// return world.rayTraceBlocks(start, end, false, false, false);
}
}

View File

@@ -30,7 +30,6 @@ public class ServerProxy implements IProxy
@Override
public void serverStarting(FMLServerStartingEvent event)
{
//event.registerServerCommand(new CommandStructureCapture());
}
@Override

View File

@@ -3,4 +3,9 @@ key.effortlessbuilding.hud.desc=Open Settings
key.effortlessbuilding.replace.desc=Toggle QuickReplace
key.effortlessbuilding.creative.desc=Toggle Survival/Creative Mode
item.effortlessbuilding:randomizer_bag.name=Randomizer Bag
item.effortlessbuilding:randomizer_bag.name=Randomizer Bag
item.effortlessbuilding:reach_upgrade1.name=Reach Upgrade 1
item.effortlessbuilding:reach_upgrade2.name=Reach Upgrade 2
item.effortlessbuilding:reach_upgrade3.name=Reach Upgrade 3
commands.reach.usage=/reach <level>

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,5 @@
{
"conditions": {
"enable_reach_upgrades": "nl.requios.effortlessbuilding.helper.ReachConditionFactory"
}
}

View File

@@ -0,0 +1,21 @@
{
"conditions": [{
"type": "effortlessbuilding:enable_reach_upgrades"
}],
"type": "minecraft:crafting_shaped",
"pattern": [
" S",
"/ "
],
"key": {
"S": {
"item": "minecraft:string"
},
"/": {
"item": "minecraft:stick"
}
},
"result": {
"item": "effortlessbuilding:reach_upgrade1"
}
}

View File

@@ -0,0 +1,21 @@
{
"conditions": [{
"type": "effortlessbuilding:enable_reach_upgrades"
}],
"type": "minecraft:crafting_shaped",
"pattern": [
" M",
"/ "
],
"key": {
"M": {
"item": "minecraft:magma_cream"
},
"/": {
"item": "minecraft:bone"
}
},
"result": {
"item": "effortlessbuilding:reach_upgrade2"
}
}

View File

@@ -0,0 +1,25 @@
{
"conditions": [{
"type": "effortlessbuilding:enable_reach_upgrades"
}],
"type": "minecraft:crafting_shaped",
"pattern": [
" FE",
" /F",
"/ "
],
"key": {
"E": {
"item": "minecraft:ender_eye"
},
"F": {
"item": "minecraft:feather"
},
"/": {
"item": "minecraft:blaze_rod"
}
},
"result": {
"item": "effortlessbuilding:reach_upgrade3"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B