MouseHandler.java
net.minecraft.client.MouseHandler
信息
- 全限定名:net.minecraft.client.MouseHandler
- 类型:public class
- 包:net.minecraft.client
- 源码路径:src/main/java/net/minecraft/client/MouseHandler.java
- 起始行号:L35
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L36 - 说明:
TODO
- 类型:
-
DOUBLE_CLICK_THRESHOLD_MS- 类型:
long - 修饰符:
public static final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
minecraft- 类型:
Minecraft - 修饰符:
private final - 源码定位:
L38 - 说明:
TODO
- 类型:
-
isLeftPressed- 类型:
boolean - 修饰符:
private - 源码定位:
L39 - 说明:
TODO
- 类型:
-
isMiddlePressed- 类型:
boolean - 修饰符:
private - 源码定位:
L40 - 说明:
TODO
- 类型:
-
isRightPressed- 类型:
boolean - 修饰符:
private - 源码定位:
L41 - 说明:
TODO
- 类型:
-
xpos- 类型:
double - 修饰符:
private - 源码定位:
L42 - 说明:
TODO
- 类型:
-
ypos- 类型:
double - 修饰符:
private - 源码定位:
L43 - 说明:
TODO
- 类型:
-
lastClick- 类型:
MouseHandler.LastClick - 修饰符:
private - 源码定位:
L44 - 说明:
TODO
- 类型:
-
lastClickButton- 类型:
int - 修饰符:
protected - 源码定位:
L45 - 说明:
TODO
- 类型:
-
fakeRightMouse- 类型:
int - 修饰符:
private - 源码定位:
L47 - 说明:
TODO
- 类型:
-
activeButton- 类型:
MouseButtonInfo - 修饰符:
private - 源码定位:
L48 - 说明:
TODO
- 类型:
-
ignoreFirstMove- 类型:
boolean - 修饰符:
private - 源码定位:
L49 - 说明:
TODO
- 类型:
-
clickDepth- 类型:
int - 修饰符:
private - 源码定位:
L50 - 说明:
TODO
- 类型:
-
mousePressedTime- 类型:
double - 修饰符:
private - 源码定位:
L51 - 说明:
TODO
- 类型:
-
smoothTurnX- 类型:
SmoothDouble - 修饰符:
private final - 源码定位:
L52 - 说明:
TODO
- 类型:
-
smoothTurnY- 类型:
SmoothDouble - 修饰符:
private final - 源码定位:
L53 - 说明:
TODO
- 类型:
-
accumulatedDX- 类型:
double - 修饰符:
private - 源码定位:
L54 - 说明:
TODO
- 类型:
-
accumulatedDY- 类型:
double - 修饰符:
private - 源码定位:
L55 - 说明:
TODO
- 类型:
-
scrollWheelHandler- 类型:
ScrollWheelHandler - 修饰符:
private final - 源码定位:
L56 - 说明:
TODO
- 类型:
-
lastHandleMovementTime- 类型:
double - 修饰符:
private - 源码定位:
L57 - 说明:
TODO
- 类型:
-
mouseGrabbed- 类型:
boolean - 修饰符:
private - 源码定位:
L58 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.client.MouseHandler.LastClick- 类型:
record - 修饰符:
private - 源码定位:
L455 - 说明:
TODO
- 类型:
构造器
public MouseHandler(Minecraft minecraft) @ L60
- 构造器名:MouseHandler
- 源码定位:L60
- 修饰符:public
参数:
- minecraft: Minecraft
说明:
TODO
方法
下面的方法块按源码顺序生成。
private void onButton(long handle, MouseButtonInfo rawButtonInfo, int action) @ L65
- 方法名:onButton
- 源码定位:L65
- 返回类型:void
- 修饰符:private
参数:
- handle: long
- rawButtonInfo: MouseButtonInfo
- action: int
说明:
TODO
private MouseButtonInfo simulateRightClick(MouseButtonInfo info, boolean pressed) @ L157
- 方法名:simulateRightClick
- 源码定位:L157
- 返回类型:MouseButtonInfo
- 修饰符:private
参数:
- info: MouseButtonInfo
- pressed: boolean
说明:
TODO
public void fillMousePositionDetails(CrashReportCategory category, Window window) @ L173
- 方法名:fillMousePositionDetails
- 源码定位:L173
- 返回类型:void
- 修饰符:public
参数:
- category: CrashReportCategory
- window: Window
说明:
TODO
private void onScroll(long handle, double xoffset, double yoffset) @ L194
- 方法名:onScroll
- 源码定位:L194
- 返回类型:void
- 修饰符:private
参数:
- handle: long
- xoffset: double
- yoffset: double
说明:
TODO
private void onDrop(long handle, List<Path> files, int failedCount) @ L232
- 方法名:onDrop
- 源码定位:L232
- 返回类型:void
- 修饰符:private
参数:
- handle: long
- files: List
- failedCount: int
说明:
TODO
public void setup(Window window) @ L243
- 方法名:setup
- 源码定位:L243
- 返回类型:void
- 修饰符:public
参数:
- window: Window
说明:
TODO
private void onMove(long handle, double xpos, double ypos) @ L271
- 方法名:onMove
- 源码定位:L271
- 返回类型:void
- 修饰符:private
参数:
- handle: long
- xpos: double
- ypos: double
说明:
TODO
public void handleAccumulatedMovement() @ L289
- 方法名:handleAccumulatedMovement
- 源码定位:L289
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public static double getScaledXPos(Window window, double x) @ L342
- 方法名:getScaledXPos
- 源码定位:L342
- 返回类型:double
- 修饰符:public static
参数:
- window: Window
- x: double
说明:
TODO
public double getScaledXPos(Window window) @ L346
- 方法名:getScaledXPos
- 源码定位:L346
- 返回类型:double
- 修饰符:public
参数:
- window: Window
说明:
TODO
public static double getScaledYPos(Window window, double y) @ L350
- 方法名:getScaledYPos
- 源码定位:L350
- 返回类型:double
- 修饰符:public static
参数:
- window: Window
- y: double
说明:
TODO
public double getScaledYPos(Window window) @ L354
- 方法名:getScaledYPos
- 源码定位:L354
- 返回类型:double
- 修饰符:public
参数:
- window: Window
说明:
TODO
private void turnPlayer(double mousea) @ L358
- 方法名:turnPlayer
- 源码定位:L358
- 返回类型:void
- 修饰符:private
参数:
- mousea: double
说明:
TODO
public boolean isLeftPressed() @ L387
- 方法名:isLeftPressed
- 源码定位:L387
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isMiddlePressed() @ L391
- 方法名:isMiddlePressed
- 源码定位:L391
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isRightPressed() @ L395
- 方法名:isRightPressed
- 源码定位:L395
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public double xpos() @ L399
- 方法名:xpos
- 源码定位:L399
- 返回类型:double
- 修饰符:public
参数:
- 无
说明:
TODO
public double ypos() @ L403
- 方法名:ypos
- 源码定位:L403
- 返回类型:double
- 修饰符:public
参数:
- 无
说明:
TODO
public void setIgnoreFirstMove() @ L407
- 方法名:setIgnoreFirstMove
- 源码定位:L407
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isMouseGrabbed() @ L411
- 方法名:isMouseGrabbed
- 源码定位:L411
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void grabMouse() @ L415
- 方法名:grabMouse
- 源码定位:L415
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void releaseMouse() @ L433
- 方法名:releaseMouse
- 源码定位:L433
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void cursorEntered() @ L442
- 方法名:cursorEntered
- 源码定位:L442
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void drawDebugMouseInfo(Font font, GuiGraphicsExtractor graphics) @ L446
- 方法名:drawDebugMouseInfo
- 源码定位:L446
- 返回类型:void
- 修饰符:public
参数:
- font: Font
- graphics: GuiGraphicsExtractor
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class MouseHandler {
private static final Logger LOGGER = LogUtils.getLogger();
public static final long DOUBLE_CLICK_THRESHOLD_MS = 250L;
private final Minecraft minecraft;
private boolean isLeftPressed;
private boolean isMiddlePressed;
private boolean isRightPressed;
private double xpos;
private double ypos;
private MouseHandler.@Nullable LastClick lastClick;
@MouseButtonInfo.MouseButton
protected int lastClickButton;
private int fakeRightMouse;
private @Nullable MouseButtonInfo activeButton = null;
private boolean ignoreFirstMove = true;
private int clickDepth;
private double mousePressedTime;
private final SmoothDouble smoothTurnX = new SmoothDouble();
private final SmoothDouble smoothTurnY = new SmoothDouble();
private double accumulatedDX;
private double accumulatedDY;
private final ScrollWheelHandler scrollWheelHandler;
private double lastHandleMovementTime = Double.MIN_VALUE;
private boolean mouseGrabbed;
public MouseHandler(Minecraft minecraft) {
this.minecraft = minecraft;
this.scrollWheelHandler = new ScrollWheelHandler();
}
private void onButton(long handle, MouseButtonInfo rawButtonInfo, @MouseButtonInfo.Action int action) {
Window window = this.minecraft.getWindow();
if (handle == window.handle()) {
this.minecraft.getFramerateLimitTracker().onInputReceived();
if (this.minecraft.screen != null) {
this.minecraft.setLastInputType(InputType.MOUSE);
}
boolean pressed = action == 1;
MouseButtonInfo buttonInfo = this.simulateRightClick(rawButtonInfo, pressed);
if (pressed) {
if (this.minecraft.options.touchscreen().get() && this.clickDepth++ > 0) {
return;
}
this.activeButton = buttonInfo;
this.mousePressedTime = Blaze3D.getTime();
} else if (this.activeButton != null) {
if (this.minecraft.options.touchscreen().get() && --this.clickDepth > 0) {
return;
}
this.activeButton = null;
}
if (this.minecraft.getOverlay() == null) {
if (this.minecraft.screen == null) {
if (!this.mouseGrabbed && pressed) {
this.grabMouse();
}
} else {
double xm = this.getScaledXPos(window);
double ym = this.getScaledYPos(window);
Screen screen = this.minecraft.screen;
MouseButtonEvent event = new MouseButtonEvent(xm, ym, buttonInfo);
if (pressed) {
screen.afterMouseAction();
try {
long currentTime = Util.getMillis();
boolean doubleClick = this.lastClick != null
&& currentTime - this.lastClick.time() < 250L
&& this.lastClick.screen() == screen
&& this.lastClickButton == event.button();
if (screen.mouseClicked(event, doubleClick)) {
this.lastClick = new MouseHandler.LastClick(currentTime, screen);
this.lastClickButton = buttonInfo.button();
return;
}
} catch (Throwable var18) {
CrashReport report = CrashReport.forThrowable(var18, "mouseClicked event handler");
screen.fillCrashDetails(report);
CrashReportCategory mouseDetails = report.addCategory("Mouse");
this.fillMousePositionDetails(mouseDetails, window);
mouseDetails.setDetail("Button", event.button());
throw new ReportedException(report);
}
} else {
try {
if (screen.mouseReleased(event)) {
return;
}
} catch (Throwable var17) {
CrashReport report = CrashReport.forThrowable(var17, "mouseReleased event handler");
screen.fillCrashDetails(report);
CrashReportCategory mouseDetails = report.addCategory("Mouse");
this.fillMousePositionDetails(mouseDetails, window);
mouseDetails.setDetail("Button", event.button());
throw new ReportedException(report);
}
}
}
}
if (this.minecraft.screen == null && this.minecraft.getOverlay() == null) {
if (buttonInfo.button() == 0) {
this.isLeftPressed = pressed;
} else if (buttonInfo.button() == 2) {
this.isMiddlePressed = pressed;
} else if (buttonInfo.button() == 1) {
this.isRightPressed = pressed;
}
InputConstants.Key mouseKey = InputConstants.Type.MOUSE.getOrCreate(buttonInfo.button());
KeyMapping.set(mouseKey, pressed);
if (pressed) {
KeyMapping.click(mouseKey);
}
}
}
}
private MouseButtonInfo simulateRightClick(MouseButtonInfo info, boolean pressed) {
if (InputQuirks.SIMULATE_RIGHT_CLICK_WITH_LONG_LEFT_CLICK && info.button() == 0) {
if (pressed) {
if ((info.modifiers() & 2) == 2) {
this.fakeRightMouse++;
return new MouseButtonInfo(1, info.modifiers());
}
} else if (this.fakeRightMouse > 0) {
this.fakeRightMouse--;
return new MouseButtonInfo(1, info.modifiers());
}
}
return info;
}
public void fillMousePositionDetails(CrashReportCategory category, Window window) {
category.setDetail(
"Mouse location",
() -> String.format(
Locale.ROOT, "Scaled: (%f, %f). Absolute: (%f, %f)", getScaledXPos(window, this.xpos), getScaledYPos(window, this.ypos), this.xpos, this.ypos
)
);
category.setDetail(
"Screen size",
() -> String.format(
Locale.ROOT,
"Scaled: (%d, %d). Absolute: (%d, %d). Scale factor of %d",
window.getGuiScaledWidth(),
window.getGuiScaledHeight(),
window.getWidth(),
window.getHeight(),
window.getGuiScale()
)
);
}
private void onScroll(long handle, double xoffset, double yoffset) {
if (handle == this.minecraft.getWindow().handle()) {
this.minecraft.getFramerateLimitTracker().onInputReceived();
boolean discreteScroll = this.minecraft.options.discreteMouseScroll().get();
double scrollSensitivity = this.minecraft.options.mouseWheelSensitivity().get();
double scaledXOffset = (discreteScroll ? Math.signum(xoffset) : xoffset) * scrollSensitivity;
double scaledYOffset = (discreteScroll ? Math.signum(yoffset) : yoffset) * scrollSensitivity;
if (this.minecraft.getOverlay() == null) {
if (this.minecraft.screen != null) {
double xm = this.getScaledXPos(this.minecraft.getWindow());
double ym = this.getScaledYPos(this.minecraft.getWindow());
this.minecraft.screen.mouseScrolled(xm, ym, scaledXOffset, scaledYOffset);
this.minecraft.screen.afterMouseAction();
} else if (this.minecraft.player != null) {
Vector2i wheelXY = this.scrollWheelHandler.onMouseScroll(scaledXOffset, scaledYOffset);
if (wheelXY.x == 0 && wheelXY.y == 0) {
return;
}
int wheel = wheelXY.y == 0 ? -wheelXY.x : wheelXY.y;
if (this.minecraft.player.isSpectator()) {
if (this.minecraft.gui.getSpectatorGui().isMenuActive()) {
this.minecraft.gui.getSpectatorGui().onMouseScrolled(-wheel);
} else {
float speed = Mth.clamp(this.minecraft.player.getAbilities().getFlyingSpeed() + wheelXY.y * 0.005F, 0.0F, 0.2F);
this.minecraft.player.getAbilities().setFlyingSpeed(speed);
}
} else {
Inventory inventory = this.minecraft.player.getInventory();
inventory.setSelectedSlot(
ScrollWheelHandler.getNextScrollWheelSelection(wheel, inventory.getSelectedSlot(), Inventory.getSelectionSize())
);
}
}
}
}
}
private void onDrop(long handle, List<Path> files, int failedCount) {
this.minecraft.getFramerateLimitTracker().onInputReceived();
if (this.minecraft.screen != null) {
this.minecraft.screen.onFilesDrop(files);
}
if (failedCount > 0) {
SystemToast.onFileDropFailure(this.minecraft, failedCount);
}
}
public void setup(Window window) {
InputConstants.setupMouseCallbacks(
window, (window1, xpos, ypos) -> this.minecraft.execute(() -> this.onMove(window1, xpos, ypos)), (window1, button, action, mods) -> {
MouseButtonInfo buttonInfo = new MouseButtonInfo(button, mods);
this.minecraft.execute(() -> this.onButton(window1, buttonInfo, action));
}, (window1, xoffset, yoffset) -> this.minecraft.execute(() -> this.onScroll(window1, xoffset, yoffset)), (window1, count, namesPtr) -> {
List<Path> names = new ArrayList<>(count);
int failedCount = 0;
for (int i = 0; i < count; i++) {
String name = GLFWDropCallback.getName(namesPtr, i);
try {
names.add(Paths.get(name));
} catch (InvalidPathException var11) {
failedCount++;
LOGGER.error("Failed to parse path '{}'", name, var11);
}
}
if (!names.isEmpty()) {
int finalFailedCount = failedCount;
this.minecraft.execute(() -> this.onDrop(window1, names, finalFailedCount));
}
}
);
}
private void onMove(long handle, double xpos, double ypos) {
if (handle == this.minecraft.getWindow().handle()) {
if (this.ignoreFirstMove) {
this.xpos = xpos;
this.ypos = ypos;
this.ignoreFirstMove = false;
} else {
if (this.minecraft.isWindowActive()) {
this.accumulatedDX = this.accumulatedDX + (xpos - this.xpos);
this.accumulatedDY = this.accumulatedDY + (ypos - this.ypos);
}
this.xpos = xpos;
this.ypos = ypos;
}
}
}
public void handleAccumulatedMovement() {
double time = Blaze3D.getTime();
double mousea = time - this.lastHandleMovementTime;
this.lastHandleMovementTime = time;
if (this.minecraft.isWindowActive()) {
Screen screen = this.minecraft.screen;
boolean mouseMoved = this.accumulatedDX != 0.0 || this.accumulatedDY != 0.0;
if (mouseMoved) {
this.minecraft.getFramerateLimitTracker().onInputReceived();
}
if (screen != null && this.minecraft.getOverlay() == null && mouseMoved) {
Window window = this.minecraft.getWindow();
double xm = this.getScaledXPos(window);
double ym = this.getScaledYPos(window);
try {
screen.mouseMoved(xm, ym);
} catch (Throwable var20) {
CrashReport report = CrashReport.forThrowable(var20, "mouseMoved event handler");
screen.fillCrashDetails(report);
CrashReportCategory mouseDetails = report.addCategory("Mouse");
this.fillMousePositionDetails(mouseDetails, window);
throw new ReportedException(report);
}
if (this.activeButton != null && this.mousePressedTime > 0.0) {
double dx = getScaledXPos(window, this.accumulatedDX);
double dy = getScaledYPos(window, this.accumulatedDY);
try {
screen.mouseDragged(new MouseButtonEvent(xm, ym, this.activeButton), dx, dy);
} catch (Throwable var19) {
CrashReport report = CrashReport.forThrowable(var19, "mouseDragged event handler");
screen.fillCrashDetails(report);
CrashReportCategory mouseDetails = report.addCategory("Mouse");
this.fillMousePositionDetails(mouseDetails, window);
throw new ReportedException(report);
}
}
screen.afterMouseMove();
}
if (this.isMouseGrabbed() && this.minecraft.player != null) {
this.turnPlayer(mousea);
}
}
this.accumulatedDX = 0.0;
this.accumulatedDY = 0.0;
}
public static double getScaledXPos(Window window, double x) {
return x * window.getGuiScaledWidth() / window.getScreenWidth();
}
public double getScaledXPos(Window window) {
return getScaledXPos(window, this.xpos);
}
public static double getScaledYPos(Window window, double y) {
return y * window.getGuiScaledHeight() / window.getScreenHeight();
}
public double getScaledYPos(Window window) {
return getScaledYPos(window, this.ypos);
}
private void turnPlayer(double mousea) {
double ss = this.minecraft.options.sensitivity().get() * 0.6F + 0.2F;
double sensitivityMod = ss * ss * ss;
double sens = sensitivityMod * 8.0;
double xo;
double yo;
if (this.minecraft.options.smoothCamera) {
double dx = this.smoothTurnX.getNewDeltaValue(this.accumulatedDX * sens, mousea * sens);
double dy = this.smoothTurnY.getNewDeltaValue(this.accumulatedDY * sens, mousea * sens);
xo = dx;
yo = dy;
} else if (this.minecraft.options.getCameraType().isFirstPerson() && this.minecraft.player.isScoping()) {
this.smoothTurnX.reset();
this.smoothTurnY.reset();
xo = this.accumulatedDX * sensitivityMod;
yo = this.accumulatedDY * sensitivityMod;
} else {
this.smoothTurnX.reset();
this.smoothTurnY.reset();
xo = this.accumulatedDX * sens;
yo = this.accumulatedDY * sens;
}
this.minecraft.getTutorial().onMouse(xo, yo);
if (this.minecraft.player != null) {
this.minecraft.player.turn(this.minecraft.options.invertMouseX().get() ? -xo : xo, this.minecraft.options.invertMouseY().get() ? -yo : yo);
}
}
public boolean isLeftPressed() {
return this.isLeftPressed;
}
public boolean isMiddlePressed() {
return this.isMiddlePressed;
}
public boolean isRightPressed() {
return this.isRightPressed;
}
public double xpos() {
return this.xpos;
}
public double ypos() {
return this.ypos;
}
public void setIgnoreFirstMove() {
this.ignoreFirstMove = true;
}
public boolean isMouseGrabbed() {
return this.mouseGrabbed;
}
public void grabMouse() {
if (this.minecraft.isWindowActive()) {
if (!this.mouseGrabbed) {
if (InputQuirks.RESTORE_KEY_STATE_AFTER_MOUSE_GRAB) {
KeyMapping.setAll();
}
this.mouseGrabbed = true;
this.xpos = this.minecraft.getWindow().getScreenWidth() / 2;
this.ypos = this.minecraft.getWindow().getScreenHeight() / 2;
InputConstants.grabOrReleaseMouse(this.minecraft.getWindow(), 212995, this.xpos, this.ypos);
this.minecraft.setScreen(null);
this.minecraft.missTime = 10000;
this.ignoreFirstMove = true;
}
}
}
public void releaseMouse() {
if (this.mouseGrabbed) {
this.mouseGrabbed = false;
this.xpos = this.minecraft.getWindow().getScreenWidth() / 2;
this.ypos = this.minecraft.getWindow().getScreenHeight() / 2;
InputConstants.grabOrReleaseMouse(this.minecraft.getWindow(), 212993, this.xpos, this.ypos);
}
}
public void cursorEntered() {
this.ignoreFirstMove = true;
}
public void drawDebugMouseInfo(Font font, GuiGraphicsExtractor graphics) {
Window window = this.minecraft.getWindow();
double x = this.getScaledXPos(window);
double y = this.getScaledYPos(window) - 8.0;
String text = String.format(Locale.ROOT, "%.0f,%.0f", x, y);
graphics.text(font, text, (int)x, (int)y, -1);
}
@OnlyIn(Dist.CLIENT)
private record LastClick(long time, Screen screen) {
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
Blaze3D.getTime()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
InputConstants.grabOrReleaseMouse(), InputConstants.setupMouseCallbacks()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
CrashReport.forThrowable()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ReportedException()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
KeyMapping.click(), KeyMapping.set(), KeyMapping.setAll()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
字段/方法调用/构造调用 - 关联成员:
ScrollWheelHandler(), ScrollWheelHandler.getNextScrollWheelSelection()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SystemToast.onFileDropFailure()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
MouseButtonEvent()
- 引用位置:
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
MouseButtonInfo()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.clamp()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
SmoothDouble()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.getMillis()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Inventory.getSelectionSize()
- 引用位置: