Merge branch 'master' of github.com:cabaletta/baritone

This commit is contained in:
Leijurv 2018-08-11 13:08:22 -07:00
commit 6d78b7f083
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
10 changed files with 348 additions and 284 deletions

View File

@ -21,6 +21,7 @@ import baritone.bot.behavior.Behavior;
import baritone.bot.behavior.impl.LookBehavior; import baritone.bot.behavior.impl.LookBehavior;
import baritone.bot.behavior.impl.MemoryBehavior; import baritone.bot.behavior.impl.MemoryBehavior;
import baritone.bot.behavior.impl.PathingBehavior; import baritone.bot.behavior.impl.PathingBehavior;
import baritone.bot.event.GameEventHandler;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -25,9 +25,9 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* This serves as a replacement to the old {@code MovementManager}'s * An interface with the game's control system allowing the ability to
* input overriding capabilities. It is vastly more extensible in the * force down certain controls, having the same effect as if we were actually
* inputs that can be overriden. * physically forcing down the assigned key.
* *
* @author Brady * @author Brady
* @since 7/31/2018 11:20 PM * @since 7/31/2018 11:20 PM

View File

@ -17,7 +17,7 @@
package baritone.bot.behavior; package baritone.bot.behavior;
import baritone.bot.event.AbstractGameEventListener; import baritone.bot.event.listener.AbstractGameEventListener;
import baritone.bot.utils.Helper; import baritone.bot.utils.Helper;
/** /**

View File

@ -63,8 +63,7 @@ public final class CachedChunk implements IBlockTypeAccess {
private final BitSet data; private final BitSet data;
CachedChunk(int x, int z, BitSet data) { CachedChunk(int x, int z, BitSet data) {
if (data.size() > SIZE) validateSize(data);
throw new IllegalArgumentException("BitSet of invalid length provided");
this.x = x; this.x = x;
this.z = z; this.z = z;
@ -78,8 +77,7 @@ public final class CachedChunk implements IBlockTypeAccess {
} }
void updateContents(BitSet data) { void updateContents(BitSet data) {
if (data.size() > SIZE) validateSize(data);
throw new IllegalArgumentException("BitSet of invalid length provided");
for (int i = 0; i < data.length(); i++) for (int i = 0; i < data.length(); i++)
this.data.set(i, data.get(i)); this.data.set(i, data.get(i));
@ -117,4 +115,17 @@ public final class CachedChunk implements IBlockTypeAccess {
public static int getPositionIndex(int x, int y, int z) { public static int getPositionIndex(int x, int y, int z) {
return (x + (z << 4) + (y << 8)) * 2; return (x + (z << 4) + (y << 8)) * 2;
} }
/**
* Validates the size of an input {@link BitSet} containing the raw
* packed chunk data. Sizes that exceed {@link CachedChunk#SIZE} are
* considered invalid, and thus, an exception will be thrown.
*
* @param data The raw data
* @throws IllegalArgumentException if the bitset size exceeds the maximum size
*/
private static void validateSize(BitSet data) {
if (data.size() > SIZE)
throw new IllegalArgumentException("BitSet of invalid length provided");
}
} }

View File

