Increased range for placing and breaking blocks (breaking at range only in creative).

Added reach upgrade items.
Added reach command (usage: /reach <level>).
This commit is contained in:
Christian Knaapen
2018-12-23 22:15:05 +01:00
parent 13d43a0265
commit 36a698cd95
28 changed files with 616 additions and 57 deletions

View File

@@ -13,7 +13,11 @@ 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")
public int maxReachCreative = 200;
@Comment({"Maximum reach in survival without upgrades",
@@ -32,6 +36,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,13 +9,13 @@ 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.*;
@@ -45,6 +45,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)));
@@ -83,6 +90,15 @@ public class BuildModifiers {
}
//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;

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,7 +41,7 @@ public class BuildSettingsManager {
}
public static String sanitize(BuildSettings buildSettings, EntityPlayer player) {
int maxReach = getMaxReach(player);
int maxReach = ReachHelper.getMaxReach(player);
String error = "";
//Mirror settings
@@ -77,20 +78,6 @@ 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;

View File

@@ -3,10 +3,12 @@ package nl.requios.effortlessbuilding;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager;
import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.SidedProxy;
@@ -18,8 +20,13 @@ 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.command.CommandReach;
import nl.requios.effortlessbuilding.gui.RandomizerBagGuiHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
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.BuildSettingsMessage;
import nl.requios.effortlessbuilding.network.BlockPlacedMessage;
import nl.requios.effortlessbuilding.proxy.IProxy;
@@ -47,12 +54,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 +85,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 +97,7 @@ public class EffortlessBuilding
{
ConfigManager.sync(MODID, Config.Type.INSTANCE);
NetworkRegistry.INSTANCE.registerGuiHandler(EffortlessBuilding.instance, new RandomizerBagGuiHandler());
proxy.init(event);
}
@@ -95,6 +111,7 @@ public class EffortlessBuilding
@EventHandler
public void serverStarting(FMLServerStartingEvent event)
{
event.registerServerCommand(new CommandReach());
proxy.serverStarting(event);
}

View File

@@ -72,7 +72,7 @@ public class EventHandler
@SubscribeEvent
public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
BuildModifiers.onBlockPlaced(event);
//BuildModifiers.onBlockPlaced(event);
}
@SubscribeEvent

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);

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);

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

@@ -9,6 +9,7 @@ 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;
@@ -26,6 +27,8 @@ 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.item.ItemReachUpgrade1;
import nl.requios.effortlessbuilding.proxy.ClientProxy;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.util.Color;
@@ -167,21 +170,21 @@ public class RenderHelper implements IWorldEventListener {
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 +192,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 +203,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()) {
@@ -225,14 +228,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);
}
}
}
}

View File

@@ -0,0 +1,68 @@
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 net.minecraftforge.fml.relauncher.Side;
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.setUnlocalizedName(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.TOOLS);
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand 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 getUnlocalizedName() {
return super.getUnlocalizedName();
}
}

View File

@@ -0,0 +1,65 @@
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.setUnlocalizedName(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.TOOLS);
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand 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 getUnlocalizedName() {
return super.getUnlocalizedName();
}
}

View File

@@ -0,0 +1,68 @@
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.setUnlocalizedName(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.TOOLS);
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand 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 getUnlocalizedName() {
return super.getUnlocalizedName();
}
}

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.getFront(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

@@ -7,18 +7,18 @@ 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;
@@ -26,21 +26,26 @@ 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.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.BuildConfig;
import nl.requios.effortlessbuilding.BuildModifiers;
import nl.requios.effortlessbuilding.BuildSettingsManager;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.command.CommandReach;
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 {
@@ -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,47 @@ 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) {
//find position in distance
RayTraceResult lookingAt = getLookingAt(player);
if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK) {
EffortlessBuilding.packetHandler.sendToServer(new BlockPlacedMessage(lookingAt));
}
}
}
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)) {
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);
}
}
}
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 +160,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 +193,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 +216,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

@@ -8,6 +8,7 @@ import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import nl.requios.effortlessbuilding.command.CommandReach;
public class ServerProxy implements IProxy
{
@@ -30,7 +31,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