Merge branch 'master' into configGui-part5

This commit is contained in:
alexcrea 2024-04-28 18:01:39 +02:00
commit 95c976bd56
No known key found for this signature in database
GPG key ID: 43FD265DB0DBF91F
11 changed files with 117 additions and 37 deletions

View file

@ -1,7 +1,7 @@
# Custom Anvil
**Custom Anvil** is a plugin that allows server administrators to customise every aspect of the anvil's mechanics.
It is expected to work on 1.18 to 1.20.4 minecraft servers running spigot or paper.
It is expected to work on 1.18 to 1.20.5 minecraft servers running spigot or paper.
**Custom Anvil** was previously named **Unsafe Enchants+**.
It was renamed because it now affects every anvil aspect and not only unsafe enchants
@ -53,5 +53,13 @@ Default configuration can be found on following links:
- [unit_repair_item.yml](https://github.com/alexcrea/CustomAnvil/blob/master/src/main/resources/unit_repair_item.yml)
- [custom_recipes.yml](https://github.com/alexcrea/CustomAnvil/blob/master/src/main/resources/custom_recipes.yml)
---
### Know issue:
There is non known issue, if you find one please report the issue.
### Known issue:
- Custom recipe config GUI is not reloaded on reload config command. (this should not impact a lot of admin, Custom recipe config should be edited manually only in rare occasion)
### Planned:
- Finish the config gui
- Semi manual config update on pluign or minecraft update
- Check unknow registered enchantment & warn
- Warn admin on unsuported minecraft version

View file

@ -4,7 +4,7 @@ plugins {
}
group = "xyz.alexcrea"
version = "1.4.1a"
version = "1.4.3a"
repositories {
mavenCentral()

View file

@ -39,6 +39,7 @@ public enum EnchantmentProperties {
SOUL_SPEED(EnchantmentRarity.VERY_RARE),
SWIFT_SNEAK(EnchantmentRarity.VERY_RARE),
SWEEPING(EnchantmentRarity.RARE),
SWEEPING_EDGE(EnchantmentRarity.RARE),
THORNS(EnchantmentRarity.VERY_RARE),
UNBREAKING(EnchantmentRarity.UNCOMMON),
VANISHING_CURSE(EnchantmentRarity.VERY_RARE);

View file

@ -9,6 +9,7 @@ import io.delilaheve.util.ItemUtil.isEnchantedBook
import io.delilaheve.util.ItemUtil.repairFrom
import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe
import io.delilaheve.util.ItemUtil.unitRepair
import org.bukkit.ChatColor
import org.bukkit.GameMode
import org.bukkit.Material
import org.bukkit.entity.Player
@ -161,7 +162,9 @@ class AnvilEventListener : Listener {
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory): Int {
// Rename item and add renaming cost
resultItem.itemMeta?.let {
if (!it.displayName.contentEquals(inventory.renameText)) {
val displayName = ChatColor.stripColor(it.displayName)
val inventoryName = ChatColor.stripColor(inventory.renameText)
if (!displayName.contentEquals(inventoryName)) {
it.setDisplayName(inventory.renameText)
resultItem.itemMeta = it
return ConfigOptions.itemRenameCost

View file

@ -217,12 +217,32 @@ object ConfigOptions {
* Get the given [enchantment]'s limit
*/
fun enchantLimit(enchantment: Enchantment): Int {
val path = "${ENCHANT_LIMIT_ROOT}.${enchantment.enchantmentName}"
return enchantLimit(enchantment.enchantmentName)
}
/**
* Get the given [enchantmentName]'s limit
*/
private fun enchantLimit(enchantmentName: String): Int {
val default = getDefaultLevel(enchantmentName)
val path = "${ENCHANT_LIMIT_ROOT}.$enchantmentName"
return CustomAnvil.instance
.config
.getInt(path, defaultEnchantLimit)
.getInt(path, default)
.takeIf { it in ENCHANT_LIMIT_RANGE }
?: defaultEnchantLimit
?: default
}
/**
* Get default value if enchantment do not exist on config
*/
private fun getDefaultLevel(enchantmentName: String, // compatibility with 1.20.5. TODO better update system
) : Int {
if(enchantmentName == "sweeping_edge"){
return enchantLimit("sweeping")
}
return defaultEnchantLimit
}
/**
@ -233,15 +253,39 @@ object ConfigOptions {
enchantment: Enchantment,
isFromBook: Boolean
): Int {
return enchantmentValue(enchantment.enchantmentName, isFromBook)
}
/**
* Get the appropriate [enchantmentName]'s value dependent on whether
* it's source [isFromBook]
*/
private fun enchantmentValue(
enchantmentName: String,
isFromBook: Boolean
): Int {
val default = getDefaultValue(enchantmentName, isFromBook)
val typeKey = if (isFromBook) KEY_BOOK else KEY_ITEM
val path = "${ENCHANT_VALUES_ROOT}.${enchantment.enchantmentName}.$typeKey"
val path = "${ENCHANT_VALUES_ROOT}.${enchantmentName}.$typeKey"
return CustomAnvil.instance
.config
.getInt(path, DEFAULT_ENCHANT_VALUE)
.getInt(path, default)
.takeIf { it >= DEFAULT_ENCHANT_VALUE }
?: DEFAULT_ENCHANT_VALUE
}
/**
* Get default value if enchantment do not exist on config
*/
private fun getDefaultValue(enchantmentName: String, // compatibility with 1.20.5. TODO better update system
isFromBook: Boolean) : Int {
if(enchantmentName == "sweeping_edge"){
return enchantmentValue("sweeping", isFromBook)
}
return DEFAULT_ENCHANT_VALUE
}
/**
* Get an array of key of basic config options
*/

View file

@ -30,10 +30,17 @@ object EnchantmentUtil {
) = mutableMapOf<Enchantment, Int>().apply {
putAll(this@combineWith)
other.forEach { (enchantment, level) ->
// Get max level or 255 if player can bypass
val maxLevel = if (player.hasPermission(CustomAnvil.bypassLevelPermission))
{ 255 } else
{ ConfigOptions.enchantLimit(enchantment) }
val cappedLevel = min(level, maxLevel)
// Enchantment not yet in result list
if (!containsKey(enchantment)) {
// Add the enchantment if it doesn't have conflicts, or if player is allowed to bypass enchantment restrictions
this[enchantment] = level
this[enchantment] = cappedLevel
val conflictType =
ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys, mat, enchantment)
if (!player.hasPermission(CustomAnvil.bypassFusePermission) &&
@ -46,6 +53,8 @@ object EnchantmentUtil {
}
// Enchantment already in result list
else {
val oldLevel = this[enchantment]!! // should be true, see the comment above
// ... and they are conflicting
val conflictType =
ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys, mat, enchantment)
@ -57,28 +66,18 @@ object EnchantmentUtil {
}
// ... and they're not the same level
if (this[enchantment] != other[enchantment]) {
val newLevel = max(this[enchantment] ?: 0, other[enchantment] ?: 0)
// apply the greater of the two if non-zero
if (oldLevel != cappedLevel) {
// apply the greater of the two or left one if right is above max
this[enchantment] = max(oldLevel, cappedLevel)
if (newLevel > 0) {
this[enchantment] = newLevel
}
}
// ... and they're the same level
else {
// try to increase the enchantment level by 1
var newLevel = this[enchantment]!! + 1
// Get max level or 255 if player can bypass
val maxLevel = if (player.hasPermission(CustomAnvil.bypassLevelPermission)) {
255
} else {
ConfigOptions.enchantLimit(enchantment)
}
newLevel = min(newLevel, maxLevel)
if (newLevel > 0) {
var newLevel = oldLevel + 1
newLevel = max(min(newLevel, maxLevel), oldLevel)
this[enchantment] = newLevel
}
}
}
}

View file

@ -24,6 +24,12 @@ class EnchantConflictManager {
// Default name for a joining group
private const val DEFAULT_GROUP_NAME = "joinedGroup"
// 1.20.5 compatibility TODO better update system
private val SWEEPING_EDGE_ENCHANT =
Enchantment.getByKey(NamespacedKey.minecraft("sweeping_edge")) ?:
Enchantment.SWEEPING_EDGE
}
private lateinit var conflictMap: HashMap<Enchantment, ArrayList<EnchantConflictGroup>>
@ -76,8 +82,7 @@ class EnchantConflictManager {
// Read and add enchantment to conflict
val enchantList = section.getStringList(ENCH_LIST_PATH)
for (enchantName in enchantList) {
val enchantKey = NamespacedKey.minecraft(enchantName)
val enchant = Enchantment.getByKey(enchantKey)
val enchant = getEnchantByName(enchantName);
if (enchant == null) {
if (!futureUse) {
CustomAnvil.instance.logger.warning("Enchantment $enchantName do not exist but was asked for conflict $conflictName")
@ -95,6 +100,20 @@ class EnchantConflictManager {
return conflict
}
private fun getEnchantByName(enchantName: String): Enchantment? {
// Temporary solution for 1.20.5
when(enchantName){
"sweeping", "sweeping_edge" -> {
return SWEEPING_EDGE_ENCHANT
}
}
val enchantKey = NamespacedKey.minecraft(enchantName)
return Enchantment.getByKey(enchantKey);
}
private fun createConflictObject(
section: ConfigurationSection,
itemManager: ItemGroupManager,

View file

@ -8,9 +8,9 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder
object MetricsUtil {
private const val baseConfigHash = -1592940914
private const val enchantLimitsConfigHash = -1014133828
private const val enchantValuesConfigHash = 1072574774
private const val enchantConflictConfigHash = 1406650190
private const val enchantLimitsConfigHash = -275034280
private const val enchantValuesConfigHash = -17048020
private const val enchantConflictConfigHash = 546475833
private const val itemGroupsConfigHash = 1406650190
private const val unitRepairItemConfigHash = 536871958
private const val customAnvilCraftConfigHash = 0

View file

@ -72,6 +72,7 @@ enchant_limits:
fire_aspect: 2
looting: 3
sweeping: 3
sweeping_edge: 3
efficiency: 5
unbreaking: 3
fortune: 3
@ -208,6 +209,9 @@ enchant_values:
sweeping:
item: 4
book: 2
sweeping_edge:
item: 4
book: 2
thorns:
item: 8
book: 4
@ -223,3 +227,5 @@ debug_log: false
# Whether to show verbose debug logging
debug_log_verbose: false
configVersion: 1.4.3

View file

@ -147,8 +147,8 @@ restriction_soul_speed:
enchantments: [ soul_speed ]
notAffectedGroups: [ enchanted_book, boots ]
restriction_sweeping:
enchantments: [ sweeping ]
restriction_sweeping_edge:
enchantments: [ sweeping, sweeping_edge ]
notAffectedGroups: [ enchanted_book, swords ]
# Do not exist in 1.18, that mean useInFuture will be set to true
@ -156,7 +156,7 @@ restriction_sweeping:
restriction_swift_sneak:
useInFuture: true
enchantments: [ swift_sneak ]
notAffectedGroups: [ enchanted_book, boots ]
notAffectedGroups: [ enchanted_book, leggings ]
restriction_thorns:
enchantments: [ thorns ]

View file

@ -1,7 +1,7 @@
main: io.delilaheve.CustomAnvil
name: CustomAnvil
prefix: "Custom Anvil"
version: 1.4.1a
version: 1.4.3a
description: Allow to customise anvil mechanics
api-version: 1.18
load: POSTWORLD