add shift click for unit repair

This commit is contained in:
alexcrea 2024-02-09 15:06:56 +01:00
parent 4195add655
commit d9c7a9376b

View file

@ -9,6 +9,7 @@ import io.delilaheve.util.ItemUtil.isEnchantedBook
import io.delilaheve.util.ItemUtil.repairFrom import io.delilaheve.util.ItemUtil.repairFrom
import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe
import io.delilaheve.util.ItemUtil.unitRepair import io.delilaheve.util.ItemUtil.unitRepair
import org.bukkit.GameMode
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.Event import org.bukkit.event.Event
@ -25,6 +26,7 @@ import xyz.alexcrea.group.ConflictType
import xyz.alexcrea.util.UnitRepairUtil.getRepair import xyz.alexcrea.util.UnitRepairUtil.getRepair
import kotlin.math.min import kotlin.math.min
/** /**
* Listener for anvil events * Listener for anvil events
*/ */
@ -35,6 +37,9 @@ class AnvilEventListener : Listener {
private const val ANVIL_INPUT_LEFT = 0 private const val ANVIL_INPUT_LEFT = 0
private const val ANVIL_INPUT_RIGHT = 1 private const val ANVIL_INPUT_RIGHT = 1
private const val ANVIL_OUTPUT_SLOT = 2 private const val ANVIL_OUTPUT_SLOT = 2
// static slot container
private val NO_SLOT = SlotContainer(SlotType.NO_SLOT,0)
private val CURSOR_SLOT = SlotContainer(SlotType.CURSOR,0)
} }
/** /**
@ -170,6 +175,20 @@ class AnvilEventListener : Listener {
if(canMerge){ if(canMerge){
event.result = Event.Result.ALLOW event.result = Event.Result.ALLOW
}else if(unitRepairResult != null){ }else if(unitRepairResult != null){
onUnitRepairExtract(leftItem, rightItem, output,
unitRepairResult, event, player, inventory)
return
}
}
private fun onUnitRepairExtract(leftItem: ItemStack,
rightItem: ItemStack,
output: ItemStack,
unitRepairResult: Double,
event: InventoryClickEvent,
player: Player,
inventory: AnvilInventory){
val resultCopy = leftItem.clone() val resultCopy = leftItem.clone()
val resultAmount = resultCopy.unitRepair( val resultAmount = resultCopy.unitRepair(
rightItem.amount, unitRepairResult) rightItem.amount, unitRepairResult)
@ -179,7 +198,8 @@ class AnvilEventListener : Listener {
event.isCancelled = true event.isCancelled = true
// And we give the item manually // And we give the item manually
// But first we check if we should give the item // But first we check if we should give the item
if(player.itemOnCursor.type != Material.AIR) return val slotDestination = getActionSlot(event,player)
if(slotDestination.type == SlotType.NO_SLOT) return
if(inventory.repairCost > player.level) return if(inventory.repairCost > player.level) return
// Get repairCost // Get repairCost
@ -196,8 +216,9 @@ class AnvilEventListener : Listener {
repairCost+= calculatePenalty(leftItem,null,resultCopy) repairCost+= calculatePenalty(leftItem,null,resultCopy)
repairCost+= resultAmount*ConfigOptions.unitRepairCost repairCost+= resultAmount*ConfigOptions.unitRepairCost
if((inventory.maximumRepairCost < repairCost) val ignoreXpCost = player.gameMode == GameMode.CREATIVE
|| (player.level < repairCost)) return if((!ignoreXpCost) && ((inventory.maximumRepairCost < repairCost)
|| (player.level < repairCost))) return
// We remove what should be removed // We remove what should be removed
inventory.setItem(ANVIL_INPUT_LEFT,null) inventory.setItem(ANVIL_INPUT_LEFT,null)
@ -205,13 +226,49 @@ class AnvilEventListener : Listener {
inventory.setItem(ANVIL_INPUT_RIGHT,rightItem) inventory.setItem(ANVIL_INPUT_RIGHT,rightItem)
inventory.setItem(ANVIL_OUTPUT_SLOT, null) inventory.setItem(ANVIL_OUTPUT_SLOT, null)
UnsafeEnchants.log("repair cost: $repairCost") if(!ignoreXpCost){
player.level-= repairCost player.level-= repairCost
}
// Finally, we add the item to the player // Finally, we add the item to the player
if(slotDestination.type == SlotType.CURSOR){
player.setItemOnCursor(output) player.setItemOnCursor(output)
}else{// We assume SlotType == SlotType.INVENTORY
player.inventory.setItem(slotDestination.slot,output)
}
}
return /**
* Get the destination slot or "NO_SLOT" slot container if there is no slot available
*/
private fun getActionSlot(event: InventoryClickEvent, player: Player): SlotContainer{
if(event.isShiftClick){
val inventory = player.inventory
val firstEmpty = inventory.firstEmpty()
if(firstEmpty == -1){
return NO_SLOT
}
//check hotbare full
var slotIndex = 8
while(slotIndex >= 0 && ((inventory.getItem(slotIndex)?.type ?: Material.AIR) != Material.AIR)){
slotIndex--
}
if(slotIndex >= 0){
return SlotContainer(SlotType.INVENTORY,slotIndex)
}
slotIndex = 35 //4*9 - 1 (max of player inventory)
while(slotIndex >= 9 && ((inventory.getItem(slotIndex)?.type ?: Material.AIR) != Material.AIR)){
slotIndex--
}
if(slotIndex < 9){
return NO_SLOT
}
return SlotContainer(SlotType.INVENTORY,slotIndex)
}else{
if(player.itemOnCursor.type != Material.AIR){
return NO_SLOT
}
return CURSOR_SLOT
} }
} }
@ -221,24 +278,24 @@ class AnvilEventListener : Listener {
*/ */
private fun calculatePenalty(left: ItemStack, right: ItemStack?, result: ItemStack): Int{ private fun calculatePenalty(left: ItemStack, right: ItemStack?, result: ItemStack): Int{
// Extracted From https://minecraft.fandom.com/wiki/Anvil_mechanics#Enchantment_equation // Extracted From https://minecraft.fandom.com/wiki/Anvil_mechanics#Enchantment_equation
// Calculate work penality // Calculate work penalty
val leftPenality = (left.itemMeta as? Repairable)?.repairCost ?: 0 val leftPenalty = (left.itemMeta as? Repairable)?.repairCost ?: 0
val rightPenality = val rightPenalty =
if(right == null){ 0 } if(right == null){ 0 }
else{ (right.itemMeta as? Repairable)?.repairCost ?: 0 } else{ (right.itemMeta as? Repairable)?.repairCost ?: 0 }
// Try to set work penality for the result item // Try to set work penalty for the result item
result.itemMeta?.let { result.itemMeta?.let {
(it as? Repairable)?.repairCost = leftPenality*2+1 (it as? Repairable)?.repairCost = leftPenalty*2+1
result.itemMeta = it result.itemMeta = it
} }
UnsafeEnchants.log("Calculated penality: " + UnsafeEnchants.log("Calculated penalty: " +
"leftPenality: $leftPenality, " + "leftPenalty: $leftPenalty, " +
"rightPenality: $rightPenality, " + "rightPenalty: $rightPenalty, " +
"result penality: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}") "result penalty: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}")
return leftPenality + rightPenality return leftPenalty + rightPenalty
} }
/** /**
@ -307,3 +364,12 @@ class AnvilEventListener : Listener {
} }
} }
private class SlotContainer(val type: SlotType, val slot: Int)
private enum class SlotType{
CURSOR,
INVENTORY,
NO_SLOT
}