184 lines
6.5 KiB
Java
184 lines
6.5 KiB
Java
/*
|
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
|
* Copyright (C) 2016-2021 ViaVersion and contributors
|
|
*
|
|
* This program 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.
|
|
*
|
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package com.viaversion.viaversion.protocols.protocol1_9to1_8.storage;
|
|
|
|
import com.viaversion.viaversion.api.connection.StoredObject;
|
|
import com.viaversion.viaversion.api.connection.UserConnection;
|
|
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
public class InventoryTracker extends StoredObject {
|
|
private String inventory;
|
|
|
|
private final Map<Short, Map<Short, Integer>> windowItemCache = new HashMap<>();
|
|
private int itemIdInCursor = 0;
|
|
private boolean dragging = false;
|
|
|
|
public InventoryTracker(UserConnection user) {
|
|
super(user);
|
|
}
|
|
|
|
public String getInventory() {
|
|
return inventory;
|
|
}
|
|
|
|
public void setInventory(String inventory) {
|
|
this.inventory = inventory;
|
|
}
|
|
|
|
public void resetInventory(short windowId) {
|
|
// Reset the cursor state of the inventory
|
|
if (inventory == null) {
|
|
this.itemIdInCursor = 0;
|
|
this.dragging = false;
|
|
|
|
// Remove window from cache (Except players window)
|
|
if (windowId != 0) {
|
|
this.windowItemCache.remove(windowId);
|
|
}
|
|
}
|
|
}
|
|
|
|
public int getItemId(short windowId, short slot) {
|
|
Map<Short, Integer> itemMap = this.windowItemCache.get(windowId);
|
|
if (itemMap == null) {
|
|
return 0;
|
|
}
|
|
|
|
return itemMap.getOrDefault(slot, 0);
|
|
}
|
|
|
|
public void setItemId(short windowId, short slot, int itemId) {
|
|
if (windowId == -1 && slot == -1) {
|
|
// Set the cursor item
|
|
this.itemIdInCursor = itemId;
|
|
} else {
|
|
// Set item in normal inventory
|
|
this.windowItemCache.computeIfAbsent(windowId, k -> new HashMap<>()).put(slot, itemId);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle the window click to track the position of the sword
|
|
*
|
|
* @param windowId Id of the current inventory
|
|
* @param mode Inventory operation mode
|
|
* @param hoverSlot The slot number of the current mouse position
|
|
* @param button The button to use in the click
|
|
*/
|
|
public void handleWindowClick(short windowId, byte mode, short hoverSlot, byte button) {
|
|
EntityTracker1_9 entityTracker = getUser().getEntityTracker(Protocol1_9To1_8.class);
|
|
|
|
// Skip inventory background clicks
|
|
if (hoverSlot == -1) {
|
|
return;
|
|
}
|
|
|
|
// Interaction with the offhand slot
|
|
if (hoverSlot == 45) {
|
|
entityTracker.setSecondHand(null); // Remove it so we know that we can update it on ITEM_USE
|
|
return;
|
|
}
|
|
|
|
// It is not possible to put a sword into the armor or crafting result slot
|
|
boolean isArmorOrResultSlot = hoverSlot >= 5 && hoverSlot <= 8 || hoverSlot == 0;
|
|
|
|
switch (mode) {
|
|
case 0: // Click on slot
|
|
|
|
// The cursor is empty, so we can put an item to it
|
|
if (this.itemIdInCursor == 0) {
|
|
// Move item to cursor
|
|
this.itemIdInCursor = getItemId(windowId, hoverSlot);
|
|
|
|
// Remove item in slot
|
|
setItemId(windowId, hoverSlot, 0);
|
|
} else {
|
|
// Dropping item
|
|
if (hoverSlot == -999) {
|
|
this.itemIdInCursor = 0;
|
|
} else if (!isArmorOrResultSlot) {
|
|
int previousItem = getItemId(windowId, hoverSlot);
|
|
|
|
// Place item in inventory
|
|
setItemId(windowId, hoverSlot, this.itemIdInCursor);
|
|
|
|
// Pick up the other item
|
|
this.itemIdInCursor = previousItem;
|
|
}
|
|
}
|
|
break;
|
|
case 2: // Move item using number keys
|
|
if (!isArmorOrResultSlot) {
|
|
short hotkeySlot = (short) (button + 36);
|
|
|
|
// Get items to swap
|
|
int sourceItem = getItemId(windowId, hoverSlot);
|
|
int destinationItem = getItemId(windowId, hotkeySlot);
|
|
|
|
// Swap
|
|
setItemId(windowId, hotkeySlot, sourceItem);
|
|
setItemId(windowId, hoverSlot, destinationItem);
|
|
}
|
|
|
|
break;
|
|
case 4: // Drop item
|
|
int hoverItem = getItemId(windowId, hoverSlot);
|
|
|
|
if (hoverItem != 0) {
|
|
setItemId(windowId, hoverSlot, 0);
|
|
}
|
|
|
|
break;
|
|
case 5: // Mouse dragging
|
|
switch (button) {
|
|
case 0: // Start left dragging
|
|
case 4: // Start right dragging
|
|
this.dragging = true;
|
|
break;
|
|
case 1: // Place item during left dragging
|
|
case 5: // Place item during right dragging
|
|
// Check dragging mode and item on cursor
|
|
if (this.dragging && this.itemIdInCursor != 0 && !isArmorOrResultSlot) {
|
|
int previousItem = getItemId(windowId, hoverSlot);
|
|
|
|
// Place item on cursor in hovering slot
|
|
setItemId(windowId, hoverSlot, this.itemIdInCursor);
|
|
|
|
// Pick up the other item
|
|
this.itemIdInCursor = previousItem;
|
|
}
|
|
break;
|
|
case 2: // Stop left dragging
|
|
case 6: // Stop right dragging
|
|
this.dragging = false;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Update shield state in offhand
|
|
entityTracker.syncShieldWithSword();
|
|
}
|
|
}
|