@ -1,169 +1,185 @@
/* /*
* This file is part of Baritone. * This file is part of Baritone.
* *
* Baritone is free software: you can redistribute it and/or modify * Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Baritone is distributed in the hope that it will be useful, * Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>. * along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/ */
package baritone.bot; /*
* This file is part of Baritone.
import baritone.bot.behavior.Behavior; *
import baritone.bot.chunk.CachedWorld; * Baritone is free software: you can redistribute it and/or modify
import baritone.bot.chunk.CachedWorldProvider; * it under the terms of the GNU General Public License as published by
import baritone.bot.chunk.ChunkPacker; * the Free Software Foundation, either version 3 of the License, or
import baritone.bot.event.IGameEventListener; * (at your option) any later version.
import baritone.bot.event.events.*; *
import baritone.bot.event.events.type.EventState; * Baritone is distributed in the hope that it will be useful,
import baritone.bot.utils.Helper; * but WITHOUT ANY WARRANTY; without even the implied warranty of
import net.minecraft.client.renderer.BufferBuilder; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
import net.minecraft.client.renderer.GlStateManager; * GNU General Public License for more details.
import net.minecraft.client.renderer.Tessellator; *
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; * You should have received a copy of the GNU General Public License
import net.minecraft.client.settings.KeyBinding; * along with Baritone. If not, see <https://www.gnu.org/licenses/>.
import org.lwjgl.input.Keyboard; */
import org.lwjgl.opengl.GL11;
package baritone.bot.event;
import java.util.function.Consumer;
import baritone.bot.Baritone;
/** import baritone.bot.InputOverrideHandler;
* @author Brady import baritone.bot.behavior.Behavior;
* @since 7/31/2018 11:04 PM import baritone.bot.chunk.CachedWorld;
*/ import baritone.bot.chunk.CachedWorldProvider;
public final class GameEventHandler implements IGameEventListener, Helper { import baritone.bot.chunk.ChunkPacker;
import baritone.bot.event.listener.IGameEventListener;
GameEventHandler() {} import baritone.bot.event.events.*;
import baritone.bot.event.events.type.EventState;
@Override import baritone.bot.utils.Helper;
public final void onTick(TickEvent event) { import net.minecraft.client.renderer.BufferBuilder;
dispatch(behavior -> behavior.onTick(event)); import net.minecraft.client.renderer.GlStateManager;
} import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@Override import net.minecraft.client.settings.KeyBinding;
public void onPlayerUpdate() { import org.lwjgl.input.Keyboard;
dispatch(Behavior::onPlayerUpdate);
} import java.util.function.Consumer;
@Override /**
public void onProcessKeyBinds() { * @author Brady
InputOverrideHandler inputHandler = Baritone.INSTANCE.getInputOverrideHandler(); * @since 7/31/2018 11:04 PM
*/
// Simulate the key being held down this tick public final class GameEventHandler implements IGameEventListener, Helper {
for (InputOverrideHandler.Input input : InputOverrideHandler.Input.values()) {
KeyBinding keyBinding = input.getKeyBinding(); @Override
public final void onTick(TickEvent event) {
if (inputHandler.isInputForcedDown(keyBinding) && !keyBinding.isKeyDown()) { dispatch(behavior -> behavior.onTick(event));
int keyCode = keyBinding.getKeyCode(); }
if (keyCode < Keyboard.KEYBOARD_SIZE) @Override
KeyBinding.onTick(keyCode < 0 ? keyCode + 100 : keyCode); public void onPlayerUpdate() {
} dispatch(Behavior::onPlayerUpdate);
} }
dispatch(Behavior::onProcessKeyBinds); @Override
} public void onProcessKeyBinds() {
InputOverrideHandler inputHandler = Baritone.INSTANCE.getInputOverrideHandler();
@Override
public void onSendChatMessage(ChatEvent event) { // Simulate the key being held down this tick
dispatch(behavior -> behavior.onSendChatMessage(event)); for (InputOverrideHandler.Input input : InputOverrideHandler.Input.values()) {
} KeyBinding keyBinding = input.getKeyBinding();
@Override if (inputHandler.isInputForcedDown(keyBinding) && !keyBinding.isKeyDown()) {
public void onChunkEvent(ChunkEvent event) { int keyCode = keyBinding.getKeyCode();
EventState state = event.getState();
ChunkEvent.Type type = event.getType(); if (keyCode < Keyboard.KEYBOARD_SIZE)
KeyBinding.onTick(keyCode < 0 ? keyCode + 100 : keyCode);
boolean isPostPopulate = state == EventState.POST }
&& type == ChunkEvent.Type.POPULATE; }
// Whenever the server sends us to another dimension, chunks are unloaded dispatch(Behavior::onProcessKeyBinds);
// technically after the new world has been loaded, so we perform a check }
// to make sure the chunk being unloaded is already loaded.
boolean isPreUnload = state == EventState.PRE @Override
&& type == ChunkEvent.Type.UNLOAD public void onSendChatMessage(ChatEvent event) {
&& mc.world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ()); dispatch(behavior -> behavior.onSendChatMessage(event));
}
if (isPostPopulate || isPreUnload) {
CachedWorldProvider.INSTANCE.ifWorldLoaded(world -> @Override
world.updateCachedChunk(event.getX(), event.getZ(), public void onChunkEvent(ChunkEvent event) {
ChunkPacker.createPackedChunk(mc.world.getChunk(event.getX(), event.getZ())))); EventState state = event.getState();
} ChunkEvent.Type type = event.getType();
dispatch(behavior -> behavior.onChunkEvent(event)); boolean isPostPopulate = state == EventState.POST
} && type == ChunkEvent.Type.POPULATE;
@Override // Whenever the server sends us to another dimension, chunks are unloaded
public void onRenderPass(RenderEvent event) { // technically after the new world has been loaded, so we perform a check
/* // to make sure the chunk being unloaded is already loaded.
CachedWorldProvider.INSTANCE.ifWorldLoaded(world -> world.forEachRegion(region -> region.forEachChunk(chunk -> { boolean isPreUnload = state == EventState.PRE
drawChunkLine(region.getX() * 512 + chunk.getX() * 16, region.getZ() * 512 + chunk.getZ() * 16, event.getPartialTicks()); && type == ChunkEvent.Type.UNLOAD
}))); && mc.world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
*/
if (isPostPopulate || isPreUnload) {
dispatch(behavior -> behavior.onRenderPass(event)); CachedWorldProvider.INSTANCE.ifWorldLoaded(world ->
} world.updateCachedChunk(event.getX(), event.getZ(),
ChunkPacker.createPackedChunk(mc.world.getChunk(event.getX(), event.getZ()))));
@Override }
public void onWorldEvent(WorldEvent event) {
CachedWorldProvider cache = CachedWorldProvider.INSTANCE; dispatch(behavior -> behavior.onChunkEvent(event));
}
switch (event.getState()) {
case PRE: @Override
cache.ifWorldLoaded(CachedWorld::save); public void onRenderPass(RenderEvent event) {
break; /*
case POST: CachedWorldProvider.INSTANCE.ifWorldLoaded(world -> world.forEachRegion(region -> region.forEachChunk(chunk -> {
cache.closeWorld(); drawChunkLine(region.getX() * 512 + chunk.getX() * 16, region.getZ() * 512 + chunk.getZ() * 16, event.getPartialTicks());
if (event.getWorld() != null) })));
cache.initWorld(event.getWorld()); */
break;
} dispatch(behavior -> behavior.onRenderPass(event));
}
dispatch(behavior -> behavior.onWorldEvent(event));
} @Override
public void onWorldEvent(WorldEvent event) {
@Override CachedWorldProvider cache = CachedWorldProvider.INSTANCE;
public void onSendPacket(PacketEvent event) {
dispatch(behavior -> behavior.onSendPacket(event)); switch (event.getState()) {
} case PRE:
cache.ifWorldLoaded(CachedWorld::save);
@Override break;
public void onReceivePacket(PacketEvent event) { case POST:
dispatch(behavior -> behavior.onReceivePacket(event)); cache.closeWorld();
} if (event.getWorld() != null)
cache.initWorld(event.getWorld());
private void dispatch(Consumer<Behavior> dispatchFunction) { break;
Baritone.INSTANCE.getBehaviors().stream().filter(Behavior::isEnabled).forEach(dispatchFunction); }
}
dispatch(behavior -> behavior.onWorldEvent(event));
private void drawChunkLine(int posX, int posZ, float partialTicks) { }
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); @Override
GlStateManager.color(1.0F, 1.0F, 0.0F, 0.4F); public void onSendPacket(PacketEvent event) {
GL11.glLineWidth(2.0F); dispatch(behavior -> behavior.onSendPacket(event));
GlStateManager.disableTexture2D(); }
Tessellator tessellator = Tessellator.getInstance(); @Override
BufferBuilder buffer = tessellator.getBuffer(); public void onReceivePacket(PacketEvent event) {
double d0 = mc.getRenderManager().viewerPosX; dispatch(behavior -> behavior.onReceivePacket(event));
double d1 = mc.getRenderManager().viewerPosY; }
double d2 = mc.getRenderManager().viewerPosZ;
buffer.begin(3, DefaultVertexFormats.POSITION); private void dispatch(Consumer<Behavior> dispatchFunction) {
buffer.pos(posX - d0, 0 - d1, posZ - d2).endVertex(); Baritone.INSTANCE.getBehaviors().stream().filter(Behavior::isEnabled).forEach(dispatchFunction);
buffer.pos(posX - d0, 256 - d1, posZ - d2).endVertex(); }
tessellator.draw();
private void drawChunkLine(int posX, int posZ, float partialTicks) {
GlStateManager.enableDepth(); GlStateManager.enableBlend();
GlStateManager.depthMask(true); GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.enableTexture2D(); GlStateManager.color(1.0F, 1.0F, 0.0F, 0.4F);
GlStateManager.disableBlend(); GlStateManager.glLineWidth(2.0F);
} GlStateManager.disableTexture2D();
}
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
double d0 = mc.getRenderManager().viewerPosX;
double d1 = mc.getRenderManager().viewerPosY;
double d2 = mc.getRenderManager().viewerPosZ;
buffer.begin(3, DefaultVertexFormats.POSITION);
buffer.pos(posX - d0, 0 - d1, posZ - d2).endVertex();
buffer.pos(posX - d0, 256 - d1, posZ - d2).endVertex();
tessellator.draw();
GlStateManager.enableDepth();
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
}
}

