wow no way, improved grindstones are here

(you can actually shift click sponges in now)
(also why are they so goddamn limited in what interactions the server receives)
This commit is contained in:
XTerPL 2025-01-26 18:14:16 +01:00
parent 20cc493196
commit 1c4969a9f1
7 changed files with 289 additions and 101 deletions

View file

@ -19,6 +19,7 @@ import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.enchantments.sys.CustomEnchantment;
import de.blazemcworld.blazinggames.enchantments.sys.EnchantmentHelper;
import de.blazemcworld.blazinggames.items.CustomItems;
import de.blazemcworld.blazinggames.items.predicates.ItemPredicates;
import de.blazemcworld.blazinggames.userinterfaces.UserInterface;
import de.blazemcworld.blazinggames.utils.InventoryUtils;
import de.blazemcworld.blazinggames.utils.Pair;
@ -56,88 +57,119 @@ public class ClickInventorySlotEventListener implements Listener {
if (event.getClick() == ClickType.RIGHT && CustomItems.PORTABLE_CRAFTING_TABLE.matchItem(event.getCurrentItem())) {
event.setCancelled(true);
Bukkit.getScheduler().runTask(BlazingGames.get(), () -> event.getWhoClicked().openWorkbench(null, true));
return;
}
if(!event.isCancelled() && event.getInventory().getHolder() instanceof UserInterface ui && event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) {
event.setCancelled(!ui.onShiftClick(event.getCurrentItem(), event.getAction(), event));
if(event.isShiftClick()) {
if(event.getInventory().getHolder() instanceof UserInterface ui) {
event.setCancelled(!ui.onShiftClick(event.getCurrentItem(), event.getAction(), event));
return;
}
if(event.getInventory() instanceof GrindstoneInventory grindstone) {
ItemStack movedItem = event.getCurrentItem();
if(movedItem != null && ItemPredicates.grindstoneHandler.matchItem(movedItem)) {
for(int i = 0; i < 2; i++) {
ItemStack current = grindstone.getItem(i);
if(current == null || current.isEmpty()) {
int available = getGrindstoneDragMax(movedItem);
if(available > movedItem.getAmount()) {
available = movedItem.getAmount();
}
grindstone.setItem(i, movedItem.asQuantity(available));
movedItem.subtract(available);
}
else if(current.isSimilar(movedItem)) {
int available = getGrindstoneDragMax(movedItem) - current.getAmount();
if(available > movedItem.getAmount()) {
available = movedItem.getAmount();
}
current.add(available);
movedItem.subtract(available);
}
}
event.setCancelled(true);
}
}
return;
}
}
if(inventory instanceof GrindstoneInventory grindstone) {
ItemStack cursorItem = event.getCursor().clone();
if(cursorItem.getType() == Material.SPONGE || cursorItem.getType() == Material.WET_SPONGE) {
if(event.getSlot() != 2) {
ItemStack eventItem;
ItemStack cursorItem = event.getCursor();
if (event.getSlot() != 2) {
ItemStack eventItem = grindstone.getItem(event.getSlot());
switch (event.getAction()) {
case PLACE_ONE, PLACE_SOME, PLACE_ALL -> {
if (ItemPredicates.grindstoneHandler.matchItem(cursorItem)) {
int amount = cursorItem.getAmount();
if(event.getSlot() == 0) {
eventItem = grindstone.getUpperItem();
}
else if(event.getSlot() == 1) {
eventItem = grindstone.getLowerItem();
}
else {
return;
}
if(eventItem == null) {
eventItem = ItemStack.empty();
}
else {
eventItem = eventItem.clone();
}
BlazingGames.get().debugLog(cursorItem.toString());
BlazingGames.get().debugLog(eventItem.toString());
if(event.getClick() == ClickType.LEFT) {
if(eventItem.isSimilar(cursorItem)) {
int total = eventItem.getAmount() + cursorItem.getAmount();
if(total > eventItem.getMaxStackSize()) {
cursorItem.setAmount(total - eventItem.getMaxStackSize());
eventItem.setAmount(eventItem.getMaxStackSize());
if (event.getAction() == InventoryAction.PLACE_ONE) {
amount = 1;
}
else {
cursorItem.subtract(cursorItem.getAmount());
eventItem.setAmount(total);
if (eventItem == null || eventItem.isEmpty()) {
int available = getGrindstoneDragMax(cursorItem);
if (available > amount) {
available = amount;
}
grindstone.setItem(event.getSlot(), cursorItem.asQuantity(available));
cursorItem.subtract(available);
event.setCancelled(true);
} else if (eventItem.isSimilar(cursorItem)) {
int available = getGrindstoneDragMax(eventItem) - eventItem.getAmount();
if (available > amount) {
available = amount;
}
eventItem.add(available);
cursorItem.subtract(available);
event.setCancelled(true);
}
}
else {
ItemStack swap = cursorItem;
cursorItem = eventItem;
eventItem = swap;
}
case SWAP_WITH_CURSOR -> {
if (ItemPredicates.grindstoneHandler.matchItem(cursorItem)) {
if (cursorItem.getAmount() <= getGrindstoneDragMax(cursorItem)) {
event.getWhoClicked().setItemOnCursor(eventItem);
grindstone.setItem(event.getSlot(), cursorItem);
}
event.setCancelled(true);
}
}
else if(event.getClick() == ClickType.RIGHT) {
if(eventItem.isSimilar(cursorItem)) {
if(eventItem.getAmount() < eventItem.getMaxStackSize()) {
eventItem.add();
cursorItem.subtract();
case HOTBAR_SWAP -> {
if (event.getHotbarButton() >= 0) {
ItemStack hotbar = event.getWhoClicked().getInventory().getItem(event.getHotbarButton());
if (hotbar == null || hotbar.isEmpty()) {
inventory.setItem(event.getSlot(), ItemStack.empty());
event.getWhoClicked().getInventory().setItem(event.getHotbarButton(), eventItem);
} else if (ItemPredicates.grindstoneHandler.matchItem(hotbar) && hotbar.getAmount() <= getGrindstoneDragMax(hotbar)) {
inventory.setItem(event.getSlot(), hotbar);
event.getWhoClicked().getInventory().setItem(event.getHotbarButton(), eventItem);
}
} else {
if (eventItem == null || eventItem.isEmpty()) {
eventItem = cursorItem.asOne();
cursorItem.subtract();
ItemStack hotbar = event.getWhoClicked().getInventory().getItemInOffHand();
if(hotbar.isEmpty()) {
inventory.setItem(event.getSlot(), ItemStack.empty());
event.getWhoClicked().getInventory().setItemInOffHand(eventItem);
}
else if (ItemPredicates.grindstoneHandler.matchItem(hotbar) && hotbar.getAmount() <= getGrindstoneDragMax(hotbar)) {
inventory.setItem(event.getSlot(), event.getWhoClicked().getInventory().getItemInOffHand());
event.getWhoClicked().getInventory().setItemInOffHand(eventItem);
}
}
}
BlazingGames.get().log(cursorItem.toString());
BlazingGames.get().log(eventItem.toString());
if(event.getSlot() == 0) {
grindstone.setUpperItem(eventItem);
}
else if(event.getSlot() == 1) {
grindstone.setLowerItem(eventItem);
}
event.getWhoClicked().setItemOnCursor(cursorItem);
event.setCancelled(true);
return;
}
}
if(event.getSlot() == 2) {
else {
ItemStack up = grindstone.getUpperItem();
ItemStack down = grindstone.getLowerItem();
ItemStack result = grindstone.getResult();
@ -145,7 +177,7 @@ public class ClickInventorySlotEventListener implements Listener {
if(result != null && !result.isEmpty()) {
if(up != null && !up.isEmpty()) {
if(down != null && !down.isEmpty()) {
if(up.getType() == Material.SPONGE || up.getType() == Material.WET_SPONGE) {
if(ItemPredicates.grindstoneScrubber.matchItem(up)) {
ItemStack book = scrubResultClick(down, up);
if(book == null) {
@ -160,7 +192,7 @@ public class ClickInventorySlotEventListener implements Listener {
return;
}
else if(down.getType() == Material.SPONGE || down.getType() == Material.WET_SPONGE) {
else if(ItemPredicates.grindstoneScrubber.matchItem(down)) {
ItemStack book = scrubResultClick(up, down);
if(book == null) {
@ -172,13 +204,12 @@ public class ClickInventorySlotEventListener implements Listener {
if(giveItemStack(event, result)) {
grindstone.setUpperItem(book);
}
return;
}
}
}
}
}
return;
}
}
@ -214,6 +245,13 @@ public class ClickInventorySlotEventListener implements Listener {
return book;
}
private int getGrindstoneDragMax(ItemStack item) {
if(ItemPredicates.grindstoneScrubber.matchItem(item)) {
return item.getMaxStackSize();
}
return 1;
}
private boolean giveItemStack(InventoryClickEvent event, ItemStack stack) {
stack = stack.clone();

View file

@ -47,18 +47,24 @@ public class PrepareAnvilEventListener implements Listener {
event.getView().setRepairItemCountCost(0);
int repairCost = result.getDataOrDefault(DataComponentTypes.REPAIR_COST, 0);
int minRepairCost = repairCost;
boolean increaseRepairCost = false;
if(enchantingItem != null && !enchantingItem.isEmpty()) {
repairCost += enchantingItem.getDataOrDefault(DataComponentTypes.REPAIR_COST, 0);
if(CustomItem.isCustomItem(enchantingItem))
{
if(EnchantmentHelper.canEnchantItem(result)) {
if(EnchantmentHelper.canEnchantItem(result) && result.getAmount() == 1) {
CustomItem<?> item = CustomItem.getCustomItem(enchantingItem);
if(item != null && item.matchItem(result)) {
Pair<ItemStack, Integer> enchantResult = EnchantmentHelper.enchantFromItem(result, enchantingItem);
result = enchantResult.left;
repairCost += repairByCombination(result, enchantingItem) + enchantResult.right;
repairCost += repairByCombination(result, enchantingItem, 12) + enchantResult.right;
increaseRepairCost = true;
minRepairCost = Math.min(minRepairCost, enchantingItem.getDataOrDefault(DataComponentTypes.REPAIR_COST, 0));
}
}
}
@ -89,19 +95,26 @@ public class PrepareAnvilEventListener implements Listener {
event.getView().setRepairItemCountCost(count);
repairCost += count;
increaseRepairCost = true;
}
}
else {
if(EnchantmentHelper.canEnchantItem(result)) {
if(EnchantmentHelper.canEnchantItem(result) && result.getAmount() == 1) {
if(enchantingItem.getType() == Material.ENCHANTED_BOOK) {
Pair<ItemStack, Integer> enchantResult = EnchantmentHelper.enchantFromItem(result, enchantingItem);
result = enchantResult.left;
repairCost += enchantResult.right;
increaseRepairCost = true;
minRepairCost = Math.min(minRepairCost, enchantingItem.getDataOrDefault(DataComponentTypes.REPAIR_COST, 0));
}
else if(!CustomItem.isCustomItem(result) && enchantingItem.getType() == result.getType()) {
Pair<ItemStack, Integer> enchantResult = EnchantmentHelper.enchantFromItem(result, enchantingItem);
result = enchantResult.left;
repairCost += repairByCombination(result, enchantingItem) + enchantResult.right;
repairCost += repairByCombination(result, enchantingItem, 12) + enchantResult.right;
increaseRepairCost = true;
minRepairCost = Math.min(minRepairCost, enchantingItem.getDataOrDefault(DataComponentTypes.REPAIR_COST, 0));
}
}
}
@ -128,11 +141,19 @@ public class PrepareAnvilEventListener implements Listener {
return;
}
if(increaseRepairCost) {
minRepairCost *= 2;
minRepairCost++;
result.setData(DataComponentTypes.REPAIR_COST, minRepairCost);
}
if(repairCost > 10) repairCost = 10;
event.setResult(result);
event.getView().setRepairCost(repairCost);
}
private static int repairByCombination(ItemStack in, ItemStack repairer) {
public static int repairByCombination(ItemStack in, ItemStack repairer, int extraPercentage) {
if(!in.hasData(DataComponentTypes.MAX_DAMAGE) ||
!in.hasData(DataComponentTypes.DAMAGE) ||
in.hasData(DataComponentTypes.UNBREAKABLE))
@ -149,7 +170,7 @@ public class PrepareAnvilEventListener implements Listener {
int inDurability = inMaxDamage - inDamage;
int repairerDurability = repairerMaxDamage - repairerDamage;
int extraDurability = inMaxDamage * 12 / 100;
int extraDurability = inMaxDamage * extraPercentage / 100;
int totalDurability = inDurability + repairerDurability + extraDurability;
int newDamage = inMaxDamage - totalDurability;

View file

@ -19,6 +19,9 @@ import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.enchantments.sys.CustomEnchantment;
import de.blazemcworld.blazinggames.enchantments.sys.EnchantmentHelper;
import de.blazemcworld.blazinggames.items.CustomItem;
import de.blazemcworld.blazinggames.items.change.ItemChangeProviders;
import de.blazemcworld.blazinggames.items.predicates.BreakableItemPredicate;
import de.blazemcworld.blazinggames.items.predicates.ItemPredicates;
import de.blazemcworld.blazinggames.utils.Pair;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
@ -33,13 +36,8 @@ public class PrepareGrindstoneEventListener implements Listener {
public void onGrindstonePrepare(PrepareGrindstoneEvent event) {
ItemStack up = event.getInventory().getUpperItem();
ItemStack down = event.getInventory().getLowerItem();
ItemStack result = event.getInventory().getResult();
result = grindstoneItem(up, down, result);
if(result == null) {
return;
}
ItemStack result = grindstoneItem(up, down);
event.setResult(result);
}
@ -47,20 +45,17 @@ public class PrepareGrindstoneEventListener implements Listener {
private ItemStack scrub(ItemStack tool, ItemStack sponge) {
ItemStack result = tool.clone();
if(CustomItem.isCustomItem(result)) return null;
if(!EnchantmentHelper.canEnchantItem(tool)) return null;
if(result.getType() == Material.ENCHANTED_BOOK) {
int total = EnchantmentHelper.getCustomEnchantments(result).size();
if(result.getItemMeta() instanceof EnchantmentStorageMeta meta) {
total += meta.getStoredEnchants().size();
}
if(!CustomItem.isCustomItem(result) && result.getType() == Material.ENCHANTED_BOOK) {
int total = EnchantmentHelper.getEnchantmentWrappers(result).size();
if(total <= 1) {
return null;
}
}
if(sponge.getType() == Material.SPONGE) {
if(!CustomItem.isCustomItem(sponge) && sponge.getType() == Material.SPONGE) {
Pair<Enchantment, Integer> entry = EnchantmentHelper.getEnchantmentEntryByIndex(tool, sponge.getAmount());
if(entry != null) {
@ -73,7 +68,7 @@ public class PrepareGrindstoneEventListener implements Listener {
}
}
}
if(sponge.getType() == Material.WET_SPONGE) {
if(!CustomItem.isCustomItem(sponge) && sponge.getType() == Material.WET_SPONGE) {
Pair<CustomEnchantment, Integer> entry = EnchantmentHelper.getCustomEnchantmentEntryByIndex(tool, sponge.getAmount());
if(entry != null) {
@ -87,10 +82,12 @@ public class PrepareGrindstoneEventListener implements Listener {
return null;
}
result = ItemChangeProviders.update(result);
return result;
}
public ItemStack grindstoneItem(ItemStack up, ItemStack down, ItemStack result) {
public ItemStack grindstoneItem(ItemStack up, ItemStack down) {
if(up == null || up.isEmpty()) {
ItemStack swap = down;
down = up;
@ -102,32 +99,50 @@ public class PrepareGrindstoneEventListener implements Listener {
else if(down != null && !down.isEmpty())
{
// double
if(!CustomItem.isCustomItem(down) && (down.getType() == Material.SPONGE || down.getType() == Material.WET_SPONGE)) {
if(ItemPredicates.grindstoneScrubber.matchItem(down)) {
if(EnchantmentHelper.canEnchantItem(up)) {
return scrub(up, down);
}
}
if(!CustomItem.isCustomItem(down) && (up.getType() == Material.SPONGE || up.getType() == Material.WET_SPONGE)) {
if(ItemPredicates.grindstoneScrubber.matchItem(up)) {
if(EnchantmentHelper.canEnchantItem(down)) {
return scrub(down, up);
}
}
if(up.getType() != down.getType()) {
CustomItem<?> customItem = CustomItem.getCustomItem(up);
if(customItem != null) {
if(!customItem.matchItem(down)) {
return null;
}
}
else if(up.getType() != down.getType()) {
return null;
}
}
if(result == null || result.isEmpty()) {
result = up.clone();
}
if(!EnchantmentHelper.hasCustomEnchantments(result)) {
return null;
}
ItemStack result = up.clone();
result = EnchantmentHelper.removeEnchantments(result);
if(down != null && !down.isEmpty()) {
if(BreakableItemPredicate.instance.matchItem(result)) {
PrepareAnvilEventListener.repairByCombination(result, down, 5);
}
else if(result.isSimilar(EnchantmentHelper.removeEnchantments(down))) {
if(result.getAmount() + down.getAmount() > result.getMaxStackSize()) {
return null;
}
result.add(down.getAmount());
if(result.isSimilar(down) && result.isSimilar(up)) {
return null;
}
}
else {
return null;
}
}
if(result.equals(up)) {
return null;
}

View file

@ -0,0 +1,62 @@
/*
* Copyright 2025 The Blazing Games Maintainers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.blazemcworld.blazinggames.items.predicates;
import net.kyori.adventure.text.Component;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
public class ComplexItemPredicate implements ItemPredicate {
List<ItemPredicate> predicates = new ArrayList<>();
String description;
public ComplexItemPredicate add(ItemPredicate... predicate) {
predicates.addAll(List.of(predicate));
return this;
}
public ComplexItemPredicate(String description, ItemPredicate... predicate) {
this.description = description;
add(predicate);
}
public List<ItemPredicate> getPredicates() {
return predicates;
}
@Override
public boolean matchItem(ItemStack stack) {
for(ItemPredicate predicate : predicates) {
if(!predicate.matchItem(stack)) {
return false;
}
}
return true;
}
@Override
public String toString() {
return predicates.toString();
}
@Override
public Component getDescription() {
return Component.text(description);
}
}

View file

@ -18,9 +18,18 @@ package de.blazemcworld.blazinggames.items.predicates;
import de.blazemcworld.blazinggames.enchantments.sys.BlazingEnchantmentTarget;
import de.blazemcworld.blazinggames.enchantments.sys.PaperEnchantmentTarget;
import org.bukkit.Material;
public class ItemPredicates {
public static final ItemPredicate enchantability = new AlternativeItemPredicate("Any Enchantable Item",
BreakableItemPredicate.instance, PaperEnchantmentTarget.ALL, BlazingEnchantmentTarget.BOW_ROCKET
);
public static final ItemPredicate grindstoneScrubber = new AlternativeItemPredicate("Sponge or Wet Sponge",
new MaterialItemPredicate(Material.SPONGE), new MaterialItemPredicate(Material.WET_SPONGE));
// Controls whether the special code regarding the grindstone inventory is run.
public static final ItemPredicate grindstoneHandler = new AlternativeItemPredicate("Any Item that can be put in a grindstone",
new ComplexItemPredicate("N/A", new NegativeItemPredicate(BreakableItemPredicate.instance), enchantability),
grindstoneScrubber
);
}

View file

@ -0,0 +1,39 @@
/*
* Copyright 2025 The Blazing Games Maintainers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.blazemcworld.blazinggames.items.predicates;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.JoinConfiguration;
import org.bukkit.inventory.ItemStack;
public class NegativeItemPredicate implements ItemPredicate {
private final ItemPredicate predicate;
public NegativeItemPredicate(ItemPredicate predicate) {
this.predicate = predicate;
}
@Override
public boolean matchItem(ItemStack stack) {
return !predicate.matchItem(stack);
}
@Override
public Component getDescription() {
return Component.join(JoinConfiguration.spaces(), Component.text("No"), predicate.getDescription());
}
}

View file

@ -111,11 +111,11 @@ public class InputSlot extends UsableInterfaceSlot {
}
yield true;
}
case HOTBAR_SWAP, HOTBAR_MOVE_AND_READD -> {
case HOTBAR_SWAP -> {
if(event.getHotbarButton() >= 0) {
ItemStack hotbar = event.getWhoClicked().getInventory().getItem(event.getHotbarButton());
if(hotbar == null) {
if(hotbar == null || hotbar.isEmpty()) {
inventory.setItem(slot, ItemStack.empty());
event.getWhoClicked().getInventory().setItem(event.getHotbarButton(), current);
}
@ -127,7 +127,11 @@ public class InputSlot extends UsableInterfaceSlot {
else {
ItemStack hotbar = event.getWhoClicked().getInventory().getItemInOffHand();
if(hotbar.getAmount() <= getDragMax(hotbar) && filterItem(hotbar)) {
if(hotbar.isEmpty()) {
inventory.setItem(slot, ItemStack.empty());
event.getWhoClicked().getInventory().setItemInOffHand(current);
}
else if(hotbar.getAmount() <= getDragMax(hotbar) && filterItem(hotbar)) {
inventory.setItem(slot, event.getWhoClicked().getInventory().getItemInOffHand());
event.getWhoClicked().getInventory().setItemInOffHand(current);
}