Skip to content

Commit ca3286a

Browse files
authored
Fix and improve copy keybind (#355)
* add copyFromPlayer shorthand * fix copyFromPos issue * fix attempting to copy jei incorrectly * check if screen is focused for valid * extract immutable list * the humble spotless apply * allow running on servers * scratch that and set stack directly
1 parent a95a041 commit ca3286a

File tree

4 files changed

+64
-50
lines changed

4 files changed

+64
-50
lines changed

src/main/java/com/cleanroommc/groovyscript/api/infocommand/InfoParserPackage.java

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
package com.cleanroommc.groovyscript.api.infocommand;
22

33
import com.cleanroommc.groovyscript.event.GsHandEvent;
4+
import com.cleanroommc.groovyscript.helper.RayTracingHelper;
45
import net.minecraft.block.Block;
56
import net.minecraft.block.state.IBlockState;
6-
import net.minecraft.client.Minecraft;
77
import net.minecraft.entity.Entity;
88
import net.minecraft.entity.player.EntityPlayer;
99
import net.minecraft.item.ItemBlock;
1010
import net.minecraft.item.ItemStack;
1111
import net.minecraft.server.MinecraftServer;
1212
import net.minecraft.tileentity.TileEntity;
13+
import net.minecraft.util.EnumHand;
1314
import net.minecraft.util.math.BlockPos;
15+
import net.minecraft.util.math.RayTraceResult;
1416
import net.minecraft.util.text.ITextComponent;
1517
import net.minecraftforge.common.MinecraftForge;
1618
import org.jetbrains.annotations.NotNull;
@@ -156,15 +158,36 @@ public void setTileEntity(@Nullable TileEntity tileEntity) {
156158
this.tileEntity = tileEntity;
157159
}
158160

159-
public void copyFromPos(BlockPos pos) {
160-
if (pos == null) return;
161-
this.pos = pos;
161+
public void copyFromPlayer(@NotNull EntityPlayer player) {
162+
// mainhand -> offhand -> entity being looked at -> block being looked at -> self
163+
var stack = player.getHeldItem(EnumHand.MAIN_HAND);
164+
if (stack.isEmpty()) stack = player.getHeldItem(EnumHand.OFF_HAND);
165+
if (stack.isEmpty()) {
166+
var entity = RayTracingHelper.getEntityLookingAt(player);
167+
if (entity == null) {
168+
var rayTrace = RayTracingHelper.getBlockLookingAt(player);
169+
if (rayTrace == null) {
170+
setEntity(player);
171+
} else {
172+
copyFromPos(rayTrace);
173+
}
174+
} else {
175+
setEntity(entity);
176+
}
177+
} else {
178+
setStack(stack);
179+
}
180+
}
181+
182+
public void copyFromPos(RayTraceResult rayTrace) {
183+
if (rayTrace == null) return;
184+
this.pos = rayTrace.getBlockPos();
162185
this.blockState = player.world.getBlockState(pos);
163186
this.block = blockState.getBlock();
164187
this.tileEntity = player.world.getTileEntity(pos);
165188

166-
this.stack = block.getPickBlock(blockState, Minecraft.getMinecraft().objectMouseOver, player.world, pos, player);
167-
if (this.stack.isEmpty()) this.stack = new ItemStack(block, 1, block.getMetaFromState(blockState));
189+
stack = block.getPickBlock(blockState, rayTrace, player.world, pos, player);
190+
if (stack.isEmpty()) stack = new ItemStack(block, 1, block.getMetaFromState(blockState));
168191
}
169192

170193
public void parse() {
Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package com.cleanroommc.groovyscript.command;
22

33
import com.cleanroommc.groovyscript.api.infocommand.InfoParserPackage;
4-
import com.cleanroommc.groovyscript.helper.RayTracingHelper;
54
import net.minecraft.entity.player.EntityPlayer;
6-
import net.minecraft.util.EnumHand;
75
import org.jetbrains.annotations.NotNull;
86

97
public class InfoInfoCommand extends BaseInfoCommand {
@@ -20,19 +18,6 @@ protected String targetDescription() {
2018

2119
@Override
2220
void gatherInfo(InfoParserPackage info, EntityPlayer player) {
23-
info.setStack(player.getHeldItem(EnumHand.MAIN_HAND));
24-
if (info.getStack().isEmpty()) info.setStack(player.getHeldItem(EnumHand.OFF_HAND));
25-
26-
// if there's nothing in the player's hands, get the entity being looked at and then the block position
27-
// because entity should be preferred
28-
if (info.getStack().isEmpty()) {
29-
info.setEntity(RayTracingHelper.getEntityLookingAt(player));
30-
if (info.getEntity() == null) {
31-
info.copyFromPos(RayTracingHelper.getBlockLookingAt(player));
32-
if (info.getPos() == null) {
33-
info.setEntity(player);
34-
}
35-
}
36-
}
21+
info.copyFromPlayer(player);
3722
}
3823
}

src/main/java/com/cleanroommc/groovyscript/helper/RayTracingHelper.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import net.minecraft.entity.player.EntityPlayer;
66
import net.minecraft.util.EntitySelectors;
77
import net.minecraft.util.math.AxisAlignedBB;
8-
import net.minecraft.util.math.BlockPos;
98
import net.minecraft.util.math.RayTraceResult;
109
import net.minecraft.util.math.Vec3d;
1110

@@ -16,15 +15,15 @@ public class RayTracingHelper {
1615
/**
1716
* gets the block being looked at, stopping on fluid blocks
1817
*/
19-
public static BlockPos getBlockLookingAt(EntityPlayer player) {
18+
public static RayTraceResult getBlockLookingAt(EntityPlayer player) {
2019
double distance = player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue();
2120
Vec3d eyes = player.getPositionEyes(0.0F);
2221
Vec3d look = player.getLook(0.0F);
2322
Vec3d end = eyes.add(look.x * distance, look.y * distance, look.z * distance);
2423

2524
RayTraceResult result = player.getEntityWorld().rayTraceBlocks(eyes, end, true);
2625
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
27-
return result.getBlockPos();
26+
return result;
2827
}
2928
return null;
3029
}

src/main/java/com/cleanroommc/groovyscript/keybinds/CopyKey.java

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
import com.cleanroommc.groovyscript.api.infocommand.InfoParserPackage;
44
import com.cleanroommc.groovyscript.compat.mods.ModSupport;
55
import com.cleanroommc.groovyscript.compat.mods.jei.JeiPlugin;
6-
import com.cleanroommc.groovyscript.helper.RayTracingHelper;
76
import com.cleanroommc.groovyscript.helper.StyleConstant;
87
import com.google.common.collect.ImmutableList;
98
import mezz.jei.api.IRecipesGui;
109
import net.minecraft.client.Minecraft;
1110
import net.minecraft.client.gui.inventory.GuiContainer;
1211
import net.minecraft.entity.player.EntityPlayer;
1312
import net.minecraft.item.ItemStack;
14-
import net.minecraft.util.EnumHand;
1513
import net.minecraft.util.text.ITextComponent;
1614
import net.minecraft.util.text.TextComponentString;
1715
import net.minecraftforge.client.settings.KeyModifier;
@@ -23,6 +21,7 @@
2321
public class CopyKey extends GroovyScriptKeybinds.Key {
2422

2523
private static final Minecraft mc = Minecraft.getMinecraft();
24+
private static final List<String> ARGS = ImmutableList.of("all");
2625

2726
public CopyKey() {
2827
super("copy", KeyModifier.CONTROL, Keyboard.KEY_C);
@@ -34,22 +33,21 @@ public static CopyKey createKeybind() {
3433

3534
private static void gatherInfo(InfoParserPackage info, EntityPlayer player) {
3635
if (mc.inGameHasFocus) {
37-
info.setStack(player.getHeldItem(EnumHand.MAIN_HAND));
38-
if (info.getStack().isEmpty()) info.setStack(player.getHeldItem(EnumHand.OFF_HAND));
39-
if (info.getStack().isEmpty()) {
40-
info.setEntity(RayTracingHelper.getEntityLookingAt(player));
41-
if (info.getEntity() == null) {
42-
info.copyFromPos(RayTracingHelper.getBlockLookingAt(player));
43-
if (info.getPos() == null) {
44-
info.setEntity(player);
45-
}
46-
}
47-
}
36+
info.copyFromPlayer(player);
4837
} else {
49-
if (mc.currentScreen instanceof GuiContainer container && container.hoveredSlot != null) {
50-
info.setStack(container.hoveredSlot.getStack());
38+
var jei = ModSupport.JEI.isLoaded();
39+
if (mc.currentScreen instanceof GuiContainer container) {
40+
var slot = container.getSlotUnderMouse();
41+
if (slot != null) {
42+
info.setStack(slot.getStack());
43+
} else if (jei && info.getStack().isEmpty()) {
44+
// check sidebars of normal guis
45+
info.setStack(getJeiStack());
46+
}
47+
} else if (jei && getJeiRecipesObject() != null) {
48+
// have to check this separately for if IRecipesGui is open, since its GuiScreen not GuiContainer
49+
info.setStack(getJeiStack());
5150
}
52-
if (info.getStack().isEmpty() && ModSupport.JEI.isLoaded()) info.setStack(getJeiStack());
5351
}
5452
}
5553

@@ -61,15 +59,20 @@ private static ItemStack getJeiStack() {
6159
}
6260

6361
private static Object getJeiObject() {
64-
if (mc.currentScreen instanceof IRecipesGui gui) {
65-
var entry = gui.getIngredientUnderMouse();
66-
if (entry != null) return entry;
67-
}
68-
var entry = JeiPlugin.jeiRuntime.getBookmarkOverlay().getIngredientUnderMouse();
62+
var entry = getJeiRecipesObject();
63+
if (entry != null) return entry;
64+
entry = JeiPlugin.jeiRuntime.getBookmarkOverlay().getIngredientUnderMouse();
6965
if (entry != null) return entry;
7066
return JeiPlugin.jeiRuntime.getIngredientListOverlay().getIngredientUnderMouse();
7167
}
7268

69+
private static Object getJeiRecipesObject() {
70+
if (mc.currentScreen instanceof IRecipesGui gui) {
71+
return gui.getIngredientUnderMouse();
72+
}
73+
return null;
74+
}
75+
7376
private static void print(EntityPlayer player, List<ITextComponent> messages) {
7477
if (messages.isEmpty()) {
7578
player.sendMessage(new TextComponentString("Couldn't find anything being focused!").setStyle(StyleConstant.getErrorStyle()));
@@ -80,18 +83,22 @@ private static void print(EntityPlayer player, List<ITextComponent> messages) {
8083
}
8184
}
8285

86+
public static boolean isCapturingKeyboard() {
87+
return mc.currentScreen != null && mc.currentScreen.isFocused();
88+
}
89+
8390
@Override
8491
public boolean isValid() {
85-
return mc.isIntegratedServerRunning();
92+
return mc.player != null && !isCapturingKeyboard();
8693
}
8794

88-
// only runs if isIntegratedServerRunning() is true, so getIntegratedServer() cannot be null
89-
@SuppressWarnings("DataFlowIssue")
9095
@Override
9196
public void runOperation() {
9297
var player = mc.player;
9398
List<ITextComponent> messages = new ArrayList<>();
94-
InfoParserPackage info = new InfoParserPackage(mc.getIntegratedServer(), player, ImmutableList.of("all"), messages, false);
99+
var server = mc.isIntegratedServerRunning() ? mc.getIntegratedServer() : player.getServer();
100+
if (server == null) return; // unsure how this would happen, should be mutually exclusive
101+
InfoParserPackage info = new InfoParserPackage(server, player, ARGS, messages, false);
95102
gatherInfo(info, player);
96103
info.parse(true);
97104
print(player, messages);

0 commit comments

Comments
 (0)