View File

@ -15,7 +15,24 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>. * along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/ */
package baritone.bot.event; /*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot.event.listener;
import baritone.bot.event.events.*; import baritone.bot.event.events.*;

View File

@ -1,99 +1,116 @@
/* /*
* This file is part of Baritone. * This file is part of Baritone.
* *
* Baritone is free software: you can redistribute it and/or modify * Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Baritone is distributed in the hope that it will be useful, * Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>. * along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/ */
package baritone.bot.event; /*
* This file is part of Baritone.
import baritone.bot.event.events.*; *
import io.netty.util.concurrent.GenericFutureListener; * Baritone is free software: you can redistribute it and/or modify
import net.minecraft.client.Minecraft; * it under the terms of the GNU General Public License as published by
import net.minecraft.client.entity.EntityPlayerSP; * the Free Software Foundation, either version 3 of the License, or
import net.minecraft.client.multiplayer.WorldClient; * (at your option) any later version.
import net.minecraft.client.renderer.EntityRenderer; *
import net.minecraft.client.settings.GameSettings; * Baritone is distributed in the hope that it will be useful,
import net.minecraft.network.NetworkManager; * but WITHOUT ANY WARRANTY; without even the implied warranty of
import net.minecraft.network.Packet; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
/** *
* @author Brady * You should have received a copy of the GNU General Public License
* @since 7/31/2018 11:05 PM * along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/ */
public interface IGameEventListener {
package baritone.bot.event.listener;
/**
* Run once per game tick before screen input is handled. import baritone.bot.event.events.*;
* import io.netty.util.concurrent.GenericFutureListener;
* @see Minecraft#runTick() import net.minecraft.client.Minecraft;
*/ import net.minecraft.client.entity.EntityPlayerSP;
void onTick(TickEvent event); import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.EntityRenderer;
/** import net.minecraft.client.settings.GameSettings;
* Run once per game tick from before the player rotation is sent to the server. import net.minecraft.network.NetworkManager;
* @see EntityPlayerSP#onUpdate() import net.minecraft.network.Packet;
*/
void onPlayerUpdate(); /**
* @author Brady
/** * @since 7/31/2018 11:05 PM
* Run once per game tick from before keybinds are processed. */
* public interface IGameEventListener {
* @see Minecraft#processKeyBinds()
*/ /**
void onProcessKeyBinds(); * Run once per game tick before screen input is handled.
*
/** * @see Minecraft#runTick()
* Runs whenever the client player sends a message to the server. */
* void onTick(TickEvent event);
* @see EntityPlayerSP#sendChatMessage(String)
*/ /**
void onSendChatMessage(ChatEvent event); * Run once per game tick from before the player rotation is sent to the server.
* @see EntityPlayerSP#onUpdate()
/** */
* Runs before and after whenever a chunk is either loaded, unloaded, or populated. void onPlayerUpdate();
*
* @see WorldClient#doPreChunk(int, int, boolean) /**
*/ * Run once per game tick from before keybinds are processed.
void onChunkEvent(ChunkEvent event); *
* @see Minecraft#processKeyBinds()
/** */
* Runs once per world render pass. Two passes are made when {@link GameSettings#anaglyph} is on. void onProcessKeyBinds();
* <p>
* <b>Note:</b> {@link GameSettings#anaglyph} has been removed in Minecraft 1.13 /**
* * Runs whenever the client player sends a message to the server.
* @see EntityRenderer#renderWorldPass(int, float, long) *
*/ * @see EntityPlayerSP#sendChatMessage(String)
void onRenderPass(RenderEvent event); */
void onSendChatMessage(ChatEvent event);
/**
* Runs before and after whenever a new world is loaded /**
* * Runs before and after whenever a chunk is either loaded, unloaded, or populated.
* @see Minecraft#loadWorld(WorldClient, String) *
*/ * @see WorldClient#doPreChunk(int, int, boolean)
void onWorldEvent(WorldEvent event); */
void onChunkEvent(ChunkEvent event);
/**
* Runs before a outbound packet is sent /**
* * Runs once per world render pass. Two passes are made when {@link GameSettings#anaglyph} is on.
* @see NetworkManager#dispatchPacket(Packet, GenericFutureListener[]) * <p>
*/ * <b>Note:</b> {@link GameSettings#anaglyph} has been removed in Minecraft 1.13
void onSendPacket(PacketEvent event); *
* @see EntityRenderer#renderWorldPass(int, float, long)
/** */
* Runs before an inbound packet is processed void onRenderPass(RenderEvent event);
*
* @see NetworkManager#dispatchPacket(Packet, GenericFutureListener[]) /**
*/ * Runs before and after whenever a new world is loaded
void onReceivePacket(PacketEvent event); *
} * @see Minecraft#loadWorld(WorldClient, String)
*/
void onWorldEvent(WorldEvent event);
/**
* Runs before a outbound packet is sent
*
* @see NetworkManager#dispatchPacket(Packet, GenericFutureListener[])
*/
void onSendPacket(PacketEvent event);
/**
* Runs before an inbound packet is processed
*
* @see NetworkManager#dispatchPacket(Packet, GenericFutureListener[])
*/
void onReceivePacket(PacketEvent event);
}

View File

@ -19,6 +19,7 @@ package baritone.bot.pathing.movement;
import baritone.bot.utils.Helper; import baritone.bot.utils.Helper;
import baritone.bot.utils.ToolSet; import baritone.bot.utils.ToolSet;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Items; import net.minecraft.init.Items;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -28,6 +29,8 @@ import net.minecraft.item.ItemStack;
*/ */
public class CalculationContext implements Helper { public class CalculationContext implements Helper {
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
private final ToolSet toolSet; private final ToolSet toolSet;
private final boolean hasWaterBucket; private final boolean hasWaterBucket;
@ -37,7 +40,7 @@ public class CalculationContext implements Helper {
public CalculationContext(ToolSet toolSet) { public CalculationContext(ToolSet toolSet) {
this.toolSet = toolSet; this.toolSet = toolSet;
this.hasWaterBucket = player().inventory.hasItemStack(new ItemStack(Items.WATER_BUCKET)); // TODO check if water bucket is on hotbar or main inventory this.hasWaterBucket = InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER));
} }
public ToolSet getToolSet() { public ToolSet getToolSet() {

View File

@ -35,7 +35,7 @@ import java.util.Optional;
public class MovementFall extends Movement { public class MovementFall extends Movement {
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET); private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
private static final ItemStack STACK_BUCKET_AIR = new ItemStack(Items.BUCKET); private static final ItemStack STACK_BUCKET_EMPTY = new ItemStack(Items.BUCKET);
public MovementFall(BlockPos src, BlockPos dest) { public MovementFall(BlockPos src, BlockPos dest) {
super(src, dest, MovementFall.buildPositionsToBreak(src, dest), new BlockPos[]{dest.down()}); super(src, dest, MovementFall.buildPositionsToBreak(src, dest), new BlockPos[]{dest.down()});
@ -89,8 +89,8 @@ public class MovementFall extends Movement {
} }
if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.01 if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.01
|| BlockStateInterface.isWater(dest))) { || BlockStateInterface.isWater(dest))) {
if (BlockStateInterface.isWater(dest) && player().inventory.hasItemStack(STACK_BUCKET_AIR)) { if (BlockStateInterface.isWater(dest) && player().inventory.hasItemStack(STACK_BUCKET_EMPTY)) {
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_AIR); player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
if (player().motionY >= 0) { if (player().motionY >= 0) {
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true); return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
} else { } else {

View File

@ -29,7 +29,6 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import org.lwjgl.opengl.GL11;
import java.awt.*; import java.awt.*;
import java.util.Collection; import java.util.Collection;
@ -52,7 +51,7 @@ public final class PathRenderer implements Helper {
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F); GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
GL11.glLineWidth(3.0F); GlStateManager.glLineWidth(3.0F);
GlStateManager.disableTexture2D(); GlStateManager.disableTexture2D();
GlStateManager.depthMask(false); GlStateManager.depthMask(false);
List<BlockPos> positions = path.positions(); List<BlockPos> positions = path.positions();
@ -99,7 +98,7 @@ public final class PathRenderer implements Helper {
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F); GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
GL11.glLineWidth(5.0F); GlStateManager.glLineWidth(5.0F);
GlStateManager.disableTexture2D(); GlStateManager.disableTexture2D();
GlStateManager.depthMask(false); GlStateManager.depthMask(false);
float expand = 0.002F; float expand = 0.002F;