mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 08:14:00 +02:00
Compare commits
110 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8447233b1e | |||
| eb2e7b3abb | |||
| 7f7f049b7b | |||
| 37e8ca7da9 | |||
| 95d3cf3228 | |||
| 178b372255 | |||
| 106cd53b02 | |||
| 950bad2168 | |||
| bc9cbe0b44 | |||
| 9d616d2fd0 | |||
| f82ccfa07e | |||
| cff94a2c5a | |||
| 4b5133c872 | |||
| 98d359f59f | |||
| 96754fd260 | |||
| b92b762551 | |||
| c064e4b1e1 | |||
| fc33b6fbd5 | |||
| 29e08fe29b | |||
| 151666fd21 | |||
| 593527241a | |||
| 3578322686 | |||
| 12ec4e1f54 | |||
| b0f32fdba2 | |||
| d82bd9b22c | |||
| 380b0de92f | |||
| d91576b0de | |||
| 2f9d25bfe9 | |||
| 49b0054eca | |||
| 2efb6e55e2 | |||
| d679cd73f9 | |||
| 9f06f708f5 | |||
| 31fa3d38b7 | |||
| bf4395ba3f | |||
| 2768c0a0dc | |||
| f0d53a6ffa | |||
| d0078e528d | |||
| edceba879f | |||
| 106bc724a1 | |||
| e6293be1c6 | |||
| 7a705f3bfc | |||
| df92b4bf91 | |||
| bf8144ad06 | |||
| 2d31a7f5a8 | |||
| 3992ce1662 | |||
| 7aac325c70 | |||
| 171a8cad6d | |||
| fb27ad2e55 | |||
| 1b3447d041 | |||
| ac9f492125 | |||
| 1660250ee1 | |||
| 856c1e08bd | |||
| 2c3e43cb84 | |||
| d67380da1a | |||
| b18cf1fd59 | |||
| bf926fb159 | |||
| 21087b89e0 | |||
| a392702df2 | |||
| 5265d81176 | |||
| 91d2cce8cc | |||
| 31f9e7e281 | |||
| 05951d0ace | |||
| 65bf82a239 | |||
| 90cc758e88 | |||
| d926b5001e | |||
| 809dc3488b | |||
| 3594cf72af | |||
| 2070f8fd68 | |||
| 68f63a8ec7 | |||
| c703dc68f9 | |||
| 36030c598b | |||
| a6cdd79750 | |||
| 440b2b2741 | |||
| 41a62d810a | |||
| 459e3351fd | |||
| e00c5e8b47 | |||
| 638df714fd | |||
| 190f334656 | |||
| 8141232c46 | |||
| a1984ad5b9 | |||
| f5343440e4 | |||
| 55f6b94ba9 | |||
| 24db259435 | |||
| d867ca6c85 | |||
| 1b86996317 | |||
| bce43649bc | |||
| 12bfcb75ce | |||
| e30f09120d | |||
| b42fb42d83 | |||
| daa1c6171f | |||
| d4e94872d8 | |||
| 7612eac765 | |||
|
|
1a71086327 | ||
| 45fe037a92 | |||
| d061bfc6f4 | |||
| 889d452466 | |||
| 7fbf68dff3 | |||
| f520d5e3db | |||
| e5167971f4 | |||
| 3d50e0ec82 | |||
| 60ebdbf107 | |||
| f3c6526967 | |||
| 8ded2ae9c6 | |||
| f0d2f07703 | |||
| 26469982b2 | |||
| 882e50e449 | |||
| c96dd7d308 | |||
| f59071f504 | |||
| 6afe51acca | |||
| 6a4c861eab |
125 changed files with 3325 additions and 1198 deletions
24
.github/workflows/gradle.yml
vendored
24
.github/workflows/gradle.yml
vendored
|
|
@ -25,6 +25,10 @@ jobs:
|
|||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
MODRINTH_VERSIONS: '["1.18.x", "1.19.x", "1.20.x", "1.21.x", "26.1.x", "26.2.x"]'
|
||||
MODRINTH_PLATFORMS: '["spigot", "paper", "purpur", "folia"]'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDKs
|
||||
|
|
@ -66,19 +70,6 @@ jobs:
|
|||
if: ${{ github.event_name != 'release' && success() }}
|
||||
run: echo "SMALL_COMMIT_HASH=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_ENV
|
||||
|
||||
- name: Prepare release env variable
|
||||
if: ${{ github.event_name == 'release' && success() }}
|
||||
run: |
|
||||
echo "RELEASE_CHANGELOG<<EOF" >> $GITHUB_ENV
|
||||
echo "${{ github.event.release.body || '' }}" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "IS_GITHUB_PRERELEASE=${{ github.event.release.prerelease }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Prepare publish env variable
|
||||
run: |
|
||||
echo MODRINTH_VERSIONS='["1.18.x", "1.19.x", "1.20.x", "1.21.x"]' >> $GITHUB_ENV
|
||||
echo MODRINTH_PLATFORMS='["spigot", "paper", "purpur", "folia"]' >> $GITHUB_ENV
|
||||
|
||||
- name: Build with Gradle Wrapper
|
||||
run: ./gradlew build --parallel --stacktrace
|
||||
|
||||
|
|
@ -128,6 +119,7 @@ jobs:
|
|||
if: ${{ (github.event_name != 'release' || github.event_name != 'push') && github.repository_owner == 'alexcrea' && success() }}
|
||||
env:
|
||||
HANGAR_API_TOKEN: ${{ secrets.HANGAR_API_TOKEN }}
|
||||
RELEASE_CHANGELOG: ${{ github.event.release.body }}
|
||||
run: ./gradlew publishAllPublicationsToHangar --stacktrace
|
||||
|
||||
- name: Modrinth publish alpha
|
||||
|
|
@ -156,7 +148,7 @@ jobs:
|
|||
game-versions: ${{ env.MODRINTH_VERSIONS }}
|
||||
channel: ${{ github.event.release.prerelease == false && 'release' || 'beta' }}
|
||||
files: build/libs/${{ env.ONLINE_JAR_NAME }}
|
||||
changelog: ${{ env.RELEASE_CHANGELOG }}
|
||||
changelog: ${{ github.event.release.body }}
|
||||
|
||||
- name: Send release note to discord
|
||||
if: ${{ github.event_name == 'release' && github.repository_owner == 'alexcrea' && success() }}
|
||||
|
|
@ -165,7 +157,7 @@ jobs:
|
|||
webhook-url: ${{ secrets.RELEASE_WEBHOOK_URL }}
|
||||
content: |
|
||||
${{ github.event.release.prerelease == false && '<@&1338546156325568642>' || '<@&1352296092989001768>' }}
|
||||
# New ${{ github.event.release.prerelease && 'beta' || '' }} version of custom anvil ! <:CustomAnvil:1262550667986342001>([Modrinth](https://modrinth.com/plugin/customanvil), [Hangar](https://hangar.papermc.io/alexcrea/CustomAnvil) and [GitHub](${{ github.event.release.html_url }}) links)
|
||||
# New ${{ github.event.release.prerelease && 'beta ' || '' }}version of custom anvil ! <:CustomAnvil:1262550667986342001>([Modrinth](https://modrinth.com/plugin/customanvil), [Hangar](https://hangar.papermc.io/alexcrea/CustomAnvil) and [GitHub](${{ github.event.release.html_url }}) links)
|
||||
-# note: automated release. spigot is not uploaded yet.
|
||||
|
||||
${{ env.RELEASE_CHANGELOG }}
|
||||
${{ github.event.release.body }}
|
||||
|
|
|
|||
|
|
@ -6,44 +6,55 @@ This is cannot be fixed on geyser or my side.
|
|||
Here is various plugins that had issues with CustomAnvil
|
||||
where efforts was made for compatibility and should be working right:
|
||||
|
||||
some of them are cool I recommend checking them out !
|
||||
some if not all of them are cool ! I recommend checking them out !
|
||||
|
||||
## Supported By CustomAnvil
|
||||
These plugins have compatibility handled by custom anvil. seek help on custom anvil and do not bother these developers
|
||||
|
||||
#### Enchantment plugins
|
||||
- [ExcellentEnchants](https://www.spigotmc.org/resources/excellentenchants-%E2%AD%90-75-vanilla-like-enchantments.61693/):
|
||||
Use ExcellentEnchants item type
|
||||
#### Enchantment Plugins
|
||||
- [ExcellentEnchants](https://www.spigotmc.org/resources/excellentenchants-%E2%AD%90-75-vanilla-like-enchantments.61693/) by NightExpress:
|
||||
Use ExcellentEnchants item type \
|
||||
Also use ExcellentEnchant max enchant limit
|
||||
|
||||
- [EcoEnchant](https://www.spigotmc.org/resources/ecoenchants-%E2%AD%95-250-enchantments-%E2%9C%85-create-custom-enchants-%E2%9C%A8-essentials-cmi-support.79573/):
|
||||
- [EcoEnchant](https://www.spigotmc.org/resources/ecoenchants-%E2%AD%95-250-enchantments-%E2%9C%85-create-custom-enchants-%E2%9C%A8-essentials-cmi-support.79573/) by Auxilor:
|
||||
Need to use /anvilconfigreload or a server restart to add newly added enchantment.
|
||||
Use EcoEnchant restriction system but new restriction can be added in custom anvil
|
||||
|
||||
- [Enchantment²](https://www.spigotmc.org/resources/enchants-squared-the-enchantsplus-rewrite-custom-enchantments-that-act-like-vanilla-ones.86747/):
|
||||
- [Enchantment²](https://www.spigotmc.org/resources/enchants-squared-the-enchantsplus-rewrite-custom-enchantments-that-act-like-vanilla-ones.86747/) by Athlaeos:
|
||||
Support by Custom Anvil but still experimental. Automatic configuration. Plugin is not actively developed anymore
|
||||
|
||||
#### Anvil Mechanics
|
||||
- [Disenchantment](https://www.spigotmc.org/resources/disenchantment-1-21-1-1-20-6-new-book-splitting-mechanics.110741/)
|
||||
- [SuperEnchants](https://modrinth.com/plugin/superenchants) by Aznos:
|
||||
Use SuperEnchant restrictions system but new restriction can be added in custom anvil
|
||||
|
||||
|
||||
#### Custom Items Plugins
|
||||
Custom Items support is considered unstable. If you find issue please report it !
|
||||
|
||||
- [EcoItem](https://www.spigotmc.org/resources/30-sale%E2%8F%B3-ecoitems-%E2%AD%95-create-custom-items-%E2%9C%85-weapons-armors-tools-charms-%E2%9C%A8-item-levels-rarities.94601/) by Exanthiax:
|
||||
May have some issue. but should partially work I hope
|
||||
|
||||
- [ItemAdder](https://www.spigotmc.org/resources/%E2%9C%A8itemsadder%E2%AD%90emotes-mobs-items-armors-hud-gui-emojis-blocks-wings-hats-liquids.73355/) by LoneDev:
|
||||
Need to fix unit item not working completly correctly as in can't have twice same base item
|
||||
|
||||
#### Anvil Mechanics Plugins
|
||||
- [Disenchantment](https://www.spigotmc.org/resources/disenchantment-1-21-1-1-20-6-new-book-splitting-mechanics.110741/) by H7KZ
|
||||
Partially use Custom Anvil maximum XP settings (>= 6.1.5)
|
||||
|
||||
- [HavenBags](https://www.spigotmc.org/resources/havenbags-shulker-like-player-bound-bags-1-17-1-21-4.110420/)
|
||||
- [HavenBags](https://www.spigotmc.org/resources/havenbags-shulker-like-player-bound-bags-1-17-1-21-4.110420/) by hyperdefined
|
||||
For bag upgrade and skin via anvil. (version >= 1.31.0)
|
||||
|
||||
- [AxPlayerWarp](https://modrinth.com/project/QDJHDKvi)
|
||||
- [AxPlayerWarp](https://modrinth.com/project/QDJHDKvi) by ArtillexStudios
|
||||
For its anvil inventory usage
|
||||
|
||||
- [ToolsStats](https://modrinth.com/project/oBZj9E15)
|
||||
- [ToolsStats](https://modrinth.com/project/oBZj9E15) by Valorless
|
||||
For token application using anvil
|
||||
|
||||
### Known Partially Incompatible
|
||||
- [UberEnchant](https://modrinth.com/plugin/uberenchant)
|
||||
- [UberEnchant](https://modrinth.com/plugin/uberenchant) by coltonj96
|
||||
Anvil handling as they are doing something similar to CustomAnvil.
|
||||
It is by no mean there faults and I recomend checking them out
|
||||
It is by no mean there faults and I recommend checking them out especially if custom anvil do not work for your use case !
|
||||
|
||||
- [SuperEnchant](https://modrinth.com/plugin/superenchants)
|
||||
Reported potential incompatibility
|
||||
|
||||
- [AdvencedEnchantments](https://ae.advancedplugins.net/)
|
||||
- [AdvencedEnchantments](https://ae.advancedplugins.net/) by Advanced Plugins
|
||||
Paid plugin I do not own as I did not get commissioned for support.
|
||||
may be able to use api but cannot test on my side
|
||||
|
||||
|
|
|
|||
21
CREDITS.md
21
CREDITS.md
|
|
@ -5,7 +5,7 @@ Thanks for all the contributors of bukkit, spigot, the paper team and the advent
|
|||
Thanks JetBrain for making IntelliJ
|
||||
|
||||
### Dependencies
|
||||
Here dependencies are used by custom anvil
|
||||
These dependencies (or a modified version of) are used by custom anvil
|
||||
- [IF](https://github.com/stefvanschie/IF) an inventory framework by stefvanschie
|
||||
- [Mockbukkit](https://github.com/MockBukkit/MockBukkit) for unit testing
|
||||
- [CentralPortalPlus](https://github.com/lalakii/central-portal-plus) by lalakii
|
||||
|
|
@ -17,23 +17,18 @@ Here dependencies are used by custom anvil
|
|||
- [ModrinthUpdateChecker](https://github.com/Clickism/ModrinthUpdateChecker) by Clickism and thanks to the modrinth team
|
||||
|
||||
### Compatibility
|
||||
Here is to credits all the author of plugins
|
||||
It partially repeat the the [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md)
|
||||
- Big Thanks for H7KZ for [Disenchantment](https://github.com/H7KZ/Disenchantment)
|
||||
- [Enchantment²](https://www.spigotmc.org/resources/enchants-squared-the-enchantsplus-rewrite-custom-enchantments-that-act-like-vanilla-ones.86747/) by Athlaeos
|
||||
- [EcoEnchant](https://www.spigotmc.org/resources/ecoenchants-%E2%AD%95-250-enchantments-%E2%9C%85-create-custom-enchants-%E2%9C%A8-essentials-cmi-support.79573/) by Auxilor
|
||||
- [ExcellentEnchants](https://www.spigotmc.org/resources/excellentenchants-%E2%AD%90-75-vanilla-like-enchantments.61693/) by NightExpress
|
||||
- [HavenBags](https://www.spigotmc.org/resources/havenbags-shulker-like-player-bound-bags-1-17-1-21-4.110420/) by hyperdefined
|
||||
- [AxPlayerWarp](https://modrinth.com/project/QDJHDKvi) by ArtillexStudios
|
||||
- [ToolsStats](https://modrinth.com/project/oBZj9E15) by Valorless
|
||||
Thanks to all the cool creator making the minecraft plugin's ecosystem works ! \
|
||||
See [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md) for details
|
||||
|
||||
but especially, Big Thanks for H7KZ maker of [Disenchantment](https://github.com/H7KZ/Disenchantment)
|
||||
|
||||
### Special Thanks
|
||||
|
||||
Thanks for Microsoft leading me into using a better operating system \
|
||||
Thanks for all the users trying my plugin for these niche use cases
|
||||
and for reporting issues and giving ideas !
|
||||
, reporting issues and giving ideas !
|
||||
|
||||
Thanks coltonj96 for [UberEnchant](https://modrinth.com/plugin/uberenchant).
|
||||
we may be incompatible with the anvil, but I do think it is a good alternative ! \
|
||||
I wish one day to work on cross compatibiltiy
|
||||
I wish one day to work on cross compatibiltiy \
|
||||
* If custom anvil do not work well for you or your use case give it a try ! *
|
||||
|
||||
|
|
|
|||
31
README.md
31
README.md
|
|
@ -1,8 +1,6 @@
|
|||
# Custom Anvil
|
||||
|
||||
**Custom Anvil** is a plugin that allows server administrators to customize every aspect of the anvil's mechanics.
|
||||
It is expected to work on 1.18 to 1.21.7 minecraft servers running spigot or paper.
|
||||
(the plugin support of 1.16.5 to 1.17.1 is experimental and may encounter issues)
|
||||
|
||||
### Download Locations:
|
||||
|
||||
|
|
@ -16,7 +14,7 @@ the plugin can be downloaded on
|
|||
- Vanilla like default configuration.
|
||||
- Custom enchantment level limit.
|
||||
- Custom anvil recipes.
|
||||
- Custom enchant restrictions (allow unsafe enchantment only for a group of item or create new restriction).
|
||||
- Custom enchant restrictions (allows unsafe enchantment only for a group of item or create new restriction).
|
||||
- Custom items of unit repairs (repair damaged with unit of "material", for example the repair of diamond sword by diamonds).
|
||||
- Custom XP cost for every aspect of the anvil.
|
||||
- Permissions to bypass level limit or enchantment restriction.
|
||||
|
|
@ -25,8 +23,14 @@ the plugin can be downloaded on
|
|||
- Gui to configure the plugin in game.
|
||||
- Support use of color code, hexadecimal color and minimessage for color/decoration
|
||||
- (Experimental) Folia support (gui do not work)
|
||||
- (Experimental) Dialog rename (allows longer rename)
|
||||
- (Experimental) Anvil with monetary cost (using vault) (require dialog rename)
|
||||
|
||||
And more !
|
||||
|
||||
---
|
||||
### Permissions:
|
||||
Note that for most of them you also need to enable feature and in most case enable use of permission for the specfic feature (indicated with `(toggleable)`)
|
||||
```yml
|
||||
# Generic and bypass permissions
|
||||
ca.affected: Player with this permission will be affected by the plugin
|
||||
|
|
@ -44,17 +48,22 @@ ca.config.edit: Allow administrator to edit the plugin's config in game
|
|||
# -----------------------------------------------------------------------------
|
||||
# Permissions related to use of color and minimessage
|
||||
ca.color.code: Allow player to use color code on rename if enabled (toggleable)
|
||||
ca.color.code.[thecode] (for example ca.color.code.a): Allows usage of only certain color code (toggleable)
|
||||
ca.color.hex: Allow player to use hexadecimal color on rename if enabled (toggleable)
|
||||
ca.rename.minimessage: Allow player to use minimessage formating on rename if enabled (toggleable) (only legacy compatible at the time)
|
||||
ca.rename.minimessage: Allow player to use minimessage formating on rename if enabled (toggleable)
|
||||
|
||||
# Permissions related to edition of the lore
|
||||
ca.lore_edit.book: Allow player to edit lore via book and quil if enabled (toggleable)
|
||||
ca.lore_edit.paper: Allow player to edit lore via paper if enabled (toggleable)
|
||||
|
||||
# Others
|
||||
ca.rename.dialog: Allow player to use the rename dialog (toggleable)
|
||||
```
|
||||
|
||||
### Commands
|
||||
|
||||
run `customanvil help` to get information about available commands (need permissions to use them)
|
||||
run `/customanvil help` to get information about available commands \
|
||||
this only show subcommands you have permission for
|
||||
|
||||
### Supported Plugins
|
||||
See the [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md)
|
||||
|
|
@ -63,13 +72,10 @@ See the [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x
|
|||
|
||||
One of the configurations allow displaying price about 40 and removing Too Expensive. \
|
||||
By how the minecraft client work: price above 40 can only be displayed green, even if the player does not own enough experience level.
|
||||
Minecraft version 1.18 to latest marked as supported do not need any ProtocoLib dependency. \
|
||||
spigot version 1.18 to 1.21.11 do not need any ProtocoLib dependency. (26.1.0 or above requires it) \
|
||||
Any recent paper version also are supported for this feature.
|
||||
But you should wait for update for new version containing new enchantable item or new enchantments.
|
||||
Other version need ProtocoLib enabled on your server for this feature. \
|
||||
You can also wait for an update of the plugin to support a newer version.
|
||||
|
||||
Please note that 1.16.5 to 1.17.1 are not officially supported. Run at your own risk.
|
||||
But you should wait for update for new version containing new enchantable item or new enchantments if any of this got added.
|
||||
Else it is, likely, fine to use the current version you are ussing on a new paper version
|
||||
|
||||
### For custom enchantment plugin developers
|
||||
For information about the API, please refer to [the Wiki](https://github.com/alexcrea/CustomAnvil/wiki) \
|
||||
|
|
@ -100,3 +106,6 @@ Credits and thanks can be seen [here](https://github.com/alexcrea/CustomAnvil/bl
|
|||
|
||||
### Known issue:
|
||||
Most unknown registered enchantments (by unsupported custom enchantment plugin & datapacks) will not have restriction by default. Planned but no eta.
|
||||
|
||||
### Do you need help with the plugin, or have any issue or suggestion?
|
||||
You can ask on the discussion page, create a [GitHub issue](https://github.com/alexcrea/CustomAnvil/issues) or join my [discord](https://discord.gg/KHUNsUfRYJ)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|||
import java.io.ByteArrayOutputStream
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "2.1.0"
|
||||
kotlin("jvm") version "2.3.0"
|
||||
java
|
||||
id("org.jetbrains.dokka").version("1.9.20")
|
||||
id("com.gradleup.shadow").version("9.3.0")
|
||||
|
|
@ -22,7 +22,7 @@ plugins {
|
|||
}
|
||||
|
||||
group = "xyz.alexcrea"
|
||||
version = "1.16.1"
|
||||
version = "1.17.5"
|
||||
|
||||
val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null
|
||||
val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true"
|
||||
|
|
@ -37,11 +37,17 @@ repositories {
|
|||
// ExcellentEnchants
|
||||
maven(url = "https://repo.nightexpressdev.com/releases")
|
||||
|
||||
// for fast stats
|
||||
// ItemsAdder
|
||||
maven(url = "https://maven.devs.beer/")
|
||||
|
||||
// For fast stats
|
||||
maven {
|
||||
name = "thenextlvlReleases"
|
||||
url = uri("https://repo.thenextlvl.net/releases")
|
||||
}
|
||||
|
||||
// For vault unlocked
|
||||
maven { url = uri("https://repo.codemc.io/repository/creatorfromhell/") }
|
||||
}
|
||||
|
||||
val reobfNMS = providers.gradleProperty("subprojects.reobfnms")
|
||||
|
|
@ -52,7 +58,7 @@ dependencies {
|
|||
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT")
|
||||
|
||||
// fast stats
|
||||
implementation("dev.faststats.metrics:bukkit:0.16.0")
|
||||
implementation("dev.faststats.metrics:bukkit:0.27.0")
|
||||
|
||||
// minimessage
|
||||
implementation("net.kyori:adventure-text-minimessage:4.25.0")
|
||||
|
|
@ -65,13 +71,17 @@ dependencies {
|
|||
// EnchantsSquaredRewritten
|
||||
compileOnly(files("libs/EnchantsSquared.jar"))
|
||||
|
||||
// EcoEnchants
|
||||
compileOnly("com.willfp:EcoEnchants:12.11.1")
|
||||
// EcoEnchants & item
|
||||
compileOnly("com.willfp:libreforge:4.79.0:all")
|
||||
compileOnly("com.willfp:eco:6.74.5")
|
||||
|
||||
compileOnly("com.willfp:EcoEnchants:12.11.1")
|
||||
compileOnly(project(":impl:LegacyEcoEnchant"))
|
||||
|
||||
compileOnly("com.willfp:EcoItems:5.66.0")
|
||||
|
||||
// ExcellentEnchants
|
||||
implementation(project(":impl:ExcellentEnchant5_3"))
|
||||
implementation(project(":impl:ExcellentEnchant5_4"))
|
||||
compileOnly("su.nightexpress.excellentenchants:Core:5.1.0") {
|
||||
exclude("org.spigotmc")
|
||||
}
|
||||
|
|
@ -90,6 +100,15 @@ dependencies {
|
|||
// AxPlayerWarps
|
||||
compileOnly(files("libs/AxPlayerWarps-1.10.3.jar"))
|
||||
|
||||
// SuperEnchants
|
||||
compileOnly(files("libs/SuperEnchants-4.6.2-all.jar"))
|
||||
|
||||
// ItemsAdder API
|
||||
compileOnly("dev.lone:api-itemsadder:4.0.10")
|
||||
|
||||
// Vault api
|
||||
compileOnly("net.milkbowl.vault:VaultUnlockedAPI:2.16")
|
||||
|
||||
// Include nms
|
||||
implementation(project(":nms:nms-common"))
|
||||
implementation(project(":nms:nms-paper"))
|
||||
|
|
@ -149,7 +168,7 @@ allprojects {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_16)
|
||||
}
|
||||
}
|
||||
|
|
@ -183,7 +202,7 @@ tasks {
|
|||
shadowJar {
|
||||
configureBaseShadow("",
|
||||
arrayOf(
|
||||
"org.jetbrains.kotlin:kotlin-stdlib:2.1.0",
|
||||
"org.jetbrains.kotlin:kotlin-stdlib:2.3.0",
|
||||
"net.kyori:adventure-text-minimessage:4.25.0",
|
||||
"net.kyori:adventure-text-serializer-plain:4.25.0",
|
||||
"net.kyori:adventure-text-serializer-legacy:4.25.0",
|
||||
|
|
|
|||
|
|
@ -77,6 +77,18 @@ allow_color_code: false
|
|||
allow_hexadecimal_color: false
|
||||
allow_minimessage: false
|
||||
|
||||
# This enables restricting color code for player having specific permission
|
||||
# It requires allow_color_code enabled for... obvious reasons
|
||||
#
|
||||
# For example: if player want to use "&aHello" it will be required that the player has
|
||||
# the permission "ca.color.code.a" as he used the color code "a"
|
||||
# In general permission to give to the player is "ca.color.code.[code]"
|
||||
# where [code] is the color code you wish to allow the player
|
||||
#
|
||||
# It is kinda of useless when minimessage is supported as players would be able to bypass
|
||||
# that using the equivalent minimessage tag
|
||||
per_color_code_permission: false
|
||||
|
||||
# Toggle if color should only be applicable if the player a certain permission.
|
||||
#
|
||||
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
||||
|
|
@ -87,10 +99,23 @@ permission_needed_for_color: true
|
|||
# Valid values include 0 to 1000.
|
||||
use_of_color_cost: 0
|
||||
|
||||
# Default limit to apply to any enchants missing from enchant_limits
|
||||
# Dialogue rename menu make use of dialog menu to allow bigger rename
|
||||
# You can also change the maximum size and set it to -1 or less for maximum
|
||||
#
|
||||
# Valid values include 1 to 1000
|
||||
default_limit: 5
|
||||
# This feature only work on paper 1.21.7 or later
|
||||
#
|
||||
# At the moment only english is available for this menu... sorry !
|
||||
#
|
||||
# CustomAnvil use "ca.rename.dialog" when permission
|
||||
enable_dialog_rename: false
|
||||
dialog_rename_max_size: 256
|
||||
permission_needed_for_dialog_rename: false
|
||||
|
||||
# This allows custom anvil to not "guess" the text used for rename but store it in the item
|
||||
# It will make item stackable only and only if it had used the same rename text
|
||||
#
|
||||
# For practical reason. this only work when dialog rename is enabled
|
||||
dialog_rename_keep_user_text: true
|
||||
|
||||
# Override limits for specific enchants
|
||||
#
|
||||
|
|
@ -98,7 +123,8 @@ default_limit: 5
|
|||
#
|
||||
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
||||
#
|
||||
# Valid range of 1 - 255 for each enchantment
|
||||
# Valid range of 0 - 255 for each enchantment
|
||||
# -1 mean keep default
|
||||
enchant_limits:
|
||||
minecraft:aqua_affinity: 1
|
||||
minecraft:binding_curse: 1
|
||||
|
|
@ -404,16 +430,37 @@ lore_edit:
|
|||
allow_hexadecimal_color: false
|
||||
allow_minimessage: true
|
||||
|
||||
# Allow to replace the xp cost by a monetary cost
|
||||
# If enabled it will not be bound to the experience level limits
|
||||
#
|
||||
# It also requires to enable dialog rename (set "enable_dialog_rename: false" a bit higher)
|
||||
# If dialog rename permission is enabled and player do not have the permission merge will fall back to vanilla xp cost
|
||||
#
|
||||
# If you are using custom craft I recommend using Linear Xp Cost with Exact Linear Xp as normal Xp Cost will act "weird"
|
||||
# But Linear Xp will act as 1$ time global multiplier. In other word: like you expect
|
||||
#
|
||||
# As this feature require dialog rename, it can only be enabled starting with paper 1.21.6 and later
|
||||
monetary_cost:
|
||||
enabled: false
|
||||
# If using vault unlocked this allow to specify what currency should be used for anvil usage
|
||||
# default being the default currency
|
||||
currency: default
|
||||
# multiply the anvil cost by a value to allow to have price a big bigger than like 40
|
||||
multipliers:
|
||||
# global multipliers. all usage type will be multiplied by this value
|
||||
global: 1.0
|
||||
# usage specific type. it will only apply for specific xp "reason"
|
||||
enchantment: 1.0 # related to enchantments level
|
||||
repair: 1.0 # for repairing via unit repair (per unit)
|
||||
rename: 1.0 # for renaming the item
|
||||
lore_edit: 1.0 # for changing the lore of the item (only if lore edit is enabled)
|
||||
work_penalty: 1.0 # for work penalty (aka use penalty)
|
||||
recipe: 1.0 # for custom anvil recipe cost
|
||||
|
||||
# Whether to show debug logging
|
||||
debug_log: false
|
||||
|
||||
# Whether to show verbose debug logging
|
||||
debug_log_verbose: false
|
||||
|
||||
# In case something when wrong with CustomAnvil packet manager.
|
||||
# If you see "missing class exception" or similar you may test this.
|
||||
# If enabled and Protocolib absent or disabled "Replace to expensive" will not work.
|
||||
# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled.
|
||||
force_protocolib: false
|
||||
|
||||
configVersion: 1.11.0
|
||||
|
|
|
|||
|
|
@ -79,6 +79,18 @@ allow_color_code: false
|
|||
allow_hexadecimal_color: false
|
||||
allow_minimessage: false
|
||||
|
||||
# This enables restricting color code for player having specific permission
|
||||
# It requires allow_color_code enabled for... obvious reasons
|
||||
#
|
||||
# For example: if player want to use "&aHello" it will be required that the player has
|
||||
# the permission "ca.color.code.a" as he used the color code "a"
|
||||
# In general permission to give to the player is "ca.color.code.[code]"
|
||||
# where [code] is the color code you wish to allow the player
|
||||
#
|
||||
# It is kinda of useless when minimessage is supported as players would be able to bypass
|
||||
# that using the equivalent minimessage tag
|
||||
per_color_code_permission: false
|
||||
|
||||
# Toggle if color should only be applicable if the player a certain permission.
|
||||
#
|
||||
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
||||
|
|
@ -89,10 +101,23 @@ permission_needed_for_color: true
|
|||
# Valid values include 0 to 1000.
|
||||
use_of_color_cost: 0
|
||||
|
||||
# Default limit to apply to any enchants missing from enchant_limits
|
||||
# Dialogue rename menu make use of dialog menu to allow bigger rename
|
||||
# You can also change the maximum size and set it to -1 or less for maximum
|
||||
#
|
||||
# Valid values include 1 to 1000
|
||||
default_limit: 5
|
||||
# This feature only work on paper 1.21.7 or later
|
||||
#
|
||||
# At the moment only english is available for this menu... sorry !
|
||||
#
|
||||
# CustomAnvil use "ca.rename.dialog" when permission
|
||||
enable_dialog_rename: false
|
||||
dialog_rename_max_size: 256
|
||||
permission_needed_for_dialog_rename: false
|
||||
|
||||
# This allows custom anvil to not "guess" the text used for rename but store it in the item
|
||||
# It will make item stackable only and only if it had used the same rename text
|
||||
#
|
||||
# For practical reason. this only work when dialog rename is enabled
|
||||
dialog_rename_keep_user_text: true
|
||||
|
||||
# Override limits for specific enchants
|
||||
#
|
||||
|
|
@ -100,7 +125,8 @@ default_limit: 5
|
|||
#
|
||||
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
||||
#
|
||||
# Valid range of 1 - 255 for each enchantment
|
||||
# Valid range of 0 - 255 for each enchantment
|
||||
# -1 mean keep default
|
||||
enchant_limits:
|
||||
minecraft:aqua_affinity: 1
|
||||
minecraft:binding_curse: 1
|
||||
|
|
@ -424,17 +450,38 @@ lore_edit:
|
|||
allow_hexadecimal_color: false
|
||||
allow_minimessage: true
|
||||
|
||||
# Allow to replace the xp cost by a monetary cost
|
||||
# If enabled it will not be bound to the experience level limits
|
||||
#
|
||||
# It also requires to enable dialog rename (set "enable_dialog_rename: false" a bit higher)
|
||||
# If dialog rename permission is enabled and player do not have the permission merge will fall back to vanilla xp cost
|
||||
#
|
||||
# If you are using custom craft I recommend using Linear Xp Cost with Exact Linear Xp as normal Xp Cost will act "weird"
|
||||
# But Linear Xp will act as 1$ time global multiplier. In other word: like you expect
|
||||
#
|
||||
# As this feature require dialog rename, it can only be enabled starting with paper 1.21.6 and later
|
||||
monetary_cost:
|
||||
enabled: false
|
||||
# If using vault unlocked this allow to specify what currency should be used for anvil usage
|
||||
# default being the default currency
|
||||
currency: default
|
||||
# multiply the anvil cost by a value to allow to have price a big bigger than like 40
|
||||
multipliers:
|
||||
# global multipliers. all usage type will be multiplied by this value
|
||||
global: 1.0
|
||||
# usage specific type. it will only apply for specific xp "reason"
|
||||
enchantment: 1.0 # related to enchantments level
|
||||
repair: 1.0 # for repairing via unit repair (per unit)
|
||||
rename: 1.0 # for renaming the item
|
||||
lore_edit: 1.0 # for changing the lore of the item (only if lore edit is enabled)
|
||||
work_penalty: 1.0 # for work penalty (aka use penalty)
|
||||
recipe: 1.0 # for custom anvil recipe cost
|
||||
|
||||
# Whether to show debug logging
|
||||
debug_log: false
|
||||
|
||||
# Whether to show verbose debug logging
|
||||
debug_log_verbose: false
|
||||
|
||||
# In case something when wrong with CustomAnvil packet manager.
|
||||
# If you see "missing class exception" or similar you may test this.
|
||||
# If enabled and Protocolib absent or disabled "Replace to expensive" will not work.
|
||||
# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled.
|
||||
force_protocolib: false
|
||||
|
||||
configVersion: 1.15.5
|
||||
lowMinecraftVersion: 1.21.11
|
||||
|
|
|
|||
|
|
@ -77,6 +77,18 @@ allow_color_code: false
|
|||
allow_hexadecimal_color: false
|
||||
allow_minimessage: false
|
||||
|
||||
# This enables restricting color code for player having specific permission
|
||||
# It requires allow_color_code enabled for... obvious reasons
|
||||
#
|
||||
# For example: if player want to use "&aHello" it will be required that the player has
|
||||
# the permission "ca.color.code.a" as he used the color code "a"
|
||||
# In general permission to give to the player is "ca.color.code.[code]"
|
||||
# where [code] is the color code you wish to allow the player
|
||||
#
|
||||
# It is kinda of useless when minimessage is supported as players would be able to bypass
|
||||
# that using the equivalent minimessage tag
|
||||
per_color_code_permission: false
|
||||
|
||||
# Toggle if color should only be applicable if the player a certain permission.
|
||||
#
|
||||
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
||||
|
|
@ -87,10 +99,23 @@ permission_needed_for_color: true
|
|||
# Valid values include 0 to 1000.
|
||||
use_of_color_cost: 0
|
||||
|
||||
# Default limit to apply to any enchants missing from enchant_limits
|
||||
# Dialogue rename menu make use of dialog menu to allow bigger rename
|
||||
# You can also change the maximum size and set it to -1 or less for maximum
|
||||
#
|
||||
# Valid values include 1 to 1000
|
||||
default_limit: 5
|
||||
# This feature only work on paper 1.21.7 or later
|
||||
#
|
||||
# At the moment only english is available for this menu... sorry !
|
||||
#
|
||||
# CustomAnvil use "ca.rename.dialog" when permission
|
||||
enable_dialog_rename: false
|
||||
dialog_rename_max_size: 256
|
||||
permission_needed_for_dialog_rename: false
|
||||
|
||||
# This allows custom anvil to not "guess" the text used for rename but store it in the item
|
||||
# It will make item stackable only and only if it had used the same rename text
|
||||
#
|
||||
# For practical reason. this only work when dialog rename is enabled
|
||||
dialog_rename_keep_user_text: true
|
||||
|
||||
# Override limits for specific enchants
|
||||
#
|
||||
|
|
@ -98,7 +123,8 @@ default_limit: 5
|
|||
#
|
||||
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
||||
#
|
||||
# Valid range of 1 - 255 for each enchantment
|
||||
# Valid range of 0 - 255 for each enchantment
|
||||
# -1 mean keep default
|
||||
enchant_limits:
|
||||
minecraft:aqua_affinity: 1
|
||||
minecraft:binding_curse: 1
|
||||
|
|
@ -416,17 +442,38 @@ lore_edit:
|
|||
allow_hexadecimal_color: false
|
||||
allow_minimessage: true
|
||||
|
||||
# Allow to replace the xp cost by a monetary cost
|
||||
# If enabled it will not be bound to the experience level limits
|
||||
#
|
||||
# It also requires to enable dialog rename (set "enable_dialog_rename: false" a bit higher)
|
||||
# If dialog rename permission is enabled and player do not have the permission merge will fall back to vanilla xp cost
|
||||
#
|
||||
# If you are using custom craft I recommend using Linear Xp Cost with Exact Linear Xp as normal Xp Cost will act "weird"
|
||||
# But Linear Xp will act as 1$ time global multiplier. In other word: like you expect
|
||||
#
|
||||
# As this feature require dialog rename, it can only be enabled starting with paper 1.21.6 and later
|
||||
monetary_cost:
|
||||
enabled: false
|
||||
# If using vault unlocked this allow to specify what currency should be used for anvil usage
|
||||
# default being the default currency
|
||||
currency: default
|
||||
# multiply the anvil cost by a value to allow to have price a big bigger than like 40
|
||||
multipliers:
|
||||
# global multipliers. all usage type will be multiplied by this value
|
||||
global: 1.0
|
||||
# usage specific type. it will only apply for specific xp "reason"
|
||||
enchantment: 1.0 # related to enchantments level
|
||||
repair: 1.0 # for repairing via unit repair (per unit)
|
||||
rename: 1.0 # for renaming the item
|
||||
lore_edit: 1.0 # for changing the lore of the item (only if lore edit is enabled)
|
||||
work_penalty: 1.0 # for work penalty (aka use penalty)
|
||||
recipe: 1.0 # for custom anvil recipe cost
|
||||
|
||||
# Whether to show debug logging
|
||||
debug_log: false
|
||||
|
||||
# Whether to show verbose debug logging
|
||||
debug_log_verbose: false
|
||||
|
||||
# In case something when wrong with CustomAnvil packet manager.
|
||||
# If you see "missing class exception" or similar you may test this.
|
||||
# If enabled and Protocolib absent or disabled "Replace to expensive" will not work.
|
||||
# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled.
|
||||
force_protocolib: false
|
||||
|
||||
configVersion: 1.11.0
|
||||
lowMinecraftVersion: 1.21.9
|
||||
|
|
|
|||
|
|
@ -77,6 +77,18 @@ allow_color_code: false
|
|||
allow_hexadecimal_color: false
|
||||
allow_minimessage: false
|
||||
|
||||
# This enables restricting color code for player having specific permission
|
||||
# It requires allow_color_code enabled for... obvious reasons
|
||||
#
|
||||
# For example: if player want to use "&aHello" it will be required that the player has
|
||||
# the permission "ca.color.code.a" as he used the color code "a"
|
||||
# In general permission to give to the player is "ca.color.code.[code]"
|
||||
# where [code] is the color code you wish to allow the player
|
||||
#
|
||||
# It is kinda of useless when minimessage is supported as players would be able to bypass
|
||||
# that using the equivalent minimessage tag
|
||||
per_color_code_permission: false
|
||||
|
||||
# Toggle if color should only be applicable if the player a certain permission.
|
||||
#
|
||||
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
||||
|
|
@ -87,10 +99,23 @@ permission_needed_for_color: true
|
|||
# Valid values include 0 to 1000.
|
||||
use_of_color_cost: 0
|
||||
|
||||
# Default limit to apply to any enchants missing from enchant_limits
|
||||
# Dialogue rename menu make use of dialog menu to allow bigger rename
|
||||
# You can also change the maximum size and set it to -1 or less for maximum
|
||||
#
|
||||
# Valid values include 1 to 1000
|
||||
default_limit: 5
|
||||
# This feature only work on paper 1.21.7 or later
|
||||
#
|
||||
# At the moment only english is available for this menu... sorry !
|
||||
#
|
||||
# CustomAnvil use "ca.rename.dialog" when permission
|
||||
enable_dialog_rename: false
|
||||
dialog_rename_max_size: 256
|
||||
permission_needed_for_dialog_rename: false
|
||||
|
||||
# This allows custom anvil to not "guess" the text used for rename but store it in the item
|
||||
# It will make item stackable only and only if it had used the same rename text
|
||||
#
|
||||
# For practical reason. this only work when dialog rename is enabled
|
||||
dialog_rename_keep_user_text: true
|
||||
|
||||
# Override limits for specific enchants
|
||||
#
|
||||
|
|
@ -98,7 +123,8 @@ default_limit: 5
|
|||
#
|
||||
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
||||
#
|
||||
# Valid range of 1 - 255 for each enchantment
|
||||
# Valid range of 0 - 255 for each enchantment
|
||||
# -1 mean keep default
|
||||
enchant_limits:
|
||||
minecraft:aqua_affinity: 1
|
||||
minecraft:binding_curse: 1
|
||||
|
|
@ -404,16 +430,37 @@ lore_edit:
|
|||
allow_hexadecimal_color: false
|
||||
allow_minimessage: true
|
||||
|
||||
# Allow to replace the xp cost by a monetary cost
|
||||
# If enabled it will not be bound to the experience level limits
|
||||
#
|
||||
# It also requires to enable dialog rename (set "enable_dialog_rename: false" a bit higher)
|
||||
# If dialog rename permission is enabled and player do not have the permission merge will fall back to vanilla xp cost
|
||||
#
|
||||
# If you are using custom craft I recommend using Linear Xp Cost with Exact Linear Xp as normal Xp Cost will act "weird"
|
||||
# But Linear Xp will act as 1$ time global multiplier. In other word: like you expect
|
||||
#
|
||||
# As this feature require dialog rename, it can only be enabled starting with paper 1.21.6 and later
|
||||
monetary_cost:
|
||||
enabled: false
|
||||
# If using vault unlocked this allow to specify what currency should be used for anvil usage
|
||||
# default being the default currency
|
||||
currency: default
|
||||
# multiply the anvil cost by a value to allow to have price a big bigger than like 40
|
||||
multipliers:
|
||||
# global multipliers. all usage type will be multiplied by this value
|
||||
global: 1.0
|
||||
# usage specific type. it will only apply for specific xp "reason"
|
||||
enchantment: 1.0 # related to enchantments level
|
||||
repair: 1.0 # for repairing via unit repair (per unit)
|
||||
rename: 1.0 # for renaming the item
|
||||
lore_edit: 1.0 # for changing the lore of the item (only if lore edit is enabled)
|
||||
work_penalty: 1.0 # for work penalty (aka use penalty)
|
||||
recipe: 1.0 # for custom anvil recipe cost
|
||||
|
||||
# Whether to show debug logging
|
||||
debug_log: false
|
||||
|
||||
# Whether to show verbose debug logging
|
||||
debug_log_verbose: false
|
||||
|
||||
# In case something when wrong with CustomAnvil packet manager.
|
||||
# If you see "missing class exception" or similar you may test this.
|
||||
# If enabled and Protocolib absent or disabled "Replace to expensive" will not work.
|
||||
# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled.
|
||||
force_protocolib: false
|
||||
|
||||
configVersion: 1.11.0
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
### Default Plugin's Configurations
|
||||
From 1.18 to 1.20.6 use [1.18 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.18) \
|
||||
From 1.21 to 1.21.8 use [1.21 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21)
|
||||
From 1.21.9 to 1.21.10 use [1.21.9 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.9)
|
||||
From 1.21 to 1.21.8 use [1.21 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21) \
|
||||
From 1.21.9 to 1.21.10 use [1.21.9 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.9) \
|
||||
From 1.21.11 use [1.21.11 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11)
|
||||
|
|
@ -9,5 +9,5 @@ kotlin.daemon.jvmargs=-Xmx8G
|
|||
subprojects.reobfnms=v1_17R1,v1_18R1,v1_18R2,v1_19R1,v1_19R2,v1_19R3,v1_20R1,v1_20R2,v1_20R3,v1_20R4,v1_21R1,v1_21R2,v1_21R3,v1_21R4,v1_21R5,v1_21R6,v1_21R7
|
||||
|
||||
# list of version for hangar release
|
||||
paperVersion=1.18-1.21.11
|
||||
paperVersion=1.18-26.2
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
group = rootProject.group
|
||||
version = rootProject.version
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "2.1.0"
|
||||
}
|
||||
|
||||
repositories {
|
||||
// ExcellentEnchants
|
||||
maven(url = "https://repo.nightexpressdev.com/releases")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Spigot api
|
||||
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT")
|
||||
|
||||
// Excellent Enchant
|
||||
compileOnly("su.nightexpress.excellentenchants:Core:5.3.0") {
|
||||
exclude("org.spigotmc")
|
||||
}
|
||||
}
|
||||
17
impl/ExcellentEnchant5_4/build.gradle.kts
Normal file
17
impl/ExcellentEnchant5_4/build.gradle.kts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
group = rootProject.group
|
||||
version = rootProject.version
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "2.3.0"
|
||||
}
|
||||
|
||||
repositories {
|
||||
// ExcellentEnchants
|
||||
maven(url = "https://repo.nightexpressdev.com/releases")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Excellent Enchant
|
||||
compileOnly("su.nightexpress.excellentenchants:Core:5.4.3")
|
||||
compileOnly("su.nightexpress.nightcore:main:2.16.2")
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package xyz.alexcrea.cuanvil.dependency.plugins;
|
||||
|
||||
import su.nightexpress.excellentenchants.EnchantsAPI;
|
||||
|
||||
public class ExcellentEnchant5_4EnchantSettings {
|
||||
|
||||
|
||||
public static int anvilLimit() {
|
||||
return EnchantsAPI.getEnchantManager().getSettings().getAnvilEnchantsLimit();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ group = rootProject.group
|
|||
version = rootProject.version
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "2.1.0"
|
||||
kotlin("jvm") version "2.3.0"
|
||||
}
|
||||
|
||||
// Imitate needed class and method to support legacy version of EcoEnchant
|
||||
|
|
|
|||
BIN
libs/SuperEnchants-4.6.2-all.jar
Normal file
BIN
libs/SuperEnchants-4.6.2-all.jar
Normal file
Binary file not shown.
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_16)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package xyz.alexcrea.cuanvil.dialog
|
||||
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||
|
||||
interface AnvilRenameDialog {
|
||||
|
||||
companion object {
|
||||
val PCD_KEEP_RENAME_TEXT_KEY = NamespacedKey.fromString("customanvil:last_rename_text")!!
|
||||
}
|
||||
|
||||
fun canSendDialog(): Boolean
|
||||
|
||||
fun tryShowDialog(player: HumanEntity, event: PrepareAnvilEvent)
|
||||
|
||||
fun closeInventory(player: HumanEntity)
|
||||
|
||||
fun currentText(player: HumanEntity): String?
|
||||
|
||||
fun isOpenFor(player: HumanEntity): Boolean
|
||||
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ dependencies {
|
|||
implementation(project(":nms:nms-common"))
|
||||
|
||||
// Used for nms
|
||||
paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT")
|
||||
paperweight.paperDevBundle("1.21.7-R0.1-SNAPSHOT")
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_18)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ class PaperPacketManager : PacketManagerBase(), PacketManager {
|
|||
sendedAbilities.mayfly = playerAbilities.mayfly
|
||||
sendedAbilities.instabuild = instantBuild
|
||||
sendedAbilities.mayBuild = playerAbilities.mayBuild
|
||||
sendedAbilities.flyingSpeed = playerAbilities.flyingSpeed
|
||||
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
|
||||
sendedAbilities.setFlyingSpeed(playerAbilities.getFlyingSpeed())
|
||||
sendedAbilities.setWalkingSpeed(playerAbilities.getWalkingSpeed())
|
||||
}
|
||||
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
|
||||
nmsPlayer.connection.send(packet)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,236 @@
|
|||
package xyz.alexcrea.cuanvil.dialog
|
||||
|
||||
import io.papermc.paper.dialog.Dialog
|
||||
import io.papermc.paper.registry.data.dialog.ActionButton
|
||||
import io.papermc.paper.registry.data.dialog.DialogBase
|
||||
import io.papermc.paper.registry.data.dialog.action.DialogAction
|
||||
import io.papermc.paper.registry.data.dialog.body.DialogBody
|
||||
import io.papermc.paper.registry.data.dialog.input.DialogInput
|
||||
import io.papermc.paper.registry.data.dialog.type.DialogType
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask
|
||||
import net.kyori.adventure.text.Component
|
||||
import net.kyori.adventure.text.event.ClickCallback
|
||||
import net.kyori.adventure.text.format.TextColor
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer
|
||||
import net.minecraft.world.inventory.AnvilMenu
|
||||
import org.bukkit.craftbukkit.event.CraftEventFactory
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView
|
||||
import org.bukkit.craftbukkit.inventory.view.CraftAnvilView
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||
import org.bukkit.inventory.InventoryView
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
import org.bukkit.plugin.Plugin
|
||||
import java.util.*
|
||||
import java.util.function.BiFunction
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Supplier
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
class AnvilRenameDialogImpl(
|
||||
val fromFormated: BiFunction<HumanEntity, Component?, String?>,
|
||||
val keepUserPreviousDialog: Supplier<Boolean>,
|
||||
val maxLength: Supplier<Int>,
|
||||
val plugin: Plugin,
|
||||
) : AnvilRenameDialog {
|
||||
|
||||
companion object {
|
||||
private const val RENAME_TEXT_KEY = "rename"
|
||||
|
||||
private const val MAX_WIDTH = 512
|
||||
|
||||
private val PLAIN_TEXT_SERIALIZER = PlainTextComponentSerializer.plainText()
|
||||
|
||||
// Need to be able to translate it later !
|
||||
private val USER_FACING_RENAME_TITLE = Component.text("Rename Your Item")
|
||||
private val USER_FACING_WARNING = Component.text(
|
||||
"Note that the repair text will appear blank after Confirm\n" +
|
||||
"But the name will be correctly applied"
|
||||
)
|
||||
private val USER_FACING_CONFIRM = Component.text("Confirm").color(TextColor.fromHexString("#40FF40"))
|
||||
private val USER_FACING_CANCEL = Component.text("Cancel").color(TextColor.fromHexString("#FF4040"))
|
||||
|
||||
fun itemDefaultName(item: ItemStack?): String? {
|
||||
return PLAIN_TEXT_SERIALIZER.serializeOrNull(item?.effectiveName())
|
||||
}
|
||||
}
|
||||
|
||||
private val lastNames = HashMap<UUID, String>()
|
||||
private val lastRenames = HashMap<UUID, String>()
|
||||
|
||||
|
||||
private val lastLeftItem = HashMap<UUID, String>()
|
||||
private val runTaskMap = HashMap<UUID, ScheduledTask>()
|
||||
|
||||
// For monetary cost
|
||||
val hasUiOpen = HashSet<UUID>()
|
||||
|
||||
private val containerField = CraftInventoryView::class.java.getDeclaredField("container")
|
||||
|
||||
init {
|
||||
containerField.setAccessible(true)
|
||||
}
|
||||
|
||||
override fun canSendDialog(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun makeDialog(playerID: UUID, initial: String?, callback: Consumer<String?>): Dialog {
|
||||
val maxLength = this.maxLength.get()
|
||||
val initialFinal = initial?.take(maxLength)
|
||||
|
||||
val baseBuilder = DialogBase.builder(USER_FACING_RENAME_TITLE)
|
||||
.canCloseWithEscape(true)
|
||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
||||
.inputs(
|
||||
listOf(
|
||||
DialogInput.text(RENAME_TEXT_KEY, Component.text("Rename text"))
|
||||
.maxLength(maxLength)
|
||||
.initial(initialFinal ?: "")
|
||||
.labelVisible(false)
|
||||
.width(MAX_WIDTH)
|
||||
.build(),
|
||||
),
|
||||
)
|
||||
baseBuilder.body(
|
||||
listOf(
|
||||
DialogBody.plainMessage(USER_FACING_WARNING, MAX_WIDTH)
|
||||
)
|
||||
)
|
||||
|
||||
return Dialog.create { builder ->
|
||||
builder.empty()
|
||||
.base(baseBuilder.build())
|
||||
.type(
|
||||
DialogType.confirmation(
|
||||
ActionButton.builder(USER_FACING_CONFIRM)
|
||||
.action(DialogAction.customClick({ response, _ ->
|
||||
hasUiOpen.remove(playerID)
|
||||
val text = response.getText(RENAME_TEXT_KEY)!!
|
||||
callback.accept(text)
|
||||
}, ClickCallback.Options.builder().build()))
|
||||
.build(),
|
||||
ActionButton.builder(USER_FACING_CANCEL)
|
||||
.action(DialogAction.customClick({ response, _ ->
|
||||
hasUiOpen.remove(playerID)
|
||||
}, ClickCallback.Options.builder().build()))
|
||||
.build(),
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setResult(player: HumanEntity, view: InventoryView, result: String?) {
|
||||
val defaultName = itemDefaultName(view.getItem(0))
|
||||
if (defaultName == result) {
|
||||
setName(player, view, "", null)
|
||||
if (defaultName != null) lastNames[player.uniqueId] = defaultName
|
||||
} else setName(player, view, result, result)
|
||||
}
|
||||
|
||||
private fun setName(player: HumanEntity, view: InventoryView, name: String?, rename: String?) {
|
||||
val menu = (containerField.get(view) as AnvilMenu)
|
||||
val isSameName = menu.itemName == name
|
||||
menu.itemName = rename
|
||||
|
||||
if (name == null)
|
||||
lastNames.remove(player.uniqueId)
|
||||
else
|
||||
lastNames[player.uniqueId] = name
|
||||
|
||||
if (rename == null)
|
||||
lastRenames.remove(player.uniqueId)
|
||||
else
|
||||
lastRenames[player.uniqueId] = rename
|
||||
|
||||
if (!isSameName)
|
||||
CraftEventFactory.callPrepareResultEvent(menu, 2);
|
||||
}
|
||||
|
||||
private fun nameFromItem(player: HumanEntity, item: ItemStack?): String? {
|
||||
// Already has text
|
||||
if (item?.hasItemMeta() != true || !item.itemMeta.hasCustomName())
|
||||
return PLAIN_TEXT_SERIALIZER.serializeOrNull(item?.effectiveName())
|
||||
|
||||
if (keepUserPreviousDialog.get() && item.hasItemMeta()) {
|
||||
val lastName = item.itemMeta.persistentDataContainer.get(
|
||||
AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY,
|
||||
PersistentDataType.STRING
|
||||
)
|
||||
|
||||
if (lastName != null) return lastName
|
||||
}
|
||||
|
||||
return fromFormated.apply(player, item.effectiveName())
|
||||
}
|
||||
|
||||
private fun tryShowDialogScheduled(player: HumanEntity, event: PrepareAnvilEvent) {
|
||||
val view = event.view
|
||||
if (view !is CraftAnvilView) return
|
||||
|
||||
val renameText = view.renameText
|
||||
val leftItem = view.getItem(0)
|
||||
val leftItemStr = leftItem?.toString()
|
||||
|
||||
val lastName = lastNames.getOrDefault(player.uniqueId, null)
|
||||
val lastRename = lastRenames.getOrDefault(player.uniqueId, null)
|
||||
|
||||
if (lastLeftItem.getOrDefault(player.uniqueId, null) != leftItemStr) {
|
||||
if (leftItemStr == null)
|
||||
lastLeftItem.remove(player.uniqueId)
|
||||
else lastLeftItem[player.uniqueId] = leftItemStr
|
||||
|
||||
setName(player, view, renameText, nameFromItem(player, leftItem))
|
||||
return
|
||||
}
|
||||
|
||||
if (lastName == renameText || lastRename == renameText)
|
||||
return
|
||||
|
||||
if (renameText?.isBlank() == true || renameText == itemDefaultName(leftItem)) {
|
||||
setName(player, view, lastName, lastRename)
|
||||
return
|
||||
}
|
||||
|
||||
val dialog = makeDialog(player.uniqueId, lastRename)
|
||||
{ result -> setResult(player, view, result) }
|
||||
player.showDialog(dialog)
|
||||
|
||||
hasUiOpen.add(player.uniqueId)
|
||||
}
|
||||
|
||||
// We need to wait for a short time as changing item will change the name BEFORE the item change
|
||||
// no guaranty both of them came in the same tick too so let's wait 2 tick....
|
||||
override fun tryShowDialog(player: HumanEntity, event: PrepareAnvilEvent) {
|
||||
runTaskMap.remove(player.uniqueId)?.cancel()
|
||||
|
||||
val task = player.scheduler.runDelayed(
|
||||
plugin,
|
||||
{ _ ->
|
||||
run { tryShowDialogScheduled(player, event) }
|
||||
},
|
||||
{},
|
||||
2
|
||||
)
|
||||
if (task == null) return
|
||||
|
||||
runTaskMap[player.uniqueId] = task
|
||||
}
|
||||
|
||||
override fun closeInventory(player: HumanEntity) {
|
||||
lastNames.remove(player.uniqueId)
|
||||
lastRenames.remove(player.uniqueId)
|
||||
lastLeftItem.remove(player.uniqueId)
|
||||
runTaskMap.remove(player.uniqueId)?.cancel()
|
||||
}
|
||||
|
||||
override fun currentText(player: HumanEntity): String? {
|
||||
return lastNames[player.uniqueId]
|
||||
}
|
||||
|
||||
override fun isOpenFor(player: HumanEntity): Boolean {
|
||||
return hasUiOpen.contains(player.uniqueId)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package xyz.alexcrea.cuanvil.util
|
||||
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.inventory.InventoryView
|
||||
import org.bukkit.plugin.Plugin
|
||||
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
|
||||
import java.util.HashMap
|
||||
import java.util.UUID
|
||||
|
||||
object AnvilTitleUtil {
|
||||
|
||||
private val runTaskMap = HashMap<UUID, ScheduledTask>()
|
||||
|
||||
private fun actualRename(view: InventoryView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog) {
|
||||
runTaskMap.remove(player.uniqueId)
|
||||
if (view.title == name) return
|
||||
|
||||
// We assume rename impl is used
|
||||
if (anvilDialog.isOpenFor(player)) return
|
||||
|
||||
view.title = name
|
||||
}
|
||||
|
||||
// We don't want to rename instantly it is causing issue with rename text
|
||||
// especially as it can "override" current ui when it is rename ui time but rename ui also need some delay
|
||||
fun rename(view: InventoryView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog, plugin: Plugin) {
|
||||
runTaskMap.remove(player.uniqueId)?.cancel()
|
||||
|
||||
val task = player.scheduler.runDelayed(
|
||||
plugin,
|
||||
{ _ ->
|
||||
run { actualRename(view, name, player, anvilDialog) }
|
||||
},
|
||||
{
|
||||
runTaskMap.remove(player.uniqueId)
|
||||
},
|
||||
2
|
||||
)
|
||||
|
||||
if (task == null) return
|
||||
runTaskMap[player.uniqueId] = task
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_16)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_17)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_17)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_17)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_17)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_17)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_18)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_18)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_18)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
package xyz.alexcrea.cuanvil.util
|
||||
|
||||
import org.bukkit.inventory.meta.Damageable
|
||||
|
||||
// I LOVE support of old versions and needing to do modules like that
|
||||
// That truly is my favorite activity
|
||||
// TODO clean this one of legacy removal branch
|
||||
object MaxDamageCheckerUtil {
|
||||
|
||||
/**
|
||||
* @return max damage or int max if not set
|
||||
*/
|
||||
fun getMaxDamage(meta: Damageable): Int {
|
||||
if(!meta.hasMaxDamage()) return Integer.MAX_VALUE
|
||||
return meta.maxDamage
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_21)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_21)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_21)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_21)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_21)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_21)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ tasks.withType<JavaCompile>().configureEach {
|
|||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||
jvmTarget.set(JvmTarget.JVM_21)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,5 +18,5 @@ for (nmsPart in reobfNMS) {
|
|||
// compatibility subprojects
|
||||
include(":impl:LegacyEcoEnchant")
|
||||
findProject(":impl:LegacyEcoEnchant")?.name = "LegacyEcoEnchant"
|
||||
include("impl:ExcellentEnchant5_3")
|
||||
findProject(":impl:ExcellentEnchant5_3")?.name = "ExcellentEnchant5_3"
|
||||
include("impl:ExcellentEnchant5_4")
|
||||
findProject(":impl:ExcellentEnchant5_4")?.name = "ExcellentEnchant5_4"
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package xyz.alexcrea.cuanvil.api;
|
||||
|
||||
import io.delilaheve.CustomAnvil;
|
||||
import io.delilaheve.util.ConfigOptions;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
|
|
@ -180,13 +181,13 @@ public class EnchantmentApi {
|
|||
private static boolean tryWriteDefaultConfig(FileConfiguration defaultConfig, CAEnchantment enchantment, boolean override) {
|
||||
boolean hasChange = false;
|
||||
|
||||
String levelPath = "enchant_limits." + enchantment.getKey();
|
||||
String levelPath = ConfigOptions.ENCHANT_LIMIT_ROOT + "." + enchantment.getKey();
|
||||
if(override || !defaultConfig.isSet(levelPath)){
|
||||
defaultConfig.set(levelPath, enchantment.defaultMaxLevel());
|
||||
hasChange = true;
|
||||
}
|
||||
|
||||
String basePath = "enchant_values." + enchantment.getKey();
|
||||
String basePath = ConfigOptions.ENCHANT_VALUES_ROOT + "." + enchantment.getKey();
|
||||
EnchantmentRarity rarity = enchantment.defaultRarity();
|
||||
|
||||
String itemPath = basePath + ".item";
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package xyz.alexcrea.cuanvil.api;
|
|||
import io.delilaheve.CustomAnvil;
|
||||
import io.delilaheve.util.ConfigOptions;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
|
@ -123,7 +124,7 @@ public class MaterialGroupApi {
|
|||
FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
|
||||
|
||||
String basePath = group.getName() + ".";
|
||||
Set<Material> materialSet = group.getNonGroupInheritedMaterials();
|
||||
Set<NamespacedKey> materialSet = group.getNonGroupInheritedMaterials();
|
||||
Set<AbstractMaterialGroup> groupSet = group.getGroups();
|
||||
|
||||
boolean empty = true;
|
||||
|
|
@ -153,7 +154,7 @@ public class MaterialGroupApi {
|
|||
FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
|
||||
|
||||
String basePath = group.getName() + ".";
|
||||
EnumSet<Material> materials = group.getMaterials();
|
||||
Set<NamespacedKey> materials = group.getMaterials();
|
||||
|
||||
if (materials.isEmpty()) return false;
|
||||
|
||||
|
|
@ -163,8 +164,8 @@ public class MaterialGroupApi {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static List<String> materialSetToStringList(@NotNull Set<Material> materials) {
|
||||
return materials.stream().map(material -> material.getKey().getKey().toLowerCase()).toList();
|
||||
public static List<String> materialSetToStringList(@NotNull Set<NamespacedKey> materials) {
|
||||
return materials.stream().map(NamespacedKey::toString).toList();
|
||||
}
|
||||
|
||||
public static List<String> materialGroupSetToStringList(@NotNull Set<AbstractMaterialGroup> groups) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
* Most of the time you would likely need {@link CAPreAnvilBypassEvent} or {@link CAEarlyPreAnvilBypassEvent}
|
||||
* for this event to be useful.
|
||||
* <p>
|
||||
* There is also {@link CATreatAnvilResultEvent} that may be better for some use case.
|
||||
* There is also {@link CATreatAnvilResult2Event} that may be better for some use case.
|
||||
*/
|
||||
public class CAClickResultBypassEvent extends Event implements Cancellable {
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
* <p>
|
||||
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
|
||||
* <p>
|
||||
* It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
|
||||
* It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResult2Event}
|
||||
* as your use case may be more prone to use theses.
|
||||
*/
|
||||
public class CAEarlyPreAnvilBypassEvent extends Event implements Cancellable {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
* <p>
|
||||
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
|
||||
* <p>
|
||||
* It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
|
||||
* It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResult2Event}
|
||||
* as your use case may be more prone to use theses.
|
||||
*/
|
||||
public class CAPreAnvilBypassEvent extends Event implements Cancellable {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,196 @@
|
|||
package xyz.alexcrea.cuanvil.api.event.listener;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilCost;
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
|
||||
|
||||
/**
|
||||
* Called after custom anvil processed the click on the result on the anvil inventory.
|
||||
* This event should be used to modify the result of an anvil use.
|
||||
* <p>
|
||||
* You may also want to check {@link CAClickResultBypassEvent},
|
||||
* {@link CAPreAnvilBypassEvent}
|
||||
* and {@link CAEarlyPreAnvilBypassEvent} for your use case
|
||||
* <p>
|
||||
* A null result will cancel this event
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class CATreatAnvilResult2Event extends Event {
|
||||
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final InventoryView view;
|
||||
|
||||
private final AnvilUseType useType;
|
||||
|
||||
@Nullable
|
||||
private final ItemStack left;
|
||||
@Nullable
|
||||
private final ItemStack right;
|
||||
|
||||
@Nullable
|
||||
private ItemStack result;
|
||||
|
||||
private final AnvilCost cost;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public CATreatAnvilResult2Event(
|
||||
@NotNull InventoryView view,
|
||||
Inventory inv,
|
||||
AnvilUseType useType,
|
||||
@Nullable ItemStack result,
|
||||
AnvilCost cost) {
|
||||
this.view = view;
|
||||
this.useType = useType;
|
||||
|
||||
this.left = inv.getItem(0); // TODO use view here
|
||||
this.right = inv.getItem(1);
|
||||
this.result = result;
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bukkit inventory view.
|
||||
* <p>
|
||||
* Temporarily marked as internal as it will get changed to anvil view on legacy removal
|
||||
* so signature will change
|
||||
*
|
||||
* @return The inventory view of this event.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public @NotNull InventoryView getView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the type of use source of the result.
|
||||
*
|
||||
* @return The craft use type.
|
||||
*/
|
||||
public AnvilUseType getUseType() {
|
||||
return useType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the left item of the anvil use
|
||||
*
|
||||
* @return the left item
|
||||
*/
|
||||
public @Nullable ItemStack getLeftItem() {
|
||||
return left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the right item of the anvil use
|
||||
*
|
||||
* @return the right item
|
||||
*/
|
||||
public @Nullable ItemStack getRightItem() {
|
||||
return right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current result
|
||||
* <p>
|
||||
* note that it will not be null unless another listener previously set it to null.
|
||||
*
|
||||
* @return The current result.
|
||||
*/
|
||||
public @Nullable ItemStack getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current result
|
||||
* <p>
|
||||
* note that a null result will cancel this anvil use.
|
||||
*
|
||||
* @param result The new result
|
||||
*/
|
||||
public void setResult(@Nullable ItemStack result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the level cost displayed on the anvil.
|
||||
* <h3>Important note:</h3>
|
||||
* the final price are re calculated on click for the following use case:
|
||||
* <ul>
|
||||
* <li>Custom craft</li>
|
||||
* <li>Unit repair</li>
|
||||
* <li>Lore edit</li>
|
||||
* </ul>
|
||||
* This value will be used as final price for:
|
||||
* <li>Item merge</li>
|
||||
* <li>Item rename</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return The current cost.
|
||||
* @deprecated use #{@link #getCost()} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.17.0")
|
||||
public int getLevelCost() {
|
||||
return cost.asXpCost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the level cost displayed on the anvil.
|
||||
* <h3>Important note:</h3>
|
||||
* the final price are re calculated on click for the following use case:
|
||||
* <ul>
|
||||
* <li>Custom craft</li>
|
||||
* <li>Unit repair</li>
|
||||
* <li>Lore edit</li>
|
||||
* </ul>
|
||||
* This value will be used as final price for:
|
||||
* <li>Item merge</li>
|
||||
* <li>Item rename</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param levelCost The new cost.
|
||||
* @deprecated use #{@link #getCost()} and set value on this instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.17.0")
|
||||
public void setLevelCost(int levelCost) {
|
||||
cost.setGeneric(levelCost - cost.getGeneric() - cost.asXpCost());
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow access to the current cost of the event
|
||||
* Note that modifying this object will change the event resulting cost
|
||||
*
|
||||
* <h3>Important note:</h3>
|
||||
* the final price are re calculated on click for the following use case:
|
||||
* <ul>
|
||||
* <li>Custom craft</li>
|
||||
* <li>Unit repair</li>
|
||||
* <li>Lore edit</li>
|
||||
* </ul>
|
||||
* This value will be used as final price for:
|
||||
* <li>Item merge</li>
|
||||
* <li>Item rename</li>
|
||||
*
|
||||
* @return the current anvil cost
|
||||
*/
|
||||
public AnvilCost getCost() {
|
||||
return cost;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,8 @@ import org.bukkit.event.inventory.PrepareAnvilEvent;
|
|||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import xyz.alexcrea.cuanvil.util.AnvilUseType;
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilCost;
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
|
||||
|
||||
/**
|
||||
* Called after custom anvil processed the click on the result on the anvil inventory.
|
||||
|
|
@ -17,8 +18,12 @@ import xyz.alexcrea.cuanvil.util.AnvilUseType;
|
|||
* and {@link CAEarlyPreAnvilBypassEvent} for your use case
|
||||
* <p>
|
||||
* A null result will cancel this pre anvil event
|
||||
*
|
||||
* @deprecated Prepare anvil Event cannot be provided as it can be called on result and therefore not have prepared anvil event
|
||||
* use {@link CATreatAnvilResult2Event} instead
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Deprecated(forRemoval = true, since = "1.17.0")
|
||||
public class CATreatAnvilResultEvent extends Event {
|
||||
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
|
|
@ -40,13 +45,13 @@ public class CATreatAnvilResultEvent extends Event {
|
|||
@Nullable
|
||||
private ItemStack result;
|
||||
|
||||
private int levelCost;
|
||||
private final AnvilCost cost;
|
||||
|
||||
public CATreatAnvilResultEvent(@NotNull PrepareAnvilEvent event, AnvilUseType useType, @Nullable ItemStack result, int levelCost) {
|
||||
public CATreatAnvilResultEvent(@NotNull PrepareAnvilEvent event, AnvilUseType useType, @Nullable ItemStack result, AnvilCost cost) {
|
||||
this.event = event;
|
||||
this.useType = useType;
|
||||
this.result = result;
|
||||
this.levelCost = levelCost;
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -104,9 +109,11 @@ public class CATreatAnvilResultEvent extends Event {
|
|||
* </ul>
|
||||
*
|
||||
* @return The current cost.
|
||||
* @deprecated use #{@link #getCost()} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.17.0")
|
||||
public int getLevelCost() {
|
||||
return levelCost;
|
||||
return cost.asXpCost();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -124,8 +131,32 @@ public class CATreatAnvilResultEvent extends Event {
|
|||
* </ul>
|
||||
*
|
||||
* @param levelCost The new cost.
|
||||
* @deprecated use #{@link #getCost()} and set value on this instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.17.0")
|
||||
public void setLevelCost(int levelCost) {
|
||||
this.levelCost = levelCost;
|
||||
cost.setGeneric(levelCost - cost.getGeneric() - cost.asXpCost());
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow access to the current cost of the event
|
||||
* Note that modifying this object will change the event resulting cost
|
||||
*
|
||||
* <h3>Important note:</h3>
|
||||
* the final price are re calculated on click for the following use case:
|
||||
* <ul>
|
||||
* <li>Custom craft</li>
|
||||
* <li>Unit repair</li>
|
||||
* <li>Lore edit</li>
|
||||
* </ul>
|
||||
* This value will be used as final price for:
|
||||
* <li>Item merge</li>
|
||||
* <li>Item rename</li>
|
||||
*
|
||||
* @return the current anvil cost
|
||||
*/
|
||||
public AnvilCost getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package xyz.alexcrea.cuanvil.config;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import xyz.alexcrea.cuanvil.util.AnvilUseType;
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package xyz.alexcrea.cuanvil.enchant;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
|
@ -11,24 +12,23 @@ public interface AdditionalTestEnchantment {
|
|||
/**
|
||||
* Test if the provided enchantments can be compatible with this enchantment. only non-Custom Anvil conflict.
|
||||
* @param enchantments Immutable map of validated enchantments for the item.
|
||||
* @param itemMat Material of the tested item.
|
||||
* @param itemType Material namespaced key of the tested item.
|
||||
* @return If there is a conflict with the enchantments.
|
||||
*/
|
||||
boolean isEnchantConflict(
|
||||
@NotNull Map<CAEnchantment, Integer> enchantments,
|
||||
@NotNull Material itemMat);
|
||||
|
||||
@NotNull NamespacedKey itemType);
|
||||
|
||||
/**
|
||||
* Test if the provided item can be compatible with this enchantment. only non-Custom Anvil conflict.
|
||||
* @param enchantments Immutable map of validated enchantments for the item.
|
||||
* @param itemMat Material of the tested item.
|
||||
* @param itemType Material namespaced key of the tested item.
|
||||
* @param item Provide a new instance of the used item stack with the partial enchantment applied.
|
||||
* @return If there is a conflict with the enchantment and the item.
|
||||
*/
|
||||
boolean isItemConflict(
|
||||
@NotNull Map<CAEnchantment, Integer> enchantments,
|
||||
@NotNull Material itemMat,
|
||||
@NotNull NamespacedKey itemType,
|
||||
@NotNull ItemStack item);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
package xyz.alexcrea.cuanvil.enchant.bulk;
|
||||
|
||||
import com.maddoxh.superEnchants.items.EnchantApplicator;
|
||||
import com.maddoxh.superEnchants.items.EnchantReader;
|
||||
import io.delilaheve.CustomAnvil;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.api.EnchantmentApi;
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SuperEnchantBulkOperation implements BulkGetEnchantOperation, BulkCleanEnchantOperation {
|
||||
|
||||
private Plugin plugin;
|
||||
public SuperEnchantBulkOperation(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bulkGet(@NotNull Map<CAEnchantment, Integer> enchantmentMap, @NotNull ItemStack item, @NotNull ItemMeta meta) {
|
||||
EnchantReader.INSTANCE.readEnchants(item).forEach((ench, level) -> {
|
||||
var enchantment = EnchantmentApi.getByKey(NamespacedKey.fromString(ench, plugin));
|
||||
if(enchantment == null) {
|
||||
CustomAnvil.log("Enchantment " + ench + " not found in custom anvil");
|
||||
return;
|
||||
}
|
||||
|
||||
enchantmentMap.put(enchantment, level);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bulkClear(@NotNull ItemStack item) {
|
||||
EnchantApplicator.INSTANCE.clearAllCustomEnchants(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bulkClear(@NotNull ItemStack item, @NotNull ItemMeta meta) {
|
||||
// item meta is not preferred for enchantment squared clear
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
||||
|
|
@ -39,7 +40,7 @@ public class CAEEPreV5Enchantment extends CABukkitEnchantment implements Additio
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||
if (!definition.hasConflicts()) return false;
|
||||
|
||||
Set<String> conflicts = definition.getConflicts();
|
||||
|
|
@ -52,8 +53,8 @@ public class CAEEPreV5Enchantment extends CABukkitEnchantment implements Additio
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat, @NotNull ItemStack item) {
|
||||
if (Material.ENCHANTED_BOOK.equals(itemMat)) return false;
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) {
|
||||
if (Material.ENCHANTED_BOOK.getKey().equals(itemType)) return false;
|
||||
|
||||
return !definition.getSupportedItems().is(item);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
||||
|
|
@ -27,7 +28,7 @@ public class CAEEV5Enchantment extends CABukkitEnchantment implements Additional
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||
if (!hasConflicts()) return false;
|
||||
|
||||
Set<String> conflicts = getExclusiveSet();
|
||||
|
|
@ -41,10 +42,10 @@ public class CAEEV5Enchantment extends CABukkitEnchantment implements Additional
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat, @NotNull ItemStack item) {
|
||||
if (Material.ENCHANTED_BOOK.equals(itemMat)) return false;
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) {
|
||||
if (Material.ENCHANTED_BOOK.getKey().equals(itemType)) return false;
|
||||
|
||||
String key = itemMat.getKey().getKey();
|
||||
String key = itemType.getKey();
|
||||
ItemSet primary = eeenchantment.getPrimaryItems();
|
||||
if (primary.getMaterials().contains(key)) return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
||||
import xyz.alexcrea.cuanvil.dependency.plugins.ExcellentEnchant5_4EnchantSettings;
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class CAEEV5_4Enchantment extends CAEEV5Enchantment {
|
||||
|
||||
public CAEEV5_4Enchantment(@NotNull CustomEnchantment enchantment) {
|
||||
super(enchantment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemMat) {
|
||||
if(super.isEnchantConflict(enchantments, itemMat)) return true;
|
||||
|
||||
var limit = ExcellentEnchant5_4EnchantSettings.anvilLimit();
|
||||
var count = enchantments.keySet().stream()
|
||||
.filter(key -> key instanceof CAEEV5_4Enchantment)
|
||||
.count();
|
||||
|
||||
return count > limit;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.willfp.ecoenchants.enchant.EcoEnchant;
|
|||
import com.willfp.ecoenchants.target.EnchantmentTarget;
|
||||
import com.willfp.ecoenchants.type.EnchantmentType;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
|
||||
|
|
@ -23,7 +24,7 @@ public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestE
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||
if (enchantments.isEmpty()) return false;
|
||||
|
||||
// Check if there is only self
|
||||
|
|
@ -61,9 +62,9 @@ public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestE
|
|||
|
||||
@Override
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments,
|
||||
@NotNull Material itemMat,
|
||||
@NotNull NamespacedKey itemType,
|
||||
@NotNull ItemStack item) {
|
||||
if (Material.ENCHANTED_BOOK.equals(itemMat)) {
|
||||
if (Material.ENCHANTED_BOOK.getKey().equals(itemType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
|
@ -24,12 +25,12 @@ public class CAIncompatibleAllEnchant extends CABukkitEnchantment implements Add
|
|||
|
||||
|
||||
@Override
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||
return !enchantments.isEmpty() && !(enchantments.size() == 1 && enchantments.containsKey(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat, @NotNull ItemStack item) {
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
|
|
@ -22,7 +23,7 @@ public class CALegacyEEEnchantment extends CABukkitEnchantment implements Additi
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||
if (!eeenchantment.hasConflicts()) return false;
|
||||
|
||||
Set<String> conflicts = eeenchantment.getConflicts();
|
||||
|
|
@ -35,8 +36,8 @@ public class CALegacyEEEnchantment extends CABukkitEnchantment implements Additi
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat, @NotNull ItemStack item) {
|
||||
if (Material.ENCHANTED_BOOK.equals(itemMat)) return false;
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) {
|
||||
if (Material.ENCHANTED_BOOK.getKey().equals(itemType)) return false;
|
||||
|
||||
return !eeenchantment.getSupportedItems().is(item);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@ import com.willfp.ecoenchants.enchantments.EcoEnchant;
|
|||
import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget;
|
||||
import com.willfp.ecoenchants.enchantments.meta.EnchantmentType;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
||||
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
|
||||
import xyz.alexcrea.cuanvil.util.MaterialUtil;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -23,7 +25,7 @@ public class CALegacyEcoEnchant extends CABukkitEnchantment implements Additiona
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||
if (enchantments.isEmpty()) return false;
|
||||
|
||||
EnchantmentType type = this.ecoEnchant.getType();
|
||||
|
|
@ -48,14 +50,15 @@ public class CALegacyEcoEnchant extends CABukkitEnchantment implements Additiona
|
|||
|
||||
@Override
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments,
|
||||
@NotNull Material itemMat,
|
||||
@NotNull NamespacedKey itemType,
|
||||
@NotNull ItemStack item) {
|
||||
if (Material.ENCHANTED_BOOK.equals(itemMat)) {
|
||||
if (Material.ENCHANTED_BOOK.getKey().equals(itemType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var mat = MaterialUtil.INSTANCE.getMatFromKey(itemType);
|
||||
for (EnchantmentTarget target : this.ecoEnchant.getTargets()) {
|
||||
if (target.getMaterials().contains(itemMat)) {
|
||||
if (target.getMaterials().contains(mat)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||
|
||||
import com.maddoxh.superEnchants.enchants.CustomEnchant;
|
||||
import com.maddoxh.superEnchants.enchants.EnchantManager;
|
||||
import com.maddoxh.superEnchants.items.EnchantApplicator;
|
||||
import com.maddoxh.superEnchants.items.EnchantReader;
|
||||
import com.maddoxh.superEnchants.util.ConflictChecker;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentBase;
|
||||
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CASuperEnchantEnchantment extends CAEnchantmentBase implements AdditionalTestEnchantment {
|
||||
|
||||
private @NotNull CustomEnchant enchant;
|
||||
private @NotNull EnchantManager enchantManager;
|
||||
|
||||
public CASuperEnchantEnchantment(@NotNull CustomEnchant enchant, @NotNull Plugin plugin, @NotNull EnchantManager enchantManager) {
|
||||
super(NamespacedKey.fromString(enchant.getId(), plugin), EnchantmentRarity.COMMON, enchant.getMaxLevel());
|
||||
|
||||
this.enchant = enchant;
|
||||
this.enchantManager = enchantManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLevel(@NotNull ItemStack item, @NotNull ItemMeta meta) {
|
||||
return EnchantReader.INSTANCE.getEnchantLevel(item, enchant.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnchantmentPresent(@NotNull ItemStack item, @NotNull ItemMeta meta) {
|
||||
return EnchantReader.INSTANCE.hasEnchant(item, enchant.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEnchantmentUnsafe(@NotNull ItemStack item, int level) {
|
||||
EnchantApplicator.INSTANCE.applyEnchant(item, enchant.getId(), level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFrom(@NotNull ItemStack item) {
|
||||
EnchantApplicator.INSTANCE.removeEnchant(item, enchant.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||
var idMap = new HashMap<String, Integer>();
|
||||
|
||||
enchantments.forEach((enchant, level) -> {
|
||||
if(!(enchant instanceof CASuperEnchantEnchantment superEnch)) return;
|
||||
idMap.put(superEnch.enchant.getId(), level);
|
||||
});
|
||||
|
||||
return ConflictChecker.INSTANCE.hasConflict(
|
||||
idMap,
|
||||
enchant.getId(),
|
||||
enchantManager
|
||||
) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) {
|
||||
if(Material.ENCHANTED_BOOK.equals(item.getType())) return false;
|
||||
|
||||
return !enchant.canApplyTo(item.getType());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +1,35 @@
|
|||
package xyz.alexcrea.cuanvil.gui.config;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public interface SelectMaterialContainer {
|
||||
|
||||
EnumSet<Material> getSelectedMaterials();
|
||||
Set<NamespacedKey> getSelectedMaterials();
|
||||
|
||||
boolean setSelectedMaterials(EnumSet<Material> materials);
|
||||
boolean setSelectedMaterials(Set<NamespacedKey> materials);
|
||||
|
||||
EnumSet<Material> illegalMaterials();
|
||||
Set<NamespacedKey> illegalMaterials();
|
||||
|
||||
static List<String> getMaterialLore(SelectMaterialContainer container, String containerType, String action){
|
||||
// Prepare material lore
|
||||
ArrayList<String> groupLore = new ArrayList<>();
|
||||
groupLore.add("§7Allow you to select a list of §ematerials §7that this " + containerType + " should " + action);
|
||||
Set<Material> materialSet = container.getSelectedMaterials();
|
||||
Set<NamespacedKey> materialSet = container.getSelectedMaterials();
|
||||
if (materialSet.isEmpty()) {
|
||||
groupLore.add("§7There is no "+action+"d material for this "+containerType+".");
|
||||
} else {
|
||||
groupLore.add("§7List of "+action+"d materials for this "+containerType+":");
|
||||
Iterator<Material> materialIterator = materialSet.iterator();
|
||||
Iterator<NamespacedKey> materialIterator = materialSet.iterator();
|
||||
|
||||
boolean greaterThanMax = materialSet.size() > 5;
|
||||
int maxindex = (greaterThanMax ? 4 : materialSet.size());
|
||||
for (int i = 0; i < maxindex; i++) {
|
||||
// format string like "- Stone Sword"
|
||||
String formattedName = CasedStringUtil.snakeToUpperSpacedCase(materialIterator.next().name().toLowerCase());
|
||||
String formattedName = CasedStringUtil.snakeToUpperSpacedCase(materialIterator.next().getKey().toLowerCase());
|
||||
groupLore.add("§7- §e" + formattedName);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
||||
import xyz.alexcrea.cuanvil.util.MaterialUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
|
@ -52,7 +53,7 @@ public class SelectItemTypeGui extends AbstractAskGui {
|
|||
event.setCancelled(true);
|
||||
|
||||
ItemStack cursor = event.getWhoClicked().getItemOnCursor();
|
||||
if(cursor.getType().isAir()) return;
|
||||
if(MaterialUtil.INSTANCE.isAir(cursor)) return;
|
||||
|
||||
ItemStack finalItem;
|
||||
if(materialOnly){
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import org.bukkit.inventory.meta.ItemMeta;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil;
|
||||
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager;
|
||||
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
|
||||
|
|
@ -283,7 +284,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
|
|||
|
||||
if(!this.packetManager.getCanSetInstantBuild()){
|
||||
lore.add("");
|
||||
lore.add("§4/!\\§cCaution§4/!\\ §cYou need ProtocoLib installed and working or a newer version of this plugin for this to work.");
|
||||
lore.add("§4/!\\§cCaution§4/!\\ §cYou need ProtocoLib installed and working or a paper server.");
|
||||
lore.add("§cCurrently ProtocoLib is not detected.");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import java.util.Locale;
|
|||
*/
|
||||
public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsGui.IntSettingFactory> {
|
||||
|
||||
private static final String SECTION_NAME = "enchant_limits";
|
||||
private static final String SECTION_NAME = ConfigOptions.ENCHANT_LIMIT_ROOT;
|
||||
|
||||
private static EnchantLimitConfigGui INSTANCE = null;
|
||||
|
||||
|
|
@ -41,18 +41,34 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsG
|
|||
String key = enchant.getKey().toString().toLowerCase(Locale.ROOT);
|
||||
String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key.replace(":", "_"));
|
||||
|
||||
var defaultValue = enchant.defaultMaxLevel();
|
||||
|
||||
return new IntSettingsGui.IntSettingFactory(prettyKey + " Limit", this,
|
||||
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG,
|
||||
Collections.singletonList(
|
||||
"§7Maximum applied level of " + prettyKey
|
||||
),
|
||||
0, 255,
|
||||
enchant.defaultMaxLevel(),
|
||||
-1, 255, -1,
|
||||
1, 5, 10, 50, 100){
|
||||
|
||||
@Override
|
||||
public int getConfiguredValue() {
|
||||
return ConfigOptions.INSTANCE.enchantLimit(enchant);
|
||||
var value = ConfigOptions.INSTANCE.rawEnchantLimit(enchant);
|
||||
return Math.min(value, ConfigOptions.ENCHANT_LIMIT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valueDisplayName(IntSettingsGui.ValueDisplayType type, int value) {
|
||||
|
||||
if(value < 0) {
|
||||
return switch (type) {
|
||||
case CURRENT -> "Default (" + defaultValue + ")";
|
||||
case RESET -> String.valueOf(defaultValue);
|
||||
default -> "Default";
|
||||
};
|
||||
|
||||
}
|
||||
else return super.valueDisplayName(type, value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.github.stefvanschie.inventoryframework.pane.PatternPane;
|
|||
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
|
||||
import io.delilaheve.CustomAnvil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
|
|
@ -325,19 +326,19 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
|
|||
// ----------------------------
|
||||
|
||||
@Override
|
||||
public EnumSet<Material> getSelectedMaterials() {
|
||||
public Set<NamespacedKey> getSelectedMaterials() {
|
||||
return this.group.getNonGroupInheritedMaterials();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSelectedMaterials(EnumSet<Material> materials) {
|
||||
public boolean setSelectedMaterials(Set<NamespacedKey> materials) {
|
||||
this.group.setNonGroupInheritedMaterials(materials);
|
||||
|
||||
// Write to file configuration
|
||||
String[] groupNames = new String[materials.size()];
|
||||
int index = 0;
|
||||
for (Material otherGroup : materials) {
|
||||
groupNames[index++] = otherGroup.name().toLowerCase();
|
||||
for (NamespacedKey otherGroup : materials) {
|
||||
groupNames[index++] = otherGroup.getKey().toLowerCase();
|
||||
}
|
||||
|
||||
ConfigHolder.ITEM_GROUP_HOLDER.getConfig().set(this.group.getName()+"."+ItemGroupManager.MATERIAL_LIST_PATH, groupNames);
|
||||
|
|
@ -353,8 +354,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<Material> illegalMaterials() {
|
||||
return EnumSet.of(Material.AIR);
|
||||
public Set<NamespacedKey> illegalMaterials() {
|
||||
return Set.of(Material.AIR.getKey());
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ public class IntSettingsGui extends AbstractSettingGui {
|
|||
assert meta != null;
|
||||
|
||||
meta.setDisplayName("§eReset to default value");
|
||||
meta.setLore(Collections.singletonList("§7Default value is §e" + holder.defaultVal));
|
||||
meta.setLore(Collections.singletonList("§7Default value is §e" +
|
||||
holder.valueDisplayName(ValueDisplayType.RESET, holder.defaultVal)));
|
||||
item.setItemMeta(meta);
|
||||
returnToDefault = new GuiItem(item, event -> {
|
||||
event.setCancelled(true);
|
||||
|
|
@ -86,41 +87,23 @@ public class IntSettingsGui extends AbstractSettingGui {
|
|||
* Update item using the setting value to match the new value.
|
||||
*/
|
||||
protected void updateValueDisplay() {
|
||||
|
||||
PatternPane pane = getPane();
|
||||
|
||||
// minus item
|
||||
GuiItem minusItem;
|
||||
if (now > holder.min) {
|
||||
int planned = Math.max(holder.min, now - step);
|
||||
ItemStack item = new ItemStack(Material.RED_TERRACOTTA);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
assert meta != null;
|
||||
|
||||
meta.setDisplayName("§e" + now + " §f-> §e" + planned + " §r(§c-" + (now - planned) + "§r)");
|
||||
meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE));
|
||||
item.setItemMeta(meta);
|
||||
|
||||
minusItem = new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance);
|
||||
minusItem = valueEditItem(Material.RED_TERRACOTTA, ValueDisplayType.REMOVE, planned);
|
||||
} else {
|
||||
minusItem = GuiGlobalItems.backgroundItem(Material.BARRIER);
|
||||
}
|
||||
pane.bindItem('-', minusItem);
|
||||
|
||||
//plus item
|
||||
// may do a function to generalise ?
|
||||
GuiItem plusItem;
|
||||
if (now < holder.max) {
|
||||
int planned = Math.min(holder.max, now + step);
|
||||
ItemStack item = new ItemStack(Material.GREEN_TERRACOTTA);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
assert meta != null;
|
||||
|
||||
meta.setDisplayName("§e" + now + " §f-> §e" + planned + " §r(§a+" + (planned - now) + "§r)");
|
||||
meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE));
|
||||
item.setItemMeta(meta);
|
||||
|
||||
plusItem = new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance);
|
||||
plusItem = valueEditItem(Material.GREEN_TERRACOTTA, ValueDisplayType.ADD, planned);
|
||||
} else {
|
||||
plusItem = GuiGlobalItems.backgroundItem(Material.BARRIER);
|
||||
}
|
||||
|
|
@ -131,7 +114,7 @@ public class IntSettingsGui extends AbstractSettingGui {
|
|||
ItemMeta resultMeta = resultPaper.getItemMeta();
|
||||
assert resultMeta != null;
|
||||
|
||||
resultMeta.setDisplayName("§fValue: §e" + now);
|
||||
resultMeta.setDisplayName("§fValue: §e" + holder.valueDisplayName(ValueDisplayType.CURRENT, now));
|
||||
resultMeta.setLore(holder.displayLore);
|
||||
|
||||
resultPaper.setItemMeta(resultMeta);
|
||||
|
|
@ -149,7 +132,21 @@ public class IntSettingsGui extends AbstractSettingGui {
|
|||
}
|
||||
pane.bindItem('D', returnToDefault);
|
||||
|
||||
}
|
||||
|
||||
private GuiItem valueEditItem(Material mat, ValueDisplayType type, int planned) {
|
||||
ItemStack item = new ItemStack(mat);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
assert meta != null;
|
||||
|
||||
var nowDisplay = holder.valueDisplayName(type, now);
|
||||
var plannedDisplay = holder.valueDisplayName(type, planned);
|
||||
var deltaDisplay = holder.deltaDisplay(type, now, planned);
|
||||
meta.setDisplayName("§e" + nowDisplay + " §f-> §e" + plannedDisplay + " §r(§c" + deltaDisplay + "§r)");
|
||||
|
||||
meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE));
|
||||
item.setItemMeta(meta);
|
||||
return new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -389,6 +386,23 @@ public class IntSettingsGui extends AbstractSettingGui {
|
|||
return getItem(itemMat, CasedStringUtil.detectToUpperSpacedCase(configPath));
|
||||
}
|
||||
|
||||
protected String valueDisplayName(ValueDisplayType type, int value) {
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
protected String deltaDisplay(ValueDisplayType type, int now, int planned) {
|
||||
var delta = planned - now;
|
||||
if(delta < 0) return "§c" + delta;
|
||||
else return "§a+" + delta;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum ValueDisplayType {
|
||||
ADD,
|
||||
CURRENT,
|
||||
REMOVE,
|
||||
RESET,
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
|
|||
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
|
||||
import io.delilaheve.CustomAnvil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
|
|
@ -18,18 +19,19 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
|||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||
import xyz.alexcrea.cuanvil.util.MaterialUtil;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MaterialSelectSettingGui extends MappedElementListConfigGui<Material, GuiItem> {
|
||||
public class MaterialSelectSettingGui extends MappedElementListConfigGui<NamespacedKey, GuiItem> {
|
||||
|
||||
private final SelectMaterialContainer selector;
|
||||
private final Gui backGui;
|
||||
private boolean instantRemove;
|
||||
|
||||
private final List<Material> defaultMaterials;
|
||||
private final EnumSet<Material> illegalMaterials;
|
||||
private final List<NamespacedKey> defaultMaterials;
|
||||
private final Set<NamespacedKey> illegalMaterials;
|
||||
private final int defaultMaterialHash;
|
||||
private int nowMaterialHash;
|
||||
|
||||
|
|
@ -161,8 +163,7 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
|||
|
||||
|
||||
// Save setting
|
||||
EnumSet<Material> result = EnumSet.noneOf(Material.class);
|
||||
result.addAll(this.elementGuiMap.keySet());
|
||||
Set<NamespacedKey> result = new HashSet<>(this.elementGuiMap.keySet());
|
||||
|
||||
if(!this.selector.setSelectedMaterials(result)){
|
||||
player.sendMessage("§cSomething went wrong while saving the change of value.");
|
||||
|
|
@ -185,8 +186,8 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
|||
ItemStack cursor = player.getItemOnCursor();
|
||||
|
||||
// Test if cursor material allowed
|
||||
Material cursorMat = cursor.getType();
|
||||
if(cursorMat.isAir()) return;
|
||||
NamespacedKey cursorMat = MaterialUtil.INSTANCE.getCustomType(cursor);
|
||||
if(MaterialUtil.INSTANCE.isAir(cursorMat)) return;
|
||||
if(this.illegalMaterials.contains(cursorMat)) return;
|
||||
|
||||
// Update gui only if item did not exist before.
|
||||
|
|
@ -201,12 +202,12 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
|||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack createItemForGeneric(Material material) {
|
||||
ItemStack item = new ItemStack(material);
|
||||
protected ItemStack createItemForGeneric(NamespacedKey material) {
|
||||
ItemStack item = new ItemStack(Objects.requireNonNull(MaterialUtil.INSTANCE.getMatFromKey(material)));
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if(meta == null) return item;
|
||||
meta.setDisplayName("§a" + CasedStringUtil.snakeToUpperSpacedCase(material.name().toLowerCase()));
|
||||
meta.setDisplayName("§a" + CasedStringUtil.snakeToUpperSpacedCase(material.getKey().toLowerCase()));
|
||||
meta.setLore(Collections.singletonList("§7Click here to remove this material from the list"));
|
||||
meta.addItemFlags(ItemFlag.values());
|
||||
|
||||
|
|
@ -216,22 +217,22 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Material> getEveryDisplayableInstanceOfGeneric() {
|
||||
protected Collection<NamespacedKey> getEveryDisplayableInstanceOfGeneric() {
|
||||
return this.defaultMaterials;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateElement(Material material, GuiItem element) {
|
||||
protected void updateElement(NamespacedKey material, GuiItem element) {
|
||||
// Nothing happen here I think
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GuiItem newElementRequested(Material material, GuiItem newItem) {
|
||||
protected GuiItem newElementRequested(NamespacedKey material, GuiItem newItem) {
|
||||
newItem.setAction(event -> {
|
||||
if(this.instantRemove){
|
||||
removeMaterial(material);
|
||||
}else {
|
||||
String materialName = CasedStringUtil.snakeToUpperSpacedCase(material.name().toLowerCase());
|
||||
String materialName = CasedStringUtil.snakeToUpperSpacedCase(material.getKey().toLowerCase());
|
||||
|
||||
// Create and show confirm remove gui.
|
||||
ConfirmActionGui confirmGui = new ConfirmActionGui(
|
||||
|
|
@ -250,7 +251,7 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
|||
return newItem;
|
||||
}
|
||||
|
||||
private void removeMaterial(Material material) {
|
||||
private void removeMaterial(NamespacedKey material) {
|
||||
if(this.elementGuiMap.containsKey(material)){
|
||||
this.nowMaterialHash ^= material.hashCode();
|
||||
setSaveItem();
|
||||
|
|
@ -260,18 +261,18 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
|||
}
|
||||
|
||||
@Override
|
||||
protected GuiItem findItemFromElement(Material generic, GuiItem element) {
|
||||
protected GuiItem findItemFromElement(NamespacedKey generic, GuiItem element) {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GuiItem findGuiItemForRemoval(Material generic, GuiItem element) {
|
||||
protected GuiItem findGuiItemForRemoval(NamespacedKey generic, GuiItem element) {
|
||||
return element;
|
||||
}
|
||||
|
||||
private static int hashFromMaterialList(List<Material> materialList){
|
||||
private static int hashFromMaterialList(List<NamespacedKey> materialList){
|
||||
int defaultMaterialHash = 0;
|
||||
for (Material material : materialList) {
|
||||
for (NamespacedKey material : materialList) {
|
||||
defaultMaterialHash ^= material.hashCode();
|
||||
}
|
||||
return defaultMaterialHash;
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ import org.bukkit.entity.HumanEntity;
|
|||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||
import xyz.alexcrea.cuanvil.config.WorkPenaltyType;
|
||||
import xyz.alexcrea.cuanvil.gui.config.global.BasicConfigGui;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
||||
import xyz.alexcrea.cuanvil.util.AnvilUseType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import io.delilaheve.util.ConfigOptions;
|
|||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||
import xyz.alexcrea.cuanvil.util.MetricType;
|
||||
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil;
|
||||
import xyz.alexcrea.cuanvil.util.config.LoreEditType;
|
||||
|
||||
|
|
@ -18,6 +19,9 @@ public class PluginSetDefault {
|
|||
|
||||
int nbSet = 0;
|
||||
|
||||
nbSet += trySetDefault(config, METRIC_TYPE, MetricType.AUTO.getValue());
|
||||
nbSet += trySetDefault(config, METRIC_COLLECT_ERROR, true);
|
||||
|
||||
nbSet += trySetDefault(config, CAP_ANVIL_COST, DEFAULT_CAP_ANVIL_COST);
|
||||
nbSet += trySetDefault(config, MAX_ANVIL_COST, DEFAULT_MAX_ANVIL_COST);
|
||||
nbSet += trySetDefault(config, REMOVE_ANVIL_COST_LIMIT, DEFAULT_REMOVE_ANVIL_COST_LIMIT);
|
||||
|
|
@ -30,7 +34,7 @@ public class PluginSetDefault {
|
|||
nbSet += trySetDefault(config, ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR);
|
||||
nbSet += trySetDefault(config, PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR);
|
||||
nbSet += trySetDefault(config, USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST);
|
||||
nbSet += trySetDefault(config, DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT);
|
||||
nbSet += trySetDefault(config, PER_COLOR_CODE_PERMISSION, DEFAULT_PER_COLOR_CODE_PERMISSION);
|
||||
|
||||
// Lore Edit defaults
|
||||
for (@NotNull LoreEditType value : LoreEditType.values()) {
|
||||
|
|
@ -57,6 +61,11 @@ public class PluginSetDefault {
|
|||
|
||||
nbSet += trySetDefault(config, PAPER_EDIT_ORDER, DEFAULT_PAPER_EDIT_ORDER);
|
||||
|
||||
nbSet += trySetDefault(config, DIALOG_RENAME_ENABLED, DEFAULT_DIALOG_RENAME_ENABLED);
|
||||
nbSet += trySetDefault(config, DIALOG_MAX_SIZE, DEFAULT_DIALOG_MAX_SIZE);
|
||||
nbSet += trySetDefault(config, DIALOG_RENAME_USE_PERMISSION, DEFAULT_DIALOG_RENAME_USE_PERMISSION);
|
||||
nbSet += trySetDefault(config, DIALOG_KEEP_USER_TEXT, DEFAULT_DIALOG_KEEP_USER_TEXT);
|
||||
|
||||
if (nbSet > 0) {
|
||||
CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values.");
|
||||
ConfigHolder.DEFAULT_CONFIG.saveToDisk(true);
|
||||
|
|
|
|||
|
|
@ -77,6 +77,12 @@ public class UpdateHandler {
|
|||
if (hadUpdate) {
|
||||
CustomAnvil.instance.getLogger().info("Updating Done !");
|
||||
}
|
||||
|
||||
if(current.major() == 1 && current.minor() < 21) {
|
||||
var logger = CustomAnvil.instance.getLogger();
|
||||
logger.warning("Your are running an old version of minecraft (lower than 1.21)");
|
||||
logger.warning("Custom Anvil will stop supporting this version on the first of july 2026");
|
||||
}
|
||||
}
|
||||
|
||||
private static void finishConfiguration(@Nonnull String newVersion, @Nonnull Set<ConfigHolder> toSave) {
|
||||
|
|
|
|||
|
|
@ -15,22 +15,6 @@ public class UpdateUtils {
|
|||
return Version.fromString(versionString);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static int[] currentMinecraftVersionArray() {
|
||||
String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0];
|
||||
return UpdateUtils.readVersionFromString(versionString);
|
||||
}
|
||||
|
||||
public static int[] readVersionFromString(String versionString) {
|
||||
String[] partialVersion = versionString.split("\\.");
|
||||
int[] versionParts = new int[]{0, 0, 0};
|
||||
|
||||
for (int i = 0; i < Math.min(3, partialVersion.length); i++) {
|
||||
versionParts[i] = Integer.parseInt(partialVersion[i]);
|
||||
}
|
||||
return versionParts;
|
||||
}
|
||||
|
||||
public static void addToStringList(FileConfiguration config, String path, String... toAdd) {
|
||||
List<String> groups = new ArrayList<>(config.getStringList(path));
|
||||
groups.addAll(Arrays.asList(toAdd));
|
||||
|
|
|
|||
|
|
@ -21,7 +21,11 @@ public record Version(int major, int minor, int patch) {
|
|||
int[] versionParts = new int[]{0, 0, 0};
|
||||
|
||||
for (int i = 0; i < Math.min(3, partialVersion.length); i++) {
|
||||
versionParts[i] = Integer.parseInt(partialVersion[i]);
|
||||
try {
|
||||
versionParts[i] = Integer.parseInt(partialVersion[i]);
|
||||
} catch (NumberFormatException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Version(versionParts[0], versionParts[1], versionParts[2]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package xyz.alexcrea.cuanvil.update.plugin;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
|
@ -11,6 +12,7 @@ import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup;
|
|||
import xyz.alexcrea.cuanvil.group.IncludeGroup;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
|
@ -69,7 +71,12 @@ public class PUpdate_1_11_0 {
|
|||
|
||||
// Create new group
|
||||
IncludeGroup group = new IncludeGroup(toolset);
|
||||
group.addAll(toolMats);
|
||||
NamespacedKey[] keys = new NamespacedKey[toolMats.length];
|
||||
for (int i = 0; i < toolMats.length; i++) {
|
||||
keys[i] = toolMats[i].getKey();
|
||||
}
|
||||
|
||||
group.addAll(keys);
|
||||
|
||||
MaterialGroupApi.addMaterialGroup(group, true);
|
||||
|
||||
|
|
@ -77,8 +84,8 @@ public class PUpdate_1_11_0 {
|
|||
if (tools == null) return;
|
||||
if (!(tools instanceof IncludeGroup include)) return;
|
||||
|
||||
List<Material> mats = List.of(toolMats);
|
||||
Set<Material> matSet = include.getNonGroupInheritedMaterials();
|
||||
List<NamespacedKey> mats = List.of(keys);
|
||||
Set<NamespacedKey> matSet = include.getNonGroupInheritedMaterials();
|
||||
if (!matSet.containsAll(mats)) return;
|
||||
|
||||
mats.forEach(matSet::remove);
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ package xyz.alexcrea.cuanvil.update.plugin;
|
|||
|
||||
import io.delilaheve.util.ConfigOptions;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||
import xyz.alexcrea.cuanvil.config.WorkPenaltyType;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.WorkPenaltyTypeSettingGui;
|
||||
import xyz.alexcrea.cuanvil.util.AnvilUseType;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.EnumMap;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import xyz.alexcrea.cuanvil.command.EditConfigExecutor
|
|||
import xyz.alexcrea.cuanvil.command.ReloadExecutor
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
||||
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil
|
||||
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
|
||||
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
|
||||
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui
|
||||
|
|
@ -194,6 +196,10 @@ open class CustomAnvil : JavaPlugin() {
|
|||
if(!isPaper) {
|
||||
logger.warning("It seems you are using spigot")
|
||||
logger.warning("Please take notice that spigot is less supported than paper and derivatives")
|
||||
if(MinecraftVersionUtil.isTooNewForSpigot) {
|
||||
logger.warning("If replace too expensive is not working this is likely because of spigot")
|
||||
logger.warning("As native nms is not supported for spigot starting 26.1")
|
||||
}
|
||||
}
|
||||
|
||||
val loader = if(isPaper) "paper" else "spigot"
|
||||
|
|
@ -205,7 +211,6 @@ open class CustomAnvil : JavaPlugin() {
|
|||
.setFeatured(featured)
|
||||
.setOnError {
|
||||
logger.log(Level.WARNING, "error trying to fetch latest update", it)
|
||||
MetricsUtil.trackError(it)
|
||||
}
|
||||
.checkVersion { latestVer: String? ->
|
||||
CustomAnvil.latestVer = latestVer
|
||||
|
|
@ -236,7 +241,8 @@ open class CustomAnvil : JavaPlugin() {
|
|||
|
||||
// Load config
|
||||
if (!ConfigHolder.loadNonDefaultConfig()) {
|
||||
logger.log(Level.SEVERE,"could not load non default config.")
|
||||
logger.log(Level.SEVERE,"Plugin has an issue while trying to load non default config... exiting...")
|
||||
server.pluginManager.disablePlugin(this)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -254,9 +260,11 @@ open class CustomAnvil : JavaPlugin() {
|
|||
MainConfigGui.getInstance().init(DependencyManager.packetManager)
|
||||
GuiSharedConstant.loadConstants()
|
||||
|
||||
// Prepare economy if possible
|
||||
EconomyManager.setupEconomy(this)
|
||||
|
||||
// Finally, re add default we may be missing
|
||||
PluginSetDefault.reAddMissingDefault()
|
||||
|
||||
}
|
||||
|
||||
fun reloadResource(
|
||||
|
|
|
|||
|
|
@ -2,14 +2,17 @@ package io.delilaheve.util
|
|||
|
||||
import io.delilaheve.CustomAnvil
|
||||
import io.delilaheve.util.EnchantmentUtil.enchantmentName
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilUseType
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||
import xyz.alexcrea.cuanvil.config.WorkPenaltyType
|
||||
import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart
|
||||
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
||||
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
|
||||
import xyz.alexcrea.cuanvil.util.AnvilUseType
|
||||
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
|
||||
import java.math.BigDecimal
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
|
|
@ -45,6 +48,8 @@ object ConfigOptions {
|
|||
const val PERMISSION_NEEDED_FOR_COLOR = "permission_needed_for_color"
|
||||
const val USE_OF_COLOR_COST = "use_of_color_cost"
|
||||
|
||||
const val PER_COLOR_CODE_PERMISSION = "per_color_code_permission"
|
||||
|
||||
// Work penalty config
|
||||
const val WORK_PENALTY_ROOT = "work_penalty"
|
||||
const val WORK_PENALTY_INCREASE = "shared_increase"
|
||||
|
|
@ -57,15 +62,25 @@ object ConfigOptions {
|
|||
const val ENCHANT_COUNT_LIMIT_DEFAULT = "$ENCHANT_COUNT_LIMIT_ROOT.default"
|
||||
const val ENCHANT_COUNT_LIMIT_ITEMS = "$ENCHANT_COUNT_LIMIT_ROOT.items"
|
||||
|
||||
const val DEFAULT_LIMIT_PATH = "default_limit"
|
||||
|
||||
const val ENCHANT_LIMIT_ROOT = "enchant_limits"
|
||||
const val ENCHANT_VALUES_ROOT = "enchant_values"
|
||||
|
||||
// Dialog menu rename
|
||||
const val DIALOG_RENAME_ENABLED = "enable_dialog_rename"
|
||||
const val DIALOG_MAX_SIZE = "dialog_rename_max_size"
|
||||
const val DIALOG_RENAME_USE_PERMISSION = "permission_needed_for_dialog_rename"
|
||||
const val DIALOG_KEEP_USER_TEXT = "dialog_rename_keep_user_text"
|
||||
|
||||
// Others
|
||||
const val DISABLE_MERGE_OVER_ROOT = "disable-merge-over"
|
||||
|
||||
const val IMMUTABLE_ENCHANTMENT_LIST = "immutable_enchantments"
|
||||
|
||||
// Monetary configs
|
||||
const val MONETARY_USAGE_ROOT = "monetary_cost"
|
||||
const val SHOULD_USE_MONEY = "$MONETARY_USAGE_ROOT.enabled"
|
||||
const val MONEY_CURRENCY = "$MONETARY_USAGE_ROOT.currency"
|
||||
const val MONETARY_MULTIPLIER_ROOT = "$MONETARY_USAGE_ROOT.multipliers"
|
||||
|
||||
// Keys for specific enchantment values
|
||||
private const val KEY_BOOK = "book"
|
||||
|
|
@ -102,12 +117,23 @@ object ConfigOptions {
|
|||
const val DEFAULT_PERMISSION_NEEDED_FOR_COLOR = true
|
||||
const val DEFAULT_USE_OF_COLOR_COST = 0
|
||||
|
||||
const val DEFAULT_ENCHANT_LIMIT = 5
|
||||
const val DEFAULT_PER_COLOR_CODE_PERMISSION = false
|
||||
|
||||
// Monetary configs
|
||||
const val DEFAULT_SHOULD_USE_MONEY = false
|
||||
const val DEFAULT_MONEY_CURRENCY = "default"
|
||||
const val DEFAULT_MONEY_MULTIPLIER = 1.0
|
||||
|
||||
// Debug flag
|
||||
private const val DEFAULT_DEBUG_LOG = false
|
||||
private const val DEFAULT_VERBOSE_DEBUG_LOG = false
|
||||
|
||||
// Dialog menu rename
|
||||
const val DEFAULT_DIALOG_RENAME_ENABLED = false
|
||||
const val DEFAULT_DIALOG_MAX_SIZE = 256
|
||||
const val DEFAULT_DIALOG_RENAME_USE_PERMISSION = false
|
||||
const val DEFAULT_DIALOG_KEEP_USER_TEXT = true
|
||||
|
||||
// -------------
|
||||
// Config Ranges
|
||||
// -------------
|
||||
|
|
@ -132,9 +158,11 @@ object ConfigOptions {
|
|||
@JvmField
|
||||
val USE_OF_COLOR_COST_RANGE = 0..1000
|
||||
|
||||
// Valid range for an enchantment limit
|
||||
@JvmField
|
||||
val ENCHANT_LIMIT_RANGE = 1..255
|
||||
val DIALOG_MAX_SIZE_RANGE = 0..Int.MAX_VALUE
|
||||
|
||||
// Valid range for an enchantment limit
|
||||
const val ENCHANT_LIMIT = 255
|
||||
|
||||
// Valid range for an enchantment count limit
|
||||
@JvmField
|
||||
|
|
@ -150,6 +178,11 @@ object ConfigOptions {
|
|||
// Default max before merge disabled (negative mean enabled)
|
||||
const val DEFAULT_MAX_BEFORE_MERGE_DISABLED = -1
|
||||
|
||||
// -----------
|
||||
// Permissions
|
||||
// -----------
|
||||
private const val RENAME_DIALOG_PERMISSION = "ca.rename.dialog"
|
||||
|
||||
// -------------
|
||||
// Get methods
|
||||
// -------------
|
||||
|
|
@ -302,6 +335,16 @@ object ConfigOptions {
|
|||
.getBoolean(PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR)
|
||||
}
|
||||
|
||||
/**
|
||||
* Should each color code require a permission
|
||||
*/
|
||||
val usePerColorCodePermission: Boolean
|
||||
get() {
|
||||
return ConfigHolder.DEFAULT_CONFIG
|
||||
.config
|
||||
.getBoolean(PER_COLOR_CODE_PERMISSION, DEFAULT_PER_COLOR_CODE_PERMISSION)
|
||||
}
|
||||
|
||||
/**
|
||||
* How many xp should use of color should cost
|
||||
*/
|
||||
|
|
@ -348,22 +391,12 @@ object ConfigOptions {
|
|||
return WorkPenaltyPart(penaltyIncrease, penaltyAdditive, exclusivePenaltyIncrease, exclusivePenaltyAdditive)
|
||||
}
|
||||
|
||||
/**
|
||||
* Default enchantment limit
|
||||
*/
|
||||
private val defaultEnchantLimit: Int
|
||||
get() {
|
||||
return ConfigHolder.DEFAULT_CONFIG
|
||||
.config
|
||||
.getInt(DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get material enchantment count limit
|
||||
*
|
||||
* @return the current enchantment limit. -1 if none
|
||||
*/
|
||||
fun getEnchantCountLimit(type: Material): Int? {
|
||||
fun getEnchantCountLimit(type: NamespacedKey): Int? {
|
||||
val limit = materialEnchantCountLimit(type)
|
||||
|
||||
if(limit != null) return limit
|
||||
|
|
@ -377,8 +410,8 @@ object ConfigOptions {
|
|||
*
|
||||
* @return The current enchantment limit. -1 if none
|
||||
*/
|
||||
private fun materialEnchantCountLimit(type: Material): Int? {
|
||||
val path = "$ENCHANT_COUNT_LIMIT_ITEMS.${type.key.key.lowercase()}"
|
||||
private fun materialEnchantCountLimit(type: NamespacedKey): Int? {
|
||||
val path = "$ENCHANT_COUNT_LIMIT_ITEMS.${type.key.lowercase()}"
|
||||
if(!ConfigHolder.DEFAULT_CONFIG.config.isInt(path))
|
||||
return null
|
||||
|
||||
|
|
@ -418,46 +451,90 @@ object ConfigOptions {
|
|||
.getBoolean(VERBOSE_DEBUG_LOGGING, DEFAULT_VERBOSE_DEBUG_LOG)
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the dialog menu for rename enabled
|
||||
*/
|
||||
val doRenameDialog: Boolean
|
||||
get() {
|
||||
return ConfigHolder.DEFAULT_CONFIG
|
||||
.config
|
||||
.getBoolean(DIALOG_RENAME_ENABLED, DEFAULT_DIALOG_RENAME_ENABLED)
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the dialog menu require permission
|
||||
*/
|
||||
val doRenameDialogUsePermission: Boolean
|
||||
get() {
|
||||
return ConfigHolder.DEFAULT_CONFIG
|
||||
.config
|
||||
.getBoolean(DIALOG_RENAME_USE_PERMISSION, DEFAULT_DIALOG_RENAME_USE_PERMISSION)
|
||||
}
|
||||
|
||||
fun canUseDialogRename(player: HumanEntity): Boolean {
|
||||
if(!doRenameDialog || !AnvilRenameDialogUtil.anvilRenameDialog.canSendDialog()) return false
|
||||
if(doRenameDialogUsePermission && !player.hasPermission(RENAME_DIALOG_PERMISSION)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the dialog menu require permission
|
||||
*/
|
||||
val renameDialogMaxSize: Int
|
||||
get() {
|
||||
return ConfigHolder.DEFAULT_CONFIG
|
||||
.config
|
||||
.getInt(DIALOG_MAX_SIZE, DEFAULT_DIALOG_MAX_SIZE)
|
||||
.takeIf { it in DIALOG_MAX_SIZE_RANGE }
|
||||
?: Int.MAX_VALUE
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the text used for rename should be kept in the item's pdc
|
||||
*/
|
||||
val shouldKeepRenameText: Boolean
|
||||
get() {
|
||||
return ConfigHolder.DEFAULT_CONFIG
|
||||
.config
|
||||
.getBoolean(DIALOG_KEEP_USER_TEXT, DEFAULT_DIALOG_KEEP_USER_TEXT)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the given [enchantment]'s limit
|
||||
*/
|
||||
fun enchantLimit(enchantment: CAEnchantment): Int {
|
||||
val limit = rawEnchantLimit(enchantment)
|
||||
if(limit >= 0) return limit.coerceAtMost(ENCHANT_LIMIT)
|
||||
|
||||
// get default
|
||||
return enchantment.defaultMaxLevel()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the given [enchantment]'s limit
|
||||
*/
|
||||
fun rawEnchantLimit(enchantment: CAEnchantment): Int {
|
||||
// Test namespace
|
||||
var limit = enchantLimit(enchantment.key.toString())
|
||||
if (limit != null) return limit
|
||||
if (limit >= 0) return limit
|
||||
|
||||
// Test legacy (name only)
|
||||
limit = enchantLimit(enchantment.enchantmentName)
|
||||
if (limit != null) return limit
|
||||
if (limit >= 0) return limit
|
||||
|
||||
// get default (and test old legacy if present)
|
||||
return getDefaultLevel(enchantment.enchantmentName)
|
||||
// Default to negative
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the given [enchantmentName]'s limit
|
||||
*/
|
||||
private fun enchantLimit(enchantmentName: String): Int? {
|
||||
private fun enchantLimit(enchantmentName: String): Int {
|
||||
|
||||
val path = "${ENCHANT_LIMIT_ROOT}.$enchantmentName"
|
||||
return CustomAnvil.instance
|
||||
.config
|
||||
.getInt(path, ENCHANT_LIMIT_RANGE.first - 1)
|
||||
.takeIf { it in ENCHANT_LIMIT_RANGE }
|
||||
}
|
||||
|
||||
/**
|
||||
* 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") {
|
||||
val limit = enchantLimit("sweeping")
|
||||
if (limit != null) return limit
|
||||
|
||||
}
|
||||
return defaultEnchantLimit
|
||||
return CustomAnvil.instance.config
|
||||
.getInt(path, -1)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -529,20 +606,20 @@ object ConfigOptions {
|
|||
fun maxBeforeMergeDisabled(enchantment: CAEnchantment): Int {
|
||||
val key = enchantment.key.toString()
|
||||
var value = maxBeforeMergeDisabled(key)
|
||||
if (value != null) return value
|
||||
if (value >= 0) return value
|
||||
|
||||
// Legacy name
|
||||
val legacy = enchantment.enchantmentName
|
||||
value = maxBeforeMergeDisabled(legacy)
|
||||
if (value != null) return value
|
||||
if (value >= 0) return value
|
||||
|
||||
if (key == "minecraft:sweeping_edge") {
|
||||
value = maxBeforeMergeDisabled("minecraft:sweeping")
|
||||
if (value != null) return value
|
||||
if (value >= 0) return value
|
||||
|
||||
// legacy name of legacy enchantment name
|
||||
value = maxBeforeMergeDisabled("sweeping")
|
||||
if (value != null) return value
|
||||
if (value >= 0) return value
|
||||
}
|
||||
|
||||
return DEFAULT_MAX_BEFORE_MERGE_DISABLED
|
||||
|
|
@ -552,14 +629,13 @@ object ConfigOptions {
|
|||
* Get the given [enchantmentName]'s level before merge is disabled
|
||||
* a negative value would mean never disabled
|
||||
*/
|
||||
private fun maxBeforeMergeDisabled(enchantmentName: String): Int? {
|
||||
private fun maxBeforeMergeDisabled(enchantmentName: String): Int {
|
||||
// find if set
|
||||
val path = "${DISABLE_MERGE_OVER_ROOT}.$enchantmentName"
|
||||
|
||||
return CustomAnvil.instance
|
||||
.config
|
||||
.getInt(path, ENCHANT_LIMIT_RANGE.min() - 1)
|
||||
.takeIf { it in ENCHANT_LIMIT_RANGE }
|
||||
.getInt(path, -1)
|
||||
}
|
||||
|
||||
fun isImmutable(key: NamespacedKey): Boolean {
|
||||
|
|
@ -575,4 +651,29 @@ object ConfigOptions {
|
|||
return false
|
||||
}
|
||||
|
||||
/*
|
||||
* Monetary configs (only for 1.21.6+)
|
||||
* Also require dialog rename
|
||||
*/
|
||||
fun shouldUseMoney(player: HumanEntity): Boolean {
|
||||
return EconomyManager.economy?.initialized() == true &&
|
||||
canUseDialogRename(player) &&
|
||||
ConfigHolder.DEFAULT_CONFIG
|
||||
.config
|
||||
.getBoolean(SHOULD_USE_MONEY, DEFAULT_SHOULD_USE_MONEY)
|
||||
}
|
||||
|
||||
val usedCurrency: String
|
||||
get() {
|
||||
return ConfigHolder.DEFAULT_CONFIG
|
||||
.config
|
||||
.getString(MONEY_CURRENCY, DEFAULT_MONEY_CURRENCY)!!
|
||||
}
|
||||
|
||||
fun getMonetaryMultiplier(type: String): BigDecimal {
|
||||
return BigDecimal(ConfigHolder.DEFAULT_CONFIG
|
||||
.config
|
||||
.getDouble("$MONETARY_MULTIPLIER_ROOT.$type", DEFAULT_MONEY_MULTIPLIER))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.bukkit.inventory.ItemStack
|
|||
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
|
||||
import xyz.alexcrea.cuanvil.group.ConflictType
|
||||
import xyz.alexcrea.cuanvil.util.MaterialUtil.customType
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
|
|
@ -34,7 +35,7 @@ object EnchantmentUtil {
|
|||
val bypassFuse = player.hasPermission(CustomAnvil.bypassFusePermission)
|
||||
val bypassLevel = player.hasPermission(CustomAnvil.bypassLevelPermission)
|
||||
|
||||
var maxEnchantCount = ConfigOptions.getEnchantCountLimit(item.type)
|
||||
var maxEnchantCount = ConfigOptions.getEnchantCountLimit(item.customType)
|
||||
if(maxEnchantCount == null || maxEnchantCount < 0) maxEnchantCount = Int.MAX_VALUE
|
||||
|
||||
val allowed = other.filter { (enchantment, _) -> enchantment.isAllowed(player) }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ import org.bukkit.Material.ENCHANTED_BOOK
|
|||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.Damageable
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
|
||||
import xyz.alexcrea.cuanvil.update.UpdateUtils
|
||||
import xyz.alexcrea.cuanvil.util.MaterialUtil.customType
|
||||
import xyz.alexcrea.cuanvil.util.MaxDamageCheckerUtil
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
|
@ -35,6 +38,13 @@ object ItemUtil {
|
|||
|
||||
}
|
||||
|
||||
private fun maxDamage(damageable: Damageable): Int {
|
||||
val ver = UpdateUtils.currentMinecraftVersion()
|
||||
if(ver.major <= 1 && ver.minor <= 20 && ver.patch < 5) return Integer.MAX_VALUE
|
||||
|
||||
return MaxDamageCheckerUtil.getMaxDamage(damageable)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this [ItemStack]s durability from a combination of the
|
||||
* [first] and [second] item's durability values
|
||||
|
|
@ -54,7 +64,9 @@ object ItemUtil {
|
|||
val secondDurability = durability - secondDamage
|
||||
val combinedDurability = firstDurability + secondDurability
|
||||
val newDurability = min(combinedDurability, durability)
|
||||
it.damage = durability - newDurability
|
||||
|
||||
val maxDamage = maxDamage(it)
|
||||
it.damage = min(durability - newDurability, maxDamage)
|
||||
itemMeta = it
|
||||
return true
|
||||
}
|
||||
|
|
@ -90,5 +102,5 @@ object ItemUtil {
|
|||
*/
|
||||
fun ItemStack.canMergeWith(
|
||||
other: ItemStack?
|
||||
) = (other != null) && (type == other.type || (other.isEnchantedBook()))
|
||||
) = (other != null) && (customType == other.customType || (other.isEnchantedBook()))
|
||||
}
|
||||
|
|
|
|||
72
src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilCost.kt
Normal file
72
src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilCost.kt
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
package xyz.alexcrea.cuanvil.anvil
|
||||
|
||||
import io.delilaheve.util.ConfigOptions
|
||||
import java.math.BigDecimal
|
||||
import kotlin.math.min
|
||||
import io.delilaheve.util.ConfigOptions.getMonetaryMultiplier as moneyMultiplier
|
||||
|
||||
open class AnvilCost {
|
||||
private val isAlone: Boolean
|
||||
var valid = true // Get set as invalid if cost can be satisfied
|
||||
var isMonetary = false
|
||||
|
||||
var generic = 0
|
||||
var enchantment = 0
|
||||
var repair = 0
|
||||
var rename = 0
|
||||
var lore = 0
|
||||
var illegalPenalty = 0
|
||||
var workPenalty = 0
|
||||
var recipe = 0
|
||||
|
||||
constructor(generic: Int) {
|
||||
this.generic = generic
|
||||
isAlone = true
|
||||
}
|
||||
|
||||
constructor() {
|
||||
isAlone = false
|
||||
}
|
||||
|
||||
fun asXpCost(): Int {
|
||||
return generic + enchantment + repair + rename + lore + illegalPenalty + workPenalty + recipe
|
||||
}
|
||||
|
||||
fun filteredXpCost(ignoreRules: Boolean = false): Int {
|
||||
val original = asXpCost()
|
||||
|
||||
// Test repair cost limit
|
||||
return if (
|
||||
!ignoreRules &&
|
||||
!ConfigOptions.doRemoveCostLimit &&
|
||||
ConfigOptions.doCapCost
|
||||
) {
|
||||
min(original, ConfigOptions.maxAnvilCost)
|
||||
} else {
|
||||
original
|
||||
}
|
||||
}
|
||||
|
||||
open fun asMonetaryCost(): BigDecimal {
|
||||
// multiply by per use type multipliers
|
||||
return BigDecimal(generic)
|
||||
.add(BigDecimal(enchantment).multiply(moneyMultiplier("enchantment")))
|
||||
.add(BigDecimal(repair).multiply(moneyMultiplier("repair")))
|
||||
.add(BigDecimal(rename).multiply(moneyMultiplier("rename")))
|
||||
.add(BigDecimal(lore).multiply(moneyMultiplier("lore_edit")))
|
||||
.add(BigDecimal(enchantment).multiply(moneyMultiplier("enchantment")))
|
||||
.add(BigDecimal(illegalPenalty).multiply(moneyMultiplier("work_penalty")))
|
||||
.add(BigDecimal(workPenalty).multiply(moneyMultiplier("work_penalty")))
|
||||
.add(BigDecimal(recipe).multiply(moneyMultiplier("recipe")))
|
||||
.multiply(moneyMultiplier("global"))
|
||||
}
|
||||
}
|
||||
|
||||
class CustomCraftCost(val rawCost: Int): AnvilCost() {
|
||||
|
||||
override fun asMonetaryCost(): BigDecimal {
|
||||
return BigDecimal(rawCost)
|
||||
.multiply(moneyMultiplier("global"))
|
||||
}
|
||||
|
||||
}
|
||||
331
src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt
Normal file
331
src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
package xyz.alexcrea.cuanvil.anvil
|
||||
|
||||
import io.delilaheve.CustomAnvil
|
||||
import io.delilaheve.util.ConfigOptions
|
||||
import io.delilaheve.util.EnchantmentUtil.combineWith
|
||||
import io.delilaheve.util.ItemUtil.findEnchantments
|
||||
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.Material
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.AnvilInventory
|
||||
import org.bukkit.inventory.InventoryView
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.ItemMeta
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
||||
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
|
||||
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
|
||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil
|
||||
import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
|
||||
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
|
||||
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
|
||||
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
||||
import xyz.alexcrea.cuanvil.util.anvil.AnvilColorUtil
|
||||
import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil
|
||||
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
|
||||
import xyz.alexcrea.cuanvil.util.config.LoreEditType
|
||||
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
|
||||
|
||||
object AnvilMergeLogic {
|
||||
|
||||
open class AnvilResult {
|
||||
companion object {
|
||||
val EMPTY = AnvilResult(null, AnvilCost())
|
||||
}
|
||||
|
||||
val item: ItemStack?
|
||||
val cost: AnvilCost
|
||||
val ignoreXpRules: Boolean
|
||||
|
||||
constructor(item: ItemStack?, cost: AnvilCost, ignoreXpRules: Boolean = false) {
|
||||
this.item = item
|
||||
this.cost = cost
|
||||
this.ignoreXpRules = ignoreXpRules
|
||||
}
|
||||
|
||||
fun isEmpty(): Boolean {
|
||||
return item == null
|
||||
}
|
||||
}
|
||||
|
||||
class UnitRepairResult : AnvilResult {
|
||||
companion object {
|
||||
val EMPTY = UnitRepairResult(null, AnvilCost(), 0)
|
||||
}
|
||||
|
||||
val repairAmount: Int
|
||||
|
||||
constructor(item: ItemStack?, cost: AnvilCost, repairAmount: Int) : super(item, cost) {
|
||||
this.repairAmount = repairAmount
|
||||
}
|
||||
}
|
||||
|
||||
class CustomCraftResult : AnvilResult {
|
||||
companion object {
|
||||
val EMPTY = CustomCraftResult(null, CustomCraftCost(0), 0, null)
|
||||
}
|
||||
|
||||
val customCraftCost: CustomCraftCost
|
||||
val amount: Int
|
||||
val recipe: AnvilCustomRecipe?
|
||||
|
||||
constructor(
|
||||
item: ItemStack?, cost: CustomCraftCost,
|
||||
amount: Int, recipe: AnvilCustomRecipe?
|
||||
) : super(item, cost, true) {
|
||||
this.customCraftCost = cost
|
||||
this.amount = amount
|
||||
this.recipe = recipe
|
||||
}
|
||||
}
|
||||
|
||||
class LoreEditResult : AnvilResult {
|
||||
companion object {
|
||||
val EMPTY = LoreEditResult(null, AnvilCost(), LoreEditType.APPEND_PAPER)
|
||||
}
|
||||
|
||||
val type: LoreEditType
|
||||
|
||||
constructor(item: ItemStack?, cost: AnvilCost, type: LoreEditType) : super(item, cost) {
|
||||
this.type = type
|
||||
}
|
||||
}
|
||||
|
||||
fun doRenaming(
|
||||
view: InventoryView, //TODO use anvil view
|
||||
inventory: AnvilInventory,
|
||||
player: Player, first: ItemStack
|
||||
): AnvilResult {
|
||||
val resultItem = DependencyManager.cloneItem(player, first)
|
||||
val cost = AnvilCost()
|
||||
cost.rename = handleRename(resultItem, inventory, player)
|
||||
|
||||
// Test/stop if nothing changed.
|
||||
if (first == resultItem) {
|
||||
CustomAnvil.log("no right item, But input is same as output")
|
||||
return AnvilResult.EMPTY
|
||||
}
|
||||
|
||||
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY)
|
||||
val result =
|
||||
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.RENAME_ONLY, cost)
|
||||
|
||||
return AnvilResult(result, cost)
|
||||
}
|
||||
|
||||
private fun processDialogPCD(meta: ItemMeta, player: HumanEntity) {
|
||||
val text = AnvilRenameDialogUtil.anvilRenameDialog.currentText(player)
|
||||
return processPCD(meta, player, text)
|
||||
}
|
||||
|
||||
fun processPCD(meta: ItemMeta, player: HumanEntity, text: String?) {
|
||||
val keepDialog = ConfigOptions.canUseDialogRename(player) && ConfigOptions.shouldKeepRenameText
|
||||
|
||||
val pdc = meta.persistentDataContainer
|
||||
if (!keepDialog)
|
||||
pdc.remove(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY)
|
||||
else {
|
||||
if (text == null || text.isBlank())
|
||||
pdc.remove(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY)
|
||||
else pdc.set(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY, PersistentDataType.STRING, text)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int {
|
||||
// Can be null
|
||||
var renameText = ChatColor.stripColor(inventory.renameText)
|
||||
|
||||
var sumCost = 0
|
||||
var useColor = false
|
||||
if (ConfigOptions.renameColorPossible && renameText != null) {
|
||||
val component = AnvilColorUtil.handleColor(
|
||||
renameText,
|
||||
AnvilColorUtil.renamePermission(player)
|
||||
)
|
||||
|
||||
if (component != null) {
|
||||
renameText = MiniMessageUtil.legacy_mm.serialize(component)
|
||||
|
||||
sumCost += ConfigOptions.useOfColorCost
|
||||
useColor = true
|
||||
}
|
||||
}
|
||||
|
||||
// Rename item and add renaming cost
|
||||
resultItem.itemMeta?.let {
|
||||
val hasDisplayName = it.hasDisplayName()
|
||||
val displayName = if (!hasDisplayName) null
|
||||
else if (useColor) it.displayName
|
||||
else ChatColor.stripColor(it.displayName)
|
||||
|
||||
|
||||
if (!displayName.contentEquals(renameText) && !(displayName == null &&
|
||||
renameText == "" ||
|
||||
//TODO on recent paper check effective name instead
|
||||
renameText == CasedStringUtil.snakeToUpperSpacedCase(resultItem.type.name.lowercase())
|
||||
)
|
||||
) {
|
||||
it.setDisplayName(renameText)
|
||||
processDialogPCD(it, player)
|
||||
resultItem.itemMeta = it
|
||||
|
||||
sumCost += ConfigOptions.itemRenameCost
|
||||
}
|
||||
|
||||
return sumCost
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
fun doMerge(
|
||||
view: InventoryView, //TODO use anvil view instead
|
||||
inventory: AnvilInventory,
|
||||
player: Player,
|
||||
first: ItemStack, second: ItemStack
|
||||
): AnvilResult {
|
||||
val newEnchants = first.findEnchantments()
|
||||
.combineWith(second.findEnchantments(), first, player)
|
||||
var hasChanged = !isIdentical(first.findEnchantments(), newEnchants)
|
||||
|
||||
val resultItem = DependencyManager.cloneItem(player, first)
|
||||
val cost = AnvilCost()
|
||||
if (hasChanged) {
|
||||
resultItem.setEnchantmentsUnsafe(newEnchants)
|
||||
// Calculate enchantment cost
|
||||
AnvilXpUtil.getRightValues(second, resultItem, cost)
|
||||
}
|
||||
|
||||
// Calculate repair cost
|
||||
if (!first.isEnchantedBook() && !second.isEnchantedBook()) {
|
||||
// we only need to be concerned with repair when neither item is a book
|
||||
val repaired = resultItem.repairFrom(first, second)
|
||||
cost.repair = if (repaired) ConfigOptions.itemRepairCost else 0
|
||||
hasChanged = hasChanged || repaired
|
||||
}
|
||||
|
||||
// Test/stop if nothing changed.
|
||||
if (!hasChanged) {
|
||||
CustomAnvil.log("Mergeable with second, But input is same as output")
|
||||
return AnvilResult.EMPTY
|
||||
}
|
||||
// As calculatePenalty edit result, we need to calculate penalty after checking equality
|
||||
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, second, resultItem, AnvilUseType.MERGE)
|
||||
// Calculate rename cost
|
||||
cost.rename = handleRename(resultItem, inventory, player)
|
||||
|
||||
val result =
|
||||
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.MERGE, cost)
|
||||
|
||||
return AnvilResult(result, cost)
|
||||
}
|
||||
|
||||
private fun isIdentical(
|
||||
firstEnchants: MutableMap<CAEnchantment, Int>,
|
||||
resultEnchants: MutableMap<CAEnchantment, Int>
|
||||
): Boolean {
|
||||
if (firstEnchants.size != resultEnchants.size) return false
|
||||
for (entry in resultEnchants) {
|
||||
if (firstEnchants.getOrDefault(entry.key, entry.value - 1) != entry.value) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// return true if a custom recipe exist with these ingredients
|
||||
fun testCustomRecipe(
|
||||
view: InventoryView, //TODO use anvil view instead
|
||||
inventory: AnvilInventory,
|
||||
player: Player,
|
||||
first: ItemStack, second: ItemStack?
|
||||
): CustomCraftResult {
|
||||
val recipe = CustomRecipeUtil.getCustomRecipe(first, second)
|
||||
CustomAnvil.verboseLog("custom recipe not null? ${recipe != null}")
|
||||
if (recipe == null) return CustomCraftResult.EMPTY
|
||||
|
||||
val amount = CustomRecipeUtil.getCustomRecipeAmount(recipe, first, second)
|
||||
|
||||
val resultItem: ItemStack = DependencyManager.cloneItem(player, recipe.resultItem!!)
|
||||
resultItem.amount *= amount
|
||||
|
||||
// Maybe add an option on custom craft to ignore/not ignore penalty ??
|
||||
val xpCost = recipe.determineCost(amount, first, resultItem)
|
||||
|
||||
val cost = CustomCraftCost(xpCost)
|
||||
// This is for displayed cost
|
||||
cost.recipe = if (recipe.removeExactLinearXp) AnvilXpUtil.calculateMinimumLevelForXp(xpCost)
|
||||
else AnvilXpUtil.calculateLevelForXp(xpCost)
|
||||
|
||||
val result =
|
||||
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.CUSTOM_CRAFT, cost)
|
||||
return CustomCraftResult(result, cost, amount, recipe)
|
||||
}
|
||||
|
||||
fun testUnitRepair(
|
||||
view: InventoryView, //TODO use anvil view
|
||||
inventory: AnvilInventory,
|
||||
player: Player,
|
||||
first: ItemStack, second: ItemStack
|
||||
): UnitRepairResult {
|
||||
val unitRepairAmount = first.getRepair(second) ?: return UnitRepairResult.EMPTY
|
||||
|
||||
return testUnitRepair(view, inventory, player, first, second, unitRepairAmount)
|
||||
}
|
||||
|
||||
fun testUnitRepair(
|
||||
view: InventoryView, //TODO use anvil view instead
|
||||
inventory: AnvilInventory,
|
||||
player: Player,
|
||||
first: ItemStack, second: ItemStack,
|
||||
unitRepairAmount: Double
|
||||
): UnitRepairResult {
|
||||
val resultItem = DependencyManager.cloneItem(player, first)
|
||||
val cost = AnvilCost()
|
||||
cost.rename = handleRename(resultItem, inventory, player)
|
||||
|
||||
val repairAmount = resultItem.unitRepair(second.amount, unitRepairAmount)
|
||||
if (repairAmount > 0)
|
||||
cost.repair = repairAmount * ConfigOptions.unitRepairCost
|
||||
|
||||
// We do not care about right item penalty for unit repair
|
||||
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.UNIT_REPAIR)
|
||||
|
||||
// Test/stop if nothing changed.
|
||||
if (first == resultItem) {
|
||||
CustomAnvil.log("unit repair, But input is same as output")
|
||||
return UnitRepairResult.EMPTY
|
||||
}
|
||||
|
||||
val result =
|
||||
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.UNIT_REPAIR, cost)
|
||||
return UnitRepairResult(result, cost, repairAmount)
|
||||
}
|
||||
|
||||
fun testLoreEdit(
|
||||
player: Player,
|
||||
first: ItemStack, second: ItemStack
|
||||
): LoreEditResult {
|
||||
val type = second.type
|
||||
|
||||
val result = if (Material.WRITABLE_BOOK == type)
|
||||
AnvilLoreEditUtil.tryLoreEditByBook(player, first, second)
|
||||
else if (Material.PAPER == type)
|
||||
AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second)
|
||||
else LoreEditResult.EMPTY
|
||||
|
||||
if (result.isEmpty()) return result
|
||||
|
||||
if (result.item!!.isAir || first == result.item) {
|
||||
CustomAnvil.log("lore edit, But input is same as output")
|
||||
return LoreEditResult.EMPTY
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,60 +1,60 @@
|
|||
package xyz.alexcrea.cuanvil.util
|
||||
package xyz.alexcrea.cuanvil.anvil
|
||||
|
||||
import org.bukkit.Material
|
||||
import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart
|
||||
import xyz.alexcrea.cuanvil.util.config.LoreEditType
|
||||
import xyz.alexcrea.cuanvil.config.WorkPenaltyType
|
||||
import xyz.alexcrea.cuanvil.util.anvil.AnvilUseTypeUtil
|
||||
|
||||
enum class AnvilUseType(
|
||||
val typeName: String, val path: String,
|
||||
val defaultPenalty: WorkPenaltyPart,
|
||||
val defaultPenalty: WorkPenaltyType.WorkPenaltyPart,
|
||||
val displayName: String, val displayMat: Material
|
||||
) {
|
||||
|
||||
RENAME_ONLY(
|
||||
"rename_only",
|
||||
WorkPenaltyPart(false, true),
|
||||
WorkPenaltyType.WorkPenaltyPart(false, true),
|
||||
"Rename Only", Material.NAME_TAG
|
||||
),
|
||||
MERGE(
|
||||
"merge",
|
||||
WorkPenaltyPart(true, true),
|
||||
WorkPenaltyType.WorkPenaltyPart(true, true),
|
||||
"Merge", Material.ANVIL
|
||||
),
|
||||
UNIT_REPAIR(
|
||||
"unit_repair",
|
||||
WorkPenaltyPart(true, true),
|
||||
WorkPenaltyType.WorkPenaltyPart(true, true),
|
||||
"Unit Repair", Material.DIAMOND
|
||||
),
|
||||
CUSTOM_CRAFT(
|
||||
"custom_craft",
|
||||
WorkPenaltyPart(false, false),
|
||||
WorkPenaltyType.WorkPenaltyPart(false, false),
|
||||
"Custom Craft", Material.CRAFTING_TABLE
|
||||
),
|
||||
LORE_EDIT_BOOK_APPEND(
|
||||
"lore_edit_book_append", "lore_edit.book_and_quil.append",
|
||||
WorkPenaltyPart(false, false),
|
||||
WorkPenaltyType.WorkPenaltyPart(false, false),
|
||||
"Book Add", Material.WRITABLE_BOOK
|
||||
),
|
||||
LORE_EDIT_BOOK_REMOVE(
|
||||
"lore_edit_book_remove", "lore_edit.book_and_quil.remove",
|
||||
WorkPenaltyPart(false, false),
|
||||
WorkPenaltyType.WorkPenaltyPart(false, false),
|
||||
"Book Remove", Material.WRITABLE_BOOK
|
||||
),
|
||||
LORE_EDIT_PAPER_APPEND(
|
||||
"lore_edit_paper_append", "lore_edit.paper.append_line",
|
||||
WorkPenaltyPart(false, false),
|
||||
WorkPenaltyType.WorkPenaltyPart(false, false),
|
||||
"Paper Add", Material.WRITABLE_BOOK
|
||||
),
|
||||
LORE_EDIT_PAPER_REMOVE(
|
||||
"lore_edit_paper_remove", "lore_edit.paper.remove_line",
|
||||
WorkPenaltyPart(false, false),
|
||||
WorkPenaltyType.WorkPenaltyPart(false, false),
|
||||
"Paper Remove", Material.WRITABLE_BOOK
|
||||
),
|
||||
;
|
||||
|
||||
constructor(
|
||||
typeName: String,
|
||||
defaultPenalty: WorkPenaltyPart,
|
||||
defaultPenalty: WorkPenaltyType.WorkPenaltyPart,
|
||||
displayName: String, displayMat: Material
|
||||
) :
|
||||
this(
|
||||
|
|
@ -16,7 +16,7 @@ abstract class CASubCommand: CommandExecutor {
|
|||
): Boolean {
|
||||
if(!alreadySaid){
|
||||
sender.sendMessage(ChatColor.RED.toString() +
|
||||
"Please not that this command will be replaced as a subcommand of `/customanvil`")
|
||||
"Please not that this command will be replaced as a subcommand of `/customanvil` or `/ca`")
|
||||
alreadySaid = true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import org.bukkit.plugin.RegisteredListener
|
|||
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
||||
import xyz.alexcrea.cuanvil.dependency.packet.NoPacketManager
|
||||
import xyz.alexcrea.cuanvil.dependency.packet.ProtocoLibWrapper
|
||||
import xyz.alexcrea.cuanvil.dependency.packet.versions.PaperPacketManager
|
||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
|
||||
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
|
||||
import xyz.alexcrea.cuanvil.util.MetricsUtil
|
||||
|
|
|
|||
|
|
@ -1,22 +1,28 @@
|
|||
package xyz.alexcrea.cuanvil.dependency
|
||||
|
||||
import com.maddoxh.superEnchants.SuperEnchants
|
||||
import io.delilaheve.CustomAnvil
|
||||
import net.kyori.adventure.text.Component
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||
import org.bukkit.inventory.AnvilInventory
|
||||
import org.bukkit.inventory.Inventory
|
||||
import org.bukkit.inventory.InventoryView
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilCost
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilUseType
|
||||
import xyz.alexcrea.cuanvil.api.event.listener.CAClickResultBypassEvent
|
||||
import xyz.alexcrea.cuanvil.api.event.listener.CAEarlyPreAnvilBypassEvent
|
||||
import xyz.alexcrea.cuanvil.api.event.listener.CAPreAnvilBypassEvent
|
||||
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent
|
||||
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResult2Event
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||
import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency
|
||||
import xyz.alexcrea.cuanvil.dependency.gui.GenericExternGuiTester
|
||||
import xyz.alexcrea.cuanvil.dependency.gui.GuiTesterSelector
|
||||
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
|
||||
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerSelector
|
||||
import xyz.alexcrea.cuanvil.dependency.plugins.*
|
||||
|
|
@ -26,7 +32,6 @@ import xyz.alexcrea.cuanvil.dependency.scheduler.TaskScheduler
|
|||
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
|
||||
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore
|
||||
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
|
||||
import xyz.alexcrea.cuanvil.util.AnvilUseType
|
||||
import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError
|
||||
import java.util.logging.Level
|
||||
|
||||
|
|
@ -34,7 +39,7 @@ object DependencyManager {
|
|||
|
||||
lateinit var scheduler: TaskScheduler
|
||||
lateinit var packetManager: PacketManager
|
||||
var externGuiTester: GenericExternGuiTester? = null
|
||||
var externGuiTester: GenericExternGuiTester = GenericExternGuiTester()
|
||||
|
||||
var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null
|
||||
var ecoEnchantCompatibility: EcoEnchantDependency? = null
|
||||
|
|
@ -45,6 +50,8 @@ object DependencyManager {
|
|||
|
||||
var axPlayerWarpsCompatibility: AxPlayerWarpsDependency? = null
|
||||
|
||||
var itemsAdderCompatibility: ItemsAdderDependency? = null
|
||||
|
||||
val genericDependencies = ArrayList<GenericPluginDependency>()
|
||||
|
||||
fun loadDependency() {
|
||||
|
|
@ -60,7 +67,6 @@ object DependencyManager {
|
|||
// Packet Manager
|
||||
val forceProtocolib = ConfigHolder.DEFAULT_CONFIG.config.getBoolean("force_protocolib", false)
|
||||
packetManager = PacketManagerSelector.selectPacketManager(forceProtocolib)
|
||||
externGuiTester = GuiTesterSelector.selectGuiTester
|
||||
|
||||
// Enchantment Squared dependency
|
||||
if (pluginManager.isPluginEnabled("EnchantsSquared")) {
|
||||
|
|
@ -97,6 +103,12 @@ object DependencyManager {
|
|||
axPlayerWarpsCompatibility = AxPlayerWarpsDependency()
|
||||
}
|
||||
|
||||
if (pluginManager.isPluginEnabled("ItemsAdder")){
|
||||
val dependency = ItemsAdderDependency(pluginManager.getPlugin("ItemsAdder")!!)
|
||||
itemsAdderCompatibility = dependency
|
||||
genericDependencies.add(dependency)
|
||||
}
|
||||
|
||||
// "Generic" dependencies
|
||||
if (pluginManager.isPluginEnabled("ToolStats"))
|
||||
genericDependencies.add(ToolStatsDependency(pluginManager.getPlugin("ToolStats")!!))
|
||||
|
|
@ -104,6 +116,12 @@ object DependencyManager {
|
|||
if (pluginManager.isPluginEnabled("ItemsAdder"))
|
||||
genericDependencies.add(GenericPluginDependency(pluginManager.getPlugin("ItemsAdder")!!))
|
||||
|
||||
if (pluginManager.isPluginEnabled("SuperEnchants")){
|
||||
val compatibility = SuperEnchantDependency(pluginManager.getPlugin("SuperEnchants")!! as SuperEnchants)
|
||||
if(compatibility.registerEnchantments())
|
||||
genericDependencies.add(compatibility)
|
||||
}
|
||||
|
||||
for (dependency in genericDependencies)
|
||||
dependency.redirectListeners()
|
||||
|
||||
|
|
@ -131,27 +149,35 @@ object DependencyManager {
|
|||
ecoEnchantCompatibility?.handleConfigReload()
|
||||
}
|
||||
|
||||
private fun logException(target: CommandSender, e: Exception) {
|
||||
CustomAnvil.instance.logger.log(
|
||||
Level.SEVERE,
|
||||
"Error while trying to handle custom anvil supported plugin: ",
|
||||
e
|
||||
)
|
||||
trackError(e)
|
||||
|
||||
// Finally, warn the player
|
||||
target.sendMessage(
|
||||
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
|
||||
ChatColor.RED.toString() + "Error while handling the anvil."
|
||||
)
|
||||
}
|
||||
|
||||
private fun logExceptionAndClear(target: CommandSender, inventory: Inventory, e: Exception) {
|
||||
// Just in case to avoid illegal items
|
||||
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
||||
|
||||
logException(target, e)
|
||||
}
|
||||
|
||||
// Return true if should bypass (either by a dependency or error)
|
||||
// called before immutability test
|
||||
fun earlyTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
||||
try {
|
||||
return earlyUnsafeTryEventPreAnvilBypass(event, player)
|
||||
} catch (e: Exception) {
|
||||
CustomAnvil.instance.logger.log(
|
||||
Level.SEVERE,
|
||||
"Error while trying to handle custom anvil supported plugin: ",
|
||||
e
|
||||
)
|
||||
trackError(e)
|
||||
|
||||
// Just in case to avoid illegal items
|
||||
event.inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
||||
|
||||
// Finally, warn the player, maybe a lot of time but better warn than do nothing
|
||||
event.view.player.sendMessage(
|
||||
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
|
||||
ChatColor.RED.toString() + "Error while handling the anvil."
|
||||
)
|
||||
logExceptionAndClear(event.view.player, event.inventory, e)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -164,7 +190,7 @@ object DependencyManager {
|
|||
var bypass = bypassEvent.isCancelled
|
||||
|
||||
// Test if the inventory is a gui(version specific)
|
||||
if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true
|
||||
if (!bypass && externGuiTester.testIfGui(event.view)) bypass = true
|
||||
|
||||
// Test if in an ax player warp rating gui
|
||||
if (!bypass && (axPlayerWarpsCompatibility?.testIfGui(player) == true)) bypass = true
|
||||
|
|
@ -173,30 +199,16 @@ object DependencyManager {
|
|||
}
|
||||
|
||||
// Return true if should bypass (either by a dependency or error)
|
||||
fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
||||
fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: Player): Boolean {
|
||||
try {
|
||||
return unsafeTryEventPreAnvilBypass(event, player)
|
||||
} catch (e: Exception) {
|
||||
CustomAnvil.instance.logger.log(
|
||||
Level.SEVERE,
|
||||
"Error while trying to handle custom anvil supported plugin: ",
|
||||
e
|
||||
)
|
||||
trackError(e)
|
||||
|
||||
// Just in case to avoid illegal items
|
||||
event.inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
||||
|
||||
// Finally, warn the player, maybe a lot of time but better warn than do nothing
|
||||
event.view.player.sendMessage(
|
||||
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
|
||||
ChatColor.RED.toString() + "Error while handling the anvil."
|
||||
)
|
||||
logExceptionAndClear(event.view.player, event.inventory, e)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private fun unsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
||||
private fun unsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: Player): Boolean {
|
||||
// Run the event
|
||||
val bypassEvent = CAPreAnvilBypassEvent(event)
|
||||
Bukkit.getPluginManager().callEvent(bypassEvent)
|
||||
|
|
@ -221,36 +233,24 @@ object DependencyManager {
|
|||
|
||||
// Return null if there was an issue
|
||||
fun tryTreatAnvilResult(
|
||||
event: PrepareAnvilEvent,
|
||||
view: InventoryView,
|
||||
inventory: Inventory, // TODO REMOVE, use view instead on legacy removal
|
||||
player: HumanEntity,
|
||||
result: ItemStack,
|
||||
useType: AnvilUseType,
|
||||
cost: Int
|
||||
): CATreatAnvilResultEvent? {
|
||||
val treatEvent = CATreatAnvilResultEvent(event, useType, result, cost)
|
||||
cost: AnvilCost
|
||||
): ItemStack? {
|
||||
val treatEvent = CATreatAnvilResult2Event(view, inventory, useType, result, cost)
|
||||
try {
|
||||
unsafeTryTreatAnvilResult(treatEvent)
|
||||
return treatEvent;
|
||||
return treatEvent.result
|
||||
} catch (e: Exception) {
|
||||
CustomAnvil.instance.logger.log(
|
||||
Level.SEVERE,
|
||||
"Error while trying to handle custom anvil supported plugin: ",
|
||||
e
|
||||
)
|
||||
trackError(e)
|
||||
|
||||
// Just in case to avoid illegal items
|
||||
event.inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
||||
|
||||
// Finally, warn the player, maybe a lot of time but better warn than do nothing
|
||||
event.view.player.sendMessage(
|
||||
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
|
||||
ChatColor.RED.toString() + "Error while handling the anvil."
|
||||
)
|
||||
logExceptionAndClear(player, inventory, e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResultEvent) {
|
||||
private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResult2Event) {
|
||||
Bukkit.getPluginManager().callEvent(event)
|
||||
|
||||
excellentEnchantsCompatibility?.treatAnvilResult(event)
|
||||
|
|
@ -261,21 +261,7 @@ object DependencyManager {
|
|||
try {
|
||||
return unsafeTryClickAnvilResultBypass(event, inventory)
|
||||
} catch (e: Exception) {
|
||||
CustomAnvil.instance.logger.log(
|
||||
Level.SEVERE,
|
||||
"Error while trying to handle custom anvil supported plugin: ",
|
||||
e
|
||||
)
|
||||
trackError(e)
|
||||
|
||||
// Just in case to avoid illegal items
|
||||
event.inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
||||
|
||||
// Finally, warn the player, maybe a lot of time but better warn than do nothing
|
||||
event.whoClicked.sendMessage(
|
||||
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
|
||||
ChatColor.RED.toString() + "Error while handling the anvil."
|
||||
)
|
||||
logExceptionAndClear(event.view.player, event.inventory, e)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -301,7 +287,7 @@ object DependencyManager {
|
|||
}
|
||||
|
||||
// Test if the inventory is a gui(version specific)
|
||||
if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true
|
||||
if (!bypass && externGuiTester.testIfGui(event.view)) bypass = true
|
||||
|
||||
// Test if in an ax player warp rating gui
|
||||
if (!bypass && (axPlayerWarpsCompatibility?.testIfGui(event.view.player) == true)) bypass = true
|
||||
|
|
@ -309,6 +295,23 @@ object DependencyManager {
|
|||
return bypass
|
||||
}
|
||||
|
||||
// Clone item and use plugin specific clone if needed
|
||||
fun cloneItem(player: HumanEntity, item: ItemStack): ItemStack {
|
||||
try {
|
||||
return unsafeCloneItem(item)
|
||||
} catch (e: Exception) {
|
||||
logException(player, e)
|
||||
return item.clone()
|
||||
}
|
||||
}
|
||||
|
||||
private fun unsafeCloneItem(item: ItemStack): ItemStack {
|
||||
val cloned = itemsAdderCompatibility?.tryClone(item)
|
||||
if(cloned != null) return cloned
|
||||
|
||||
return item.clone()
|
||||
}
|
||||
|
||||
fun stripLore(item: ItemStack): MutableList<Component?> {
|
||||
val dummy = item.clone()
|
||||
|
||||
|
|
|
|||
|
|
@ -6,29 +6,29 @@ object MinecraftVersionUtil {
|
|||
|
||||
val craftbukkitVersion: String?
|
||||
get() {
|
||||
val versionParts = UpdateUtils.currentMinecraftVersionArray()
|
||||
if (versionParts[0] != 1) return null
|
||||
val version = UpdateUtils.currentMinecraftVersion()
|
||||
if (version.major != 1) return null
|
||||
|
||||
return when (versionParts[1]) {
|
||||
17 -> when (versionParts[2]) {
|
||||
return when (version.minor) {
|
||||
17 -> when (version.patch) {
|
||||
0, 1 -> "1_17R1"
|
||||
else -> null
|
||||
}
|
||||
|
||||
18 -> when (versionParts[2]) {
|
||||
18 -> when (version.patch) {
|
||||
0, 1 -> "1_18R1"
|
||||
2 -> "1_18R2"
|
||||
else -> null
|
||||
}
|
||||
|
||||
19 -> when (versionParts[2]) {
|
||||
19 -> when (version.patch) {
|
||||
0, 1, 2 -> "1_19R1"
|
||||
3 -> "1_19R2"
|
||||
4 -> "1_19R3"
|
||||
else -> null
|
||||
}
|
||||
|
||||
20 -> when (versionParts[2]) {
|
||||
20 -> when (version.patch) {
|
||||
0, 1 -> "1_20R1"
|
||||
2 -> "1_20R2"
|
||||
3, 4 -> "1_20R3"
|
||||
|
|
@ -36,7 +36,7 @@ object MinecraftVersionUtil {
|
|||
else -> null
|
||||
}
|
||||
|
||||
21 -> when (versionParts[2]) {
|
||||
21 -> when (version.patch) {
|
||||
0, 1 -> "1_21R1"
|
||||
2, 3 -> "1_21R2"
|
||||
4 -> "1_21R3"
|
||||
|
|
@ -51,4 +51,8 @@ object MinecraftVersionUtil {
|
|||
}
|
||||
}
|
||||
|
||||
val isTooNewForSpigot: Boolean get() {
|
||||
return UpdateUtils.currentMinecraftVersion().major != 1
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ import xyz.alexcrea.cuanvil.update.Version
|
|||
import java.io.InputStreamReader
|
||||
|
||||
object DataPackDependency {
|
||||
private val START_DETECT_VERSION = Version(1, 19, 0)
|
||||
private val START_DETECT_VERSION = Version(1, 20, 5)
|
||||
|
||||
/**
|
||||
* Map of the latest CustomAnvil update related to the pack
|
||||
|
|
@ -145,7 +145,7 @@ object DataPackDependency {
|
|||
CustomAnvil.instance.logger.warning("Could not find material $name for item group $groupName")
|
||||
continue
|
||||
}
|
||||
group.addToPolicy(mat)
|
||||
group.addToPolicy(mat.key)
|
||||
}
|
||||
for (name in section.getStringList("groups")) {
|
||||
val otherGroup = MaterialGroupApi.getGroup(name)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
package xyz.alexcrea.cuanvil.dependency.economy
|
||||
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.plugin.Plugin
|
||||
import java.math.BigDecimal
|
||||
|
||||
interface EconomyManager {
|
||||
|
||||
companion object {
|
||||
var economy: EconomyManager? = null
|
||||
|
||||
fun setupEconomy(plugin: Plugin) {
|
||||
if (plugin.server.pluginManager.getPlugin("Vault") == null)
|
||||
return
|
||||
if (UnlockedEconomyManager.unlockedAvailable())
|
||||
economy = UnlockedEconomyManager(plugin)
|
||||
|
||||
if (economy == null || !economy!!.initialized())
|
||||
economy = VaultEconomyManager(plugin)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun initialized(): Boolean
|
||||
|
||||
// We assume "initialized" got checked before these function get called
|
||||
fun has(player: Player, money: BigDecimal): Boolean
|
||||
fun remove(player: Player, money: BigDecimal): Boolean
|
||||
|
||||
fun format(money: BigDecimal): String;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package xyz.alexcrea.cuanvil.dependency.economy
|
||||
|
||||
import io.delilaheve.util.ConfigOptions
|
||||
import net.milkbowl.vault2.economy.Economy
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.plugin.Plugin
|
||||
import java.math.BigDecimal
|
||||
|
||||
class UnlockedEconomyManager : EconomyManager {
|
||||
|
||||
val plugin: String
|
||||
val economy: Economy?
|
||||
|
||||
companion object {
|
||||
fun unlockedAvailable(): Boolean {
|
||||
try {
|
||||
Class.forName("net.milkbowl.vault2.economy.Economy")
|
||||
return true
|
||||
} catch (_: ClassNotFoundException) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor(plugin: Plugin) {
|
||||
this.plugin = plugin.name
|
||||
|
||||
val rsp = plugin.server.servicesManager.getRegistration(Economy::class.java)
|
||||
economy = rsp?.getProvider()
|
||||
}
|
||||
|
||||
override fun initialized(): Boolean {
|
||||
return economy != null
|
||||
}
|
||||
|
||||
private fun currency(): String {
|
||||
val configured = ConfigOptions.usedCurrency
|
||||
|
||||
return if ("default".equals(configured, true))
|
||||
economy!!.getDefaultCurrency(plugin)
|
||||
else configured
|
||||
}
|
||||
|
||||
override fun has(player: Player, money: BigDecimal): Boolean {
|
||||
if (money.signum() <= 0) return true
|
||||
|
||||
return economy!!.has(
|
||||
plugin,
|
||||
player.uniqueId,
|
||||
player.world.name,
|
||||
currency(),
|
||||
money
|
||||
)
|
||||
}
|
||||
|
||||
override fun remove(player: Player, money: BigDecimal): Boolean {
|
||||
if (money.signum() <= 0) return true
|
||||
|
||||
return economy!!.withdraw(
|
||||
plugin,
|
||||
player.uniqueId,
|
||||
player.world.name,
|
||||
currency(),
|
||||
money
|
||||
)
|
||||
.transactionSuccess()
|
||||
}
|
||||
|
||||
override fun format(money: BigDecimal): String {
|
||||
return economy!!.format(plugin, money, currency())
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package xyz.alexcrea.cuanvil.dependency.economy
|
||||
|
||||
import net.milkbowl.vault.economy.Economy
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.plugin.Plugin
|
||||
import java.math.BigDecimal
|
||||
|
||||
class VaultEconomyManager : EconomyManager {
|
||||
|
||||
val economy: Economy?
|
||||
|
||||
constructor(plugin: Plugin) {
|
||||
val rsp = plugin.server.servicesManager.getRegistration(Economy::class.java)
|
||||
economy = rsp?.getProvider()
|
||||
}
|
||||
|
||||
override fun initialized(): Boolean {
|
||||
return economy != null
|
||||
}
|
||||
|
||||
override fun has(player: Player, money: BigDecimal): Boolean {
|
||||
if (money.signum() <= 0) return true
|
||||
|
||||
return economy!!.has(player, money.toDouble())
|
||||
}
|
||||
|
||||
override fun remove(player: Player, money: BigDecimal): Boolean {
|
||||
if (money.signum() <= 0) return true
|
||||
|
||||
return economy!!.withdrawPlayer(player, money.toDouble()).transactionSuccess()
|
||||
}
|
||||
|
||||
override fun format(money: BigDecimal): String {
|
||||
return economy!!.format(money.toDouble())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -36,6 +36,11 @@ class GenericExternGuiTester {
|
|||
getHandleMethod = clazz.getMethod(HANDLE_METHOD_NAME)
|
||||
}
|
||||
|
||||
fun isInTest(): Boolean {
|
||||
if(!testExist) testClassExist()
|
||||
return inTesting
|
||||
}
|
||||
|
||||
fun testClassExist() {
|
||||
testExist = true
|
||||
|
||||
|
|
@ -61,8 +66,7 @@ class GenericExternGuiTester {
|
|||
// Try if were in another plugin anvil inventory
|
||||
fun testIfGui(inventory: InventoryView): Boolean {
|
||||
// In case we are in a test environment
|
||||
if(!testExist) testClassExist()
|
||||
if(inTesting) return false
|
||||
if(isInTest()) return false
|
||||
|
||||
val clazz = getContainerClass(inventory) ?: return false
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
package xyz.alexcrea.cuanvil.dependency.gui
|
||||
|
||||
import xyz.alexcrea.cuanvil.update.UpdateUtils
|
||||
|
||||
object GuiTesterSelector {
|
||||
|
||||
val selectGuiTester: GenericExternGuiTester?
|
||||
get() {
|
||||
val versionParts = UpdateUtils.currentMinecraftVersionArray()
|
||||
if (versionParts[0] != 1) return null
|
||||
|
||||
return GenericExternGuiTester()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,21 +1,31 @@
|
|||
package xyz.alexcrea.cuanvil.dependency.packet
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import su.nightexpress.nightcore.bridge.paper.PaperBridge
|
||||
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
||||
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil
|
||||
import xyz.alexcrea.cuanvil.dependency.packet.versions.*
|
||||
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
|
||||
import xyz.alexcrea.cuanvil.update.UpdateUtils
|
||||
|
||||
object PacketManagerSelector {
|
||||
|
||||
private const val PAPER_CRAFT_PLAYER_CLASS = "org.bukkit.craftbukkit.entity.CraftPlayer"
|
||||
|
||||
fun selectPacketManager(forceProtocolib: Boolean): PacketManager {
|
||||
// Try to find version
|
||||
if(DependencyManager.externGuiTester.isInTest())
|
||||
return NoPacketManager()
|
||||
|
||||
return if (forceProtocolib)
|
||||
protocolibIfPresent
|
||||
else
|
||||
reobfPacketManager ?:
|
||||
if(PlatformUtil.isPaper) PaperPacketManager()
|
||||
else protocolibIfPresent
|
||||
else {
|
||||
try {
|
||||
Class.forName(PAPER_CRAFT_PLAYER_CLASS)
|
||||
|
||||
return PaperPacketManager()
|
||||
} catch (_: ClassNotFoundException) {
|
||||
return reobfPacketManager ?: protocolibIfPresent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val protocolibIfPresent: PacketManager
|
||||
|
|
@ -28,8 +38,8 @@ object PacketManagerSelector {
|
|||
// Reobfuscated packet manager for spigot or paper as it remap
|
||||
private val reobfPacketManager: PacketManagerBase?
|
||||
get() {
|
||||
val versionParts = UpdateUtils.currentMinecraftVersionArray()
|
||||
if (versionParts[0] != 1) return null
|
||||
val versionParts = UpdateUtils.currentMinecraftVersion()
|
||||
if (versionParts.major != 1) return null
|
||||
|
||||
try {
|
||||
val clazz = Class.forName("xyz.alexcrea.cuanvil.dependency.packet.versions." +
|
||||
|
|
@ -37,7 +47,7 @@ object PacketManagerSelector {
|
|||
|
||||
val manager = clazz.getConstructor().newInstance()
|
||||
return manager as PacketManagerBase
|
||||
} catch (e: ClassNotFoundException) {
|
||||
} catch (_: ClassNotFoundException) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,15 +8,16 @@ import com.jankominek.disenchantment.events.ShatterEvent
|
|||
import com.jankominek.disenchantment.listeners.DisenchantClickListener
|
||||
import com.jankominek.disenchantment.listeners.ShatterClickListener
|
||||
import io.delilaheve.CustomAnvil
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||
import org.bukkit.inventory.AnvilInventory
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilCost
|
||||
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
|
||||
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
|
||||
import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError
|
||||
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
|
||||
import java.util.logging.Level
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
|
@ -50,7 +51,7 @@ class DisenchantmentDependency {
|
|||
InventoryClickEvent.getHandlerList().unregister(listener)
|
||||
}
|
||||
|
||||
fun testPrepareAnvil(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
||||
fun testPrepareAnvil(event: PrepareAnvilEvent, player: Player): Boolean {
|
||||
val previousResult = event.result
|
||||
event.result = null
|
||||
|
||||
|
|
@ -58,14 +59,14 @@ class DisenchantmentDependency {
|
|||
DisenchantEvent.onEvent(event)
|
||||
if (event.result != null) {
|
||||
CustomAnvil.log("Detected pre anvil item extract bypass.")
|
||||
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
|
||||
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
|
||||
return true
|
||||
}
|
||||
|
||||
ShatterEvent.onEvent(event)
|
||||
if (event.result != null) {
|
||||
CustomAnvil.log("Detected pre anvil split enchant bypass.")
|
||||
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
|
||||
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package xyz.alexcrea.cuanvil.dependency.plugins
|
||||
|
||||
import com.willfp.ecoitems.items.EcoItem
|
||||
import com.willfp.ecoitems.items.EcoItems
|
||||
import com.willfp.ecoitems.items.ecoItem
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
object EcoItemDependencyUtil {
|
||||
|
||||
fun ecoItemNamespace(item: ItemStack): NamespacedKey? {
|
||||
val ecoi = item.ecoItem ?: return null
|
||||
|
||||
return ecoi.id
|
||||
}
|
||||
|
||||
fun ecoItemFromKey(key: NamespacedKey): EcoItem? {
|
||||
return EcoItems.getByID(key.toString())
|
||||
}
|
||||
|
||||
fun ecoItemMaterialFromKey(key: NamespacedKey): Material? {
|
||||
val ecoi = ecoItemFromKey(key) ?: return null
|
||||
|
||||
return ecoi.itemStack.type
|
||||
}
|
||||
|
||||
fun newEcoItemstack(key: NamespacedKey): ItemStack? {
|
||||
val ecoi = ecoItemFromKey(key) ?: return null
|
||||
|
||||
return ecoi.itemStack
|
||||
}
|
||||
|
||||
fun getItems(): List<NamespacedKey> {
|
||||
return EcoItems.values().map { item -> item.id }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -102,15 +102,15 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
|
|||
private fun writeMissingGroups(){
|
||||
// Write group that do not exist on custom anvil.
|
||||
val shield = IncludeGroup("shield")
|
||||
shield.addToPolicy(Material.SHIELD)
|
||||
shield.addToPolicy(Material.SHIELD.key)
|
||||
MaterialGroupApi.addMaterialGroup(shield)
|
||||
|
||||
val elytra = IncludeGroup("elytra")
|
||||
elytra.addToPolicy(Material.ELYTRA)
|
||||
elytra.addToPolicy(Material.ELYTRA.key)
|
||||
MaterialGroupApi.addMaterialGroup(elytra)
|
||||
|
||||
val trinkets = IncludeGroup("trinkets")
|
||||
trinkets.addToPolicy(Material.ROTTEN_FLESH)
|
||||
trinkets.addToPolicy(Material.ROTTEN_FLESH.key)
|
||||
MaterialGroupApi.addMaterialGroup(trinkets)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ import org.bukkit.event.inventory.PrepareAnvilEvent
|
|||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.plugin.RegisteredListener
|
||||
import xyz.alexcrea.cuanvil.api.EnchantmentApi
|
||||
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent
|
||||
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResult2Event
|
||||
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment
|
||||
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment
|
||||
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5_4Enchantment
|
||||
import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEEEnchantment
|
||||
import java.lang.reflect.Constructor
|
||||
import java.lang.reflect.Method
|
||||
import su.nightexpress.excellentenchants.api.EnchantRegistry as V5EnchantRegistry
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.universal.CurseOfFragilityEnchant as LegacyCurseOfFragilityEnchant
|
||||
|
|
@ -25,6 +27,7 @@ import su.nightexpress.excellentenchants.registry.EnchantRegistry as PreV5Enchan
|
|||
class ExcellentEnchantsDependency {
|
||||
|
||||
enum class ListenerVersion(val classPath: String) {
|
||||
V5_4("su.nightexpress.excellentenchants.enchantment.EnchantSettings"),
|
||||
V5_3("su.nightexpress.excellentenchants.enchantment.EnchantRegistry"),
|
||||
V5("su.nightexpress.excellentenchants.manager.listener.AnvilListener"),
|
||||
PRE_V5("su.nightexpress.excellentenchants.enchantment.listener.AnvilListener"),
|
||||
|
|
@ -70,14 +73,14 @@ class ExcellentEnchantsDependency {
|
|||
|
||||
// As excellent enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant.
|
||||
when (listenerVersion) {
|
||||
ListenerVersion.V5_3 -> {
|
||||
ListenerVersion.V5_4 -> {
|
||||
for (enchantment in ExcellentEnchant5_3Registry.getRegistered()) {
|
||||
EnchantmentApi.unregisterEnchantment(enchantment.bukkitEnchantment.key)
|
||||
EnchantmentApi.registerEnchantment(CAEEV5Enchantment(enchantment))
|
||||
EnchantmentApi.registerEnchantment(CAEEV5_4Enchantment(enchantment))
|
||||
}
|
||||
}
|
||||
|
||||
ListenerVersion.V5 -> {
|
||||
ListenerVersion.V5, ListenerVersion.V5_3 -> {
|
||||
for (enchantment in V5EnchantRegistry.getRegistered()) {
|
||||
EnchantmentApi.unregisterEnchantment(enchantment.bukkitEnchantment.key)
|
||||
EnchantmentApi.registerEnchantment(CAEEV5Enchantment(enchantment))
|
||||
|
|
@ -115,6 +118,8 @@ class ExcellentEnchantsDependency {
|
|||
private lateinit var handleRechargeMethod: Method
|
||||
private lateinit var handleCombineMethod: Method
|
||||
|
||||
private val prepareAnvilConstructor = PrepareAnvilEvent::class.java.constructors.first() as Constructor<PrepareAnvilEvent>
|
||||
|
||||
fun redirectListeners() {
|
||||
val toUnregister = ArrayList<RegisteredListener>()
|
||||
// get required PrepareAnvilEvent listener
|
||||
|
|
@ -130,7 +135,8 @@ class ExcellentEnchantsDependency {
|
|||
|
||||
when (listenerVersion) {
|
||||
ListenerVersion.V5,
|
||||
ListenerVersion.V5_3
|
||||
ListenerVersion.V5_3,
|
||||
ListenerVersion.V5_4,
|
||||
-> {
|
||||
if (listener is V5AnvilListener) {
|
||||
this.v5AnvilListener = listener
|
||||
|
|
@ -165,6 +171,7 @@ class ExcellentEnchantsDependency {
|
|||
when (listenerVersion) {
|
||||
ListenerVersion.V5_3,
|
||||
ListenerVersion.V5,
|
||||
ListenerVersion.V5_4,
|
||||
-> this.usedAnvilListener = v5AnvilListener!!
|
||||
ListenerVersion.PRE_V5 -> this.usedAnvilListener = preV5AnvilListener!!
|
||||
ListenerVersion.LEGACY -> this.usedAnvilListener = legacyAnvilListener!!
|
||||
|
|
@ -214,21 +221,24 @@ class ExcellentEnchantsDependency {
|
|||
return handleRechargeMethod.invoke(this.usedAnvilListener, event, first, second) as Boolean
|
||||
}
|
||||
|
||||
fun treatAnvilResult(event: CATreatAnvilResultEvent) {
|
||||
val result = event.result
|
||||
if (result == null) return
|
||||
fun treatAnvilResult(event: CATreatAnvilResult2Event) {
|
||||
val result = event.result ?: return
|
||||
|
||||
val first: ItemStack = treatInput(event.event.inventory.getItem(0))
|
||||
val second: ItemStack = treatInput(event.event.inventory.getItem(1))
|
||||
val first: ItemStack = treatInput(event.leftItem)
|
||||
val second: ItemStack = treatInput(event.rightItem)
|
||||
val fakeEvent = prepareAnvilConstructor.newInstance(event.view, result)
|
||||
|
||||
handleCombineMethod.invoke(this.usedAnvilListener, event.event, first, second, result)
|
||||
handleCombineMethod.invoke(this.usedAnvilListener, fakeEvent, first, second, result)
|
||||
|
||||
event.result = fakeEvent.result
|
||||
}
|
||||
|
||||
fun testAnvilResult(event: InventoryClickEvent): Any {
|
||||
if (event.inventory.getItem(2) != null) {
|
||||
when (listenerVersion) {
|
||||
ListenerVersion.V5,
|
||||
ListenerVersion.V5_3
|
||||
ListenerVersion.V5_3,
|
||||
ListenerVersion.V5_4,
|
||||
-> v5AnvilListener!!.onClickAnvil(event)
|
||||
ListenerVersion.PRE_V5 -> preV5AnvilListener!!.onClickAnvil(event)
|
||||
ListenerVersion.LEGACY -> legacyAnvilListener!!.onClickAnvil(event)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import org.bukkit.event.inventory.PrepareAnvilEvent
|
|||
import org.bukkit.plugin.Plugin
|
||||
import org.bukkit.plugin.RegisteredListener
|
||||
|
||||
open class GenericPluginDependency(protected val plugin: Plugin) {
|
||||
open class GenericPluginDependency(protected open val plugin: Plugin, private val testPrepare: Boolean = true) {
|
||||
|
||||
private val preAnvil = ArrayList<RegisteredListener>()
|
||||
private val postAnvil = ArrayList<RegisteredListener>()
|
||||
|
|
@ -40,11 +40,19 @@ open class GenericPluginDependency(protected val plugin: Plugin) {
|
|||
}
|
||||
|
||||
open fun testPrepareAnvil(event: PrepareAnvilEvent): Boolean {
|
||||
if(!testPrepare) return false
|
||||
|
||||
val previousResult = event.result
|
||||
event.result = null
|
||||
|
||||
for (registeredListener in preAnvil) {
|
||||
registeredListener.callEvent(event)
|
||||
// We do not want error from another plugin to be our fault
|
||||
try {
|
||||
registeredListener.callEvent(event)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
if (event.result != null) return true
|
||||
}
|
||||
|
||||
|
|
@ -53,8 +61,15 @@ open class GenericPluginDependency(protected val plugin: Plugin) {
|
|||
}
|
||||
|
||||
open fun testAnvilResult(event: InventoryClickEvent): Boolean {
|
||||
if(!testPrepare) return false
|
||||
|
||||
for (registeredListener in postAnvil) {
|
||||
registeredListener.callEvent(event)
|
||||
// We do not want error from another plugin to be our fault
|
||||
try {
|
||||
registeredListener.callEvent(event)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
if (event.inventory.getItem(2) == null) return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package xyz.alexcrea.cuanvil.dependency.plugins
|
||||
|
||||
import io.delilaheve.CustomAnvil
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||
import org.bukkit.inventory.AnvilInventory
|
||||
|
|
@ -9,8 +9,9 @@ import org.bukkit.plugin.RegisteredListener
|
|||
import valorless.havenbags.HavenBags
|
||||
import valorless.havenbags.features.BagSkin
|
||||
import valorless.havenbags.features.BagUpgrade
|
||||
import xyz.alexcrea.cuanvil.anvil.AnvilCost
|
||||
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
|
||||
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
|
||||
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
|
||||
|
||||
class HavenBagsDependency {
|
||||
|
||||
|
|
@ -45,7 +46,7 @@ class HavenBagsDependency {
|
|||
|
||||
}
|
||||
|
||||
fun testPrepareAnvil(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
||||
fun testPrepareAnvil(event: PrepareAnvilEvent, player: Player): Boolean {
|
||||
val previousResult = event.result
|
||||
event.result = null
|
||||
|
||||
|
|
@ -53,14 +54,14 @@ class HavenBagsDependency {
|
|||
bagSkin.onPrepareAnvil(event)
|
||||
if (event.result != null) {
|
||||
CustomAnvil.log("Detected pre anvil heaven bag anvil skin.")
|
||||
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
|
||||
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
|
||||
return true
|
||||
}
|
||||
|
||||
bagUpgrade.onPrepareAnvil(event)
|
||||
if (event.result != null) {
|
||||
CustomAnvil.log("Detected pre anvil heaven bag anvil upgrade.")
|
||||
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
|
||||
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
package xyz.alexcrea.cuanvil.dependency.plugins
|
||||
|
||||
import dev.lone.itemsadder.api.CustomStack
|
||||
import dev.lone.itemsadder.api.ItemsAdder
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.plugin.Plugin
|
||||
|
||||
class ItemsAdderDependency(plugin: Plugin) : GenericPluginDependency(plugin) {
|
||||
var isLoaded: Boolean = false
|
||||
get() {
|
||||
if (field) return true
|
||||
|
||||
// We can't be sure the event is registered before being triggered so we need to use this function
|
||||
field = ItemsAdder.areItemsLoaded()
|
||||
return field
|
||||
}
|
||||
|
||||
fun tryClone(item: ItemStack): ItemStack? {
|
||||
if(!isLoaded) return null
|
||||
val customItem = CustomStack.byItemStack(item) ?: return null
|
||||
|
||||
return CustomStack.getInstance(customItem.namespacedID)?.itemStack
|
||||
}
|
||||
|
||||
fun fromKey(key: NamespacedKey): ItemStack? {
|
||||
if(!isLoaded) return null
|
||||
return CustomStack.getInstance(key.toString())?.itemStack
|
||||
}
|
||||
|
||||
fun getKey(item: ItemStack) : NamespacedKey? {
|
||||
if(!isLoaded) return null
|
||||
val customItem = CustomStack.byItemStack(item) ?: return null
|
||||
|
||||
return NamespacedKey.fromString(customItem.namespacedID)
|
||||
}
|
||||
|
||||
fun idsCount(): Set<String> {
|
||||
return CustomStack.getNamespacedIdsInRegistry()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package xyz.alexcrea.cuanvil.dependency.plugins
|
||||
|
||||
import com.maddoxh.superEnchants.SuperEnchants
|
||||
import com.maddoxh.superEnchants.enchants.EnchantManager
|
||||
import com.maddoxh.superEnchants.listeners.AnvilListener
|
||||
import io.delilaheve.CustomAnvil
|
||||
import org.bukkit.command.Command
|
||||
import org.bukkit.command.CommandExecutor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.plugin.RegisteredListener
|
||||
import xyz.alexcrea.cuanvil.api.EnchantmentApi
|
||||
import xyz.alexcrea.cuanvil.enchant.bulk.SuperEnchantBulkOperation
|
||||
import xyz.alexcrea.cuanvil.enchant.wrapped.CASuperEnchantEnchantment
|
||||
import java.util.logging.Level
|
||||
|
||||
class SuperEnchantDependency(override val plugin: SuperEnchants): GenericPluginDependency(plugin, false) {
|
||||
|
||||
lateinit var enchManager: EnchantManager
|
||||
val enchantments = ArrayList<CASuperEnchantEnchantment>()
|
||||
|
||||
fun registerEnchantments(): Boolean{
|
||||
CustomAnvil.instance.logger.info("Preparing Super Enchant compatibility...")
|
||||
|
||||
val field = SuperEnchants::class.java.getDeclaredField("enchantManager")
|
||||
if(field == null) {
|
||||
CustomAnvil.instance.logger.log(Level.SEVERE, "Failed to initialize Super Enchant compatibility")
|
||||
return false
|
||||
}
|
||||
field.setAccessible(true)
|
||||
|
||||
val bulkOpperations = SuperEnchantBulkOperation(plugin)
|
||||
EnchantmentApi.addBulkGet(bulkOpperations)
|
||||
EnchantmentApi.addBulkClean(bulkOpperations)
|
||||
|
||||
enchManager = field.get(plugin) as EnchantManager
|
||||
overrideReloadCommand()
|
||||
|
||||
reload()
|
||||
return true
|
||||
}
|
||||
|
||||
fun reload() {
|
||||
for (enchantment in enchantments) {
|
||||
EnchantmentApi.unregisterEnchantment(enchantment)
|
||||
}
|
||||
enchantments.clear()
|
||||
|
||||
// Register enchantments
|
||||
for (enchant in enchManager.getAll()) {
|
||||
val enchantment = CASuperEnchantEnchantment(enchant, plugin, enchManager)
|
||||
enchantments.add(enchantment)
|
||||
|
||||
EnchantmentApi.registerEnchantment(enchantment)
|
||||
}
|
||||
}
|
||||
|
||||
private fun overrideReloadCommand() {
|
||||
val reload = CustomAnvil.instance.getCommand("sereload")
|
||||
|
||||
reload?.setExecutor(ReloadInterceptor(reload.executor))
|
||||
}
|
||||
|
||||
inner class ReloadInterceptor(val other: CommandExecutor): CommandExecutor {
|
||||
|
||||
override fun onCommand(
|
||||
sender: CommandSender,
|
||||
command: Command,
|
||||
label: String,
|
||||
args: Array<out String?>
|
||||
): Boolean {
|
||||
val result = other.onCommand(sender, command, label, args)
|
||||
|
||||
CustomAnvil.log("Detected SuperEnchant reload")
|
||||
reload()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun fillPostAnvil(postAnvil: ArrayList<RegisteredListener>, preAnvil: ArrayList<RegisteredListener>) {
|
||||
|
||||
for (registeredListener in InventoryClickEvent.getHandlerList().registeredListeners) {
|
||||
|
||||
if (registeredListener.listener.javaClass != AnvilListener::class.java) continue
|
||||
postAnvil.add(registeredListener)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
package xyz.alexcrea.cuanvil.group
|
||||
|
||||
import org.bukkit.Material
|
||||
import java.util.*
|
||||
import org.bukkit.NamespacedKey
|
||||
import xyz.alexcrea.cuanvil.util.MaterialUtil
|
||||
|
||||
abstract class AbstractMaterialGroup(private val name: String) {
|
||||
protected val includedMaterial by lazy { createDefaultSet() }
|
||||
|
|
@ -9,12 +10,12 @@ abstract class AbstractMaterialGroup(private val name: String) {
|
|||
/**
|
||||
* Get the group default set
|
||||
*/
|
||||
protected abstract fun createDefaultSet(): EnumSet<Material>
|
||||
protected abstract fun createDefaultSet(): MutableSet<NamespacedKey>
|
||||
|
||||
/**
|
||||
* Get if a material is allowed following the group policy
|
||||
*/
|
||||
open fun contain(mat: Material): Boolean {
|
||||
open fun contain(mat: NamespacedKey): Boolean {
|
||||
return mat in getMaterials()
|
||||
}
|
||||
|
||||
|
|
@ -27,13 +28,13 @@ abstract class AbstractMaterialGroup(private val name: String) {
|
|||
* Push a material to this group to follow this group policy
|
||||
* @return this instance.
|
||||
*/
|
||||
abstract fun addToPolicy(mat: Material): AbstractMaterialGroup
|
||||
abstract fun addToPolicy(type: NamespacedKey): AbstractMaterialGroup
|
||||
|
||||
/**
|
||||
* Push a list of material to this group to follow this group policy
|
||||
* @return this instance.
|
||||
*/
|
||||
fun addAll(vararg materials: Material): AbstractMaterialGroup {
|
||||
fun addAll(vararg materials: NamespacedKey): AbstractMaterialGroup {
|
||||
for (material in materials) {
|
||||
addToPolicy(material)
|
||||
}
|
||||
|
|
@ -60,19 +61,19 @@ abstract class AbstractMaterialGroup(private val name: String) {
|
|||
/**
|
||||
* Get the group contained material as a set
|
||||
*/
|
||||
abstract fun getMaterials(): EnumSet<Material>
|
||||
abstract fun getMaterials(): Set<NamespacedKey>
|
||||
|
||||
/**
|
||||
* Get the group non-inherited material as a set
|
||||
*/
|
||||
open fun getNonGroupInheritedMaterials(): EnumSet<Material> {
|
||||
open fun getNonGroupInheritedMaterials(): Set<NamespacedKey> {
|
||||
return includedMaterial
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the group non-inherited material as a set
|
||||
*/
|
||||
open fun setNonGroupInheritedMaterials(materials: EnumSet<Material>) {
|
||||
open fun setNonGroupInheritedMaterials(materials: Set<NamespacedKey>) {
|
||||
this.includedMaterial.clear()
|
||||
this.includedMaterial.addAll(materials)
|
||||
}
|
||||
|
|
@ -102,8 +103,9 @@ abstract class AbstractMaterialGroup(private val name: String) {
|
|||
// Test inner material
|
||||
val matIterator = includedMaterial.iterator()
|
||||
while (matIterator.hasNext()) {
|
||||
val material = matIterator.next()
|
||||
if (material.isAir) continue
|
||||
val key = matIterator.next()
|
||||
val material = MaterialUtil.getMatFromKey(key)
|
||||
if (material == null || material.isAir) continue
|
||||
return material
|
||||
}
|
||||
// Test included group representative material
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue