9
0
mirror of https://github.com/HibiscusMC/HMCCosmetics.git synced 2025-12-23 17:09:24 +00:00

Compare commits

...

100 Commits

Author SHA1 Message Date
LoJoSho
b00c79f67b Merge pull request #111 from HibiscusMC/multi_wardrobe
Wardrobe Improvements (2.4.0)
2023-05-25 10:10:21 -05:00
LoJoSho
0528ebfa84 feat: rename setlocation to setwardrobesetting to allow modification of permission and distance ingame 2023-05-24 16:56:06 -05:00
LoJoSho
1e0ffdc08b clean: summer cleaning of CosmeticUser.java 2023-05-24 16:41:54 -05:00
LoJoSho
cc08cc6537 feat: message.yml to sync as well 2023-05-24 16:36:47 -05:00
LoJoSho
455b8cd1a1 version bump (2.4.0) 2023-05-24 16:29:07 -05:00
LoJoSho
5c6bb93e6c feat: add removeWardrobe method 2023-05-24 15:08:43 -05:00
LoJoSho
e9c7946319 feat: create new wardrobes in-game 2023-05-24 15:05:13 -05:00
LoJoSho
fcde8e7f25 feat: send message if locations are not all setup 2023-05-24 15:03:41 -05:00
LoJoSho
7fcbbd6b5a feat: add wardrobes to internal map 2023-05-24 15:03:23 -05:00
LoJoSho
a92b4c15f5 feat: check if wardrobe locations are not null 2023-05-24 15:03:13 -05:00
LoJoSho
7439aabfd1 clean: random space in wardrobe debug message 2023-05-24 14:53:59 -05:00
LoJoSho
50bda8343c fix: wardrobe region not entering wardrobe 2023-05-24 14:53:16 -05:00
LoJoSho
c189424aa8 fix: setlocation command now shows no-wardrobes message when there is no wardrobe with inputted name 2023-05-24 14:44:38 -05:00
LoJoSho
70b97667c3 feat: only show wardrobes player has access to 2023-05-24 14:38:01 -05:00
LoJoSho
128a33a21f fix: Menus being janky 2023-05-24 12:41:58 -05:00
LoJoSho
538edb67dd fix: placeholders out of bounds slight rework 2023-05-24 12:41:43 -05:00
LoJoSho
9b607a099e fix: unlocked placeholder producing out of bounds expection 2023-05-24 12:20:39 -05:00
LoJoSho
f084d9e782 feat: add values method to Menus class 2023-05-24 11:03:54 -05:00
LoJoSho
8ee1400f85 feat: menu permissions added to registered permissions 2023-05-24 11:03:40 -05:00
LoJoSho
8e33b2022b fix: going to another wg region while cosmetic hidden from wg causes cosmetics to stay hidden 2023-05-24 10:58:34 -05:00
LoJoSho
a661ea09e1 feat: better file generating logic 2023-05-24 10:11:02 -05:00
LoJoSho
9c2120d13d version bump (2.4.0-DEV) 2023-05-24 09:57:03 -05:00
LoJoSho
7ea4ccccef feat: config updater 2023-05-24 09:56:46 -05:00
LoJoSho
0b1ed0fbeb clean: create path variables to be more in line with existing code 2023-05-23 14:33:36 -05:00
LoJoSho
0aac0a2377 clean: deprecate inDistanceOfWardrobe and inDistanceOfStatic 2023-05-23 14:30:58 -05:00
LoJoSho
04810b91ef feat: add ability to select any cosmetic in wardrobe, resolves #55 2023-05-23 11:11:24 -05:00
LoJoSho
f072f0e044 clean: old variable 2023-05-23 11:06:05 -05:00
LoJoSho
6e2278f4f0 clean: loose message 2023-05-23 10:58:42 -05:00
LoJoSho
7c95d9614d clean: remove players list, just use permissions if you wish to limit it to a certain group. 2023-05-23 10:53:37 -05:00
LoJoSho
54e8e5102a feat: Multiple Wardrobes 2023-05-23 10:50:09 -05:00
LoJoSho
b270d022d4 feat: Check if there is air below emote usage 2023-05-23 09:10:00 -05:00
LoJoSho
f087933d48 Merge pull request #110 from HibiscusMC/update_geary_hook
Update Geary Hook
2023-05-22 14:31:33 -05:00
Boy
ed1d1515bc fix invalid material error before pipeline finishes 2023-05-21 23:39:09 +02:00
Boy
aa364f5e77 properly inject setup into loadPhase 2023-05-21 19:19:51 +02:00
Boy
5ae6d17ef3 update geary hook 2023-05-21 18:25:55 +02:00
LoJoSho
4590bdcde1 feat: PlayerWardrobeEnterEvent now passes wardrobe location that is modifiable 2023-05-16 15:24:26 -05:00
LoJoSho
f9465e8206 clean: finish wardrobe location overhaul 2023-05-16 15:21:20 -05:00
LoJoSho
cd3a9f1af4 clean: move wardrobe location to its own class, rename wardrobe location to NPCLocation 2023-05-16 15:09:05 -05:00
LoJoSho
853668ff1b clean: better invalid backpack debug messages 2023-05-16 14:44:48 -05:00
LoJoSho
e2ee55bab4 fix: cosmetic armor updating when a player is emoting 2023-05-16 14:17:41 -05:00
LoJoSho
7a13715897 fix: protocollib moved to correct version 2023-05-16 14:09:59 -05:00
LoJoSho
d92e3e4616 clean: include user when shown invalid backpack error 2023-05-11 19:27:12 -05:00
LoJoSho
49023ff701 fix: equipped emotes not going through emote manager 2023-05-10 16:43:08 -05:00
LoJoSho
1bd405d13e version bump (2.3.2-DEV) 2023-05-10 16:32:55 -05:00
LoJoSho
69de2fa178 version bump (2.3.1) 2023-05-09 14:20:23 -05:00
LoJoSho
cdcf904ac8 fix: cosmetic tpe gui items not processing placeholders 2023-05-08 12:23:20 -05:00
LoJoSho
80f9100bf0 fix: translation file generating 2023-05-08 12:22:57 -05:00
LoJoSho
751509ece4 version bump (2.3.1-DEV) 2023-05-08 12:22:46 -05:00
LoJoSho
f36d558e13 clean: updateCosmetic use proper method 2023-05-06 10:40:15 -05:00
LoJoSho
ab8ae8ee76 version bump (2.3.0) 2023-05-06 10:28:26 -05:00
LoJoSho
aca14f8a04 clean: config referenced wrong value in comments 2023-05-06 09:47:24 -05:00
LoJoSho
6ec13051bb clean: user tick debug message 2023-05-06 09:40:13 -05:00
LoJoSho
ebc7bfa30a feat: menu now passes int slot to gui item types 2023-05-06 09:37:54 -05:00
LoJoSho
e59717d61d feat: positive emote distances show camera facing player 2023-05-06 09:34:10 -05:00
LoJoSho
7f5a90b080 Merge pull request #105 from Craftinators/remapped
feat: allow for multiple emotes in one bbmodel file
2023-05-06 09:19:45 -05:00
LoJoSho
51d26a7983 Merge pull request #104 from HibiscusMC/2.3.0
Improved GUI configuration options (2.3.0)
2023-05-06 09:16:22 -05:00
Craftinators
d1d001fcf6 refactor(EmoteManager): move emote loading logic to EmoteManager class 2023-05-06 00:02:03 -04:00
Craftinators
79f33ca0d1 feat: allow for multiple emotes in one bbmodel file 2023-05-05 18:39:14 -04:00
LoJoSho
7f37937185 clean: removed method not needed 2023-05-05 16:34:01 -05:00
LoJoSho
0e9164a506 fix: multi-slot gui items actions not running 2023-05-05 16:23:03 -05:00
LoJoSho
91361a6373 feat: equipped and locked cosmetic item in gui 2023-05-05 14:38:54 -05:00
LoJoSho
cfe5f33a63 version bump (2.3.0-DEV) 2023-05-05 14:38:38 -05:00
LoJoSho
e50566e2cb feat: add hasCosmeticInSlot for cosmetic 2023-05-05 13:53:01 -05:00
LoJoSho
f793f4e67a Merge pull request #103 from Craftinators/main
chore: add contact link
2023-04-30 15:53:07 -05:00
Craftinators
b57428e3fe style: remove emoji from name 2023-04-30 14:13:21 -04:00
Craftinators
3137c45704 chore: add contact link
Add a contact link for general questions
2023-04-30 14:09:46 -04:00
LoJoSho
38c270558c fix: update PlayerAnimator to 1.2.6 for 1.19.4 support 2023-04-30 10:37:57 -05:00
LoJoSho
39a36fa73c Merge remote-tracking branch 'origin/remapped' into remapped
# Conflicts:
#	build.gradle.kts
2023-04-29 22:58:39 -05:00
LoJoSho
ae83355860 feat: add LibsDisguise hook, resolves #85 2023-04-29 22:57:40 -05:00
LoJoSho
60d910d148 Merge pull request #100 from Craftinators/remapped
Issue template changes
2023-04-29 12:09:21 -05:00
LoJoSho
251d227ddb Merge pull request #99 from mergu/denizen_item_support
Add support for Denizen items
2023-04-29 12:07:30 -05:00
LoJoSho
45e597c665 version bump (2.2.9-DEV) 2023-04-29 12:01:20 -05:00
Craftinators
f0e60903b5 chore: more PR description options 2023-04-29 12:55:31 -04:00
Craftinators
db49946e5e chore: add discord link at top 2023-04-29 12:49:10 -04:00
Craftinators
50ebc737e6 chore: fix 02-feature-request indent error 2023-04-29 12:47:25 -04:00
Craftinators
28d1775c86 chore: fix 02-feature_request syntax error 2023-04-29 12:46:49 -04:00
Craftinators
0a1a381ebc chore: update 02-feature_request 2023-04-29 12:45:58 -04:00
Craftinators
651067fb17 style: rename feature-request.yml 2023-04-29 12:40:43 -04:00
Craftinators
1f634d668e style: rename bug-report.yml 2023-04-29 12:40:14 -04:00
Craftinators
f5bf8c70b4 chore: modify text 2023-04-29 12:39:22 -04:00
Craftinators
f50731f83e chore: fix bug-report.yml validation errors 2023-04-29 12:36:29 -04:00
Craftinators
f44d916b32 chore: fix bug-report.yml syntax error 2023-04-29 12:34:17 -04:00
Craftinators
9cfb27da28 chore: update bug-report.yml 2023-04-29 12:33:03 -04:00
Mergu
b09bd35737 Add support for Denizen items 2023-04-29 11:56:17 -04:00
LoJoSho
b998cac5c8 clean: default earth day grabber had model field that was unused 2023-04-26 15:01:30 -05:00
LoJoSho
9b34ffebb8 version bump (2.2.8) 2023-04-23 15:44:28 -05:00
LoJoSho
3eaaf75bfb clean: removed persistant data container not being used 2023-04-23 15:42:54 -05:00
LoJoSho
c1bae96ad9 fix: cosmetic data container now contains cosmetic id 2023-04-23 15:42:31 -05:00
LoJoSho
ddb6f53655 fix: cancel event for clicking in HMCColor 2023-04-23 15:23:10 -05:00
LoJoSho
c37f52bbb1 feat: destroy loose items cover gamemode switch 2023-04-23 10:47:44 -05:00
LoJoSho
dd805f1860 feat: add cosmetics containing who they were generated for 2023-04-23 10:38:43 -05:00
LoJoSho
d9551f2827 clean: better debug messages in CosmeticUser 2023-04-22 19:09:49 -05:00
LoJoSho
1750a1bf5f fix: 1.19.2 fake player info packet issue 2023-04-22 19:05:22 -05:00
LoJoSho
d42f5ef5af fix: player still in wardrobe after death 2023-04-22 18:32:28 -05:00
LoJoSho
2ca940a929 fix: papi expansion does not persist 2023-04-22 16:31:52 -05:00
LoJoSho
36f33b54af fix: cosmetic null showing error 2023-04-22 16:27:05 -05:00
LoJoSho
d0b4be6db8 fix: wardrobe not ending with transition false 2023-04-22 16:22:18 -05:00
LoJoSho
4afa0bb538 clean: new debug messages 2023-04-22 16:21:02 -05:00
LoJoSho
201bcceaab fix: 1.19.3 fake info packet not properly casting in protocol lib 2023-04-20 14:12:25 -05:00
LoJoSho
92ad314ce1 version bump (2.2.8-DEV) 2023-04-20 14:12:05 -05:00
45 changed files with 915 additions and 430 deletions

View File

@@ -0,0 +1,61 @@
name: Bug Report
description: Report an issue with HMCCosmetics
labels: [bug]
assignees: ["LoJoSho"]
body:
- type: markdown
attributes:
value: |
Thank you for filing an bug report! If you are here to ask a question, use our [Discord server](https://discord.gg/pcm8kWrdNt) instead!
- type: input
id: release_version
attributes:
label: Plugin Version
placeholder: vx.x.x
description: |
Insert the version of HMCCosmetics you are using (e.g. `v2.2.8`). Before continuing make sure you have the latest version of HMCCosmetics as
your issue may have already been resolved.
- type: input
id: server_version
attributes:
label: Server Version
placeholder: fork-x-x.x.x
description: |
Insert the version of your minecraft server in the format `fork-build-version` (e.g. `PAPER-521-1.19.4`, `PURPUR-1838-1.19.2`)
- type: textarea
id: description
attributes:
label: Issue description
description: Describe the issue in as much detail as possible (Include any error logs in a code block below)
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: Explain how to reproduce this issue step-by-step, in as much detail as possible.
placeholder: |
Steps to reproduce:
1. Do thing
2. Observe behavior
3. Post any error logs below
validations:
required: true
- type: dropdown
id: priority
attributes:
label: Issue priority
description: Please be realistic. If you need to elaborate on your reasoning, please use the issue description field above.
options:
- Low (slightly annoying)
- Medium (should be fixed somewhat soon)
- High (immediate attention needed)
validations:
required: true
- type: textarea
id: versions
attributes:
label: Other Versions
placeholder: |
- ModelEngine R3.0.1 (`/version ModelEngine`)
- Any other relevant version information such as depenedencies
description: |
List any necessary or relevant versions here.

View File

@@ -0,0 +1,28 @@
name: Feature Request
description: Request a new feature for HMCCosmetics
labels: [enhancement]
assignees: ["LoJoSho"]
body:
- type: markdown
attributes:
value: |
If you are here to ask a question, use our [Discord server](https://discord.gg/pcm8kWrdNt) instead!
- type: markdown
attributes:
value: |
Please check that the feature you are requesting does not already exist *and/or* hasn't already been requested by someone else.
- type: textarea
id: description
attributes:
label: Feature Description
description: A clear and concise description of what the problem is, or what feature you want to be implemented.
placeholder: A good addition would be...
validations:
required: true
- type: textarea
id: solution
attributes:
label: Implementation Description
description: A clear and concise description of what you want to happen, and any optional **configuration changes** that need to be made.
validations:
required: false

View File

@@ -1,62 +0,0 @@
name: Bug Report
description: Create a bug report to help us keep track of all bugs that have to be fixed
title: "[BUG] <name for bug>"
labels: [bug]
body:
- type: checkboxes
id: i-have-checked
attributes:
label: I have checked...
options:
- label: "I am using the latest version of HMCCosmetics"
required: true
- label: "I am using the latest version of any dependencies"
required: true
- label: "I have checked if any similar bug reports exist"
required: true
- type: textarea
id: description
attributes:
label: Description
description: A full description of the bug
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: Explain how to reproduce this issue step-by-step, in as much detail as possible.
validations:
required: true
- type: textarea
id: hmcc-version
attributes:
label: Plugin Version
description: Run `version HMCCosmetics` in your console and paste the output
validations:
required: true
- type: textarea
id: meg-version
attributes:
label: ModelEngine Version
description: "Run `version ModelEngine` in your console and paste the output. Optional if not using balloons."
validations:
required: false
- type: textarea
id: server-version
attributes:
label: Server Version
description: "Run `version` in your console and paste the output."
validations:
required: true
- type: "dropdown"
id: "type"
attributes:
label: "How breaking is the bug?"
options:
- "Breaking Bug - Plugin unusable"
- "Non-breaking Bug - Plugin still usable, but certain features unavailable"
- "Minor Bug - Plugin completely functional, but features have non-working aspects"
validations:
required: true

View File

@@ -1 +1,5 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links:
- name: General Questions and Help
url: https://discord.gg/pcm8kWrdNt
about: This issue tracker is not for support questions. Please refer to the Hibiscus community's help and discussion discord server.

View File

@@ -1,29 +0,0 @@
name: Feature Request
description: Create a feature request to help us keep track of all features you want to be added
title: "[FEATURE] <title>"
labels: [enhancement]
body:
- type: "checkboxes"
id: "i-have-checked"
attributes:
label: "I have checked that..."
options:
- label: "...such a feature does not exist already"
required: true
- label: "...such a feature request has not been submitted already"
required: true
- type: "textarea"
id: "description"
attributes:
label: "Description"
description: "A full description of the feature"
validations:
required: true
- type: "textarea"
id: "config-changes"
attributes:
label: "Config Changes"
description: "The configuration changes your feature should have"
validations:
required: false

View File

@@ -1,11 +1,14 @@
#### Select the option(s) that best describes this PR: #### Select the option(s) that best describes this PR:
- [ ] Major breaking change - [ ] Major breaking change
- [ ] Minor change - [ ] Minor change
- [ ] Bug fix
- [ ] Feature implementation - [ ] Feature implementation
- [ ] Documentation - [ ] Bug fix
- [ ] Cleaning - [ ] Chore (Changes that don't fix or add new features *and don't* modify source files)
- [ ] Refactoring - [ ] Refactoring (Changes that dont't fix or add new features *but do* modify source files)
- [ ] Documentation (Changes to README files and/or JavaDocs)
- [ ] Style (Changes that don't affect the meaning of the code)
- [ ] Performance
- [ ] Other (Please specify below)
#### Please describe the changes this PR makes and why it should be merged: #### Please describe the changes this PR makes and why it should be merged:

View File

@@ -8,7 +8,7 @@ plugins {
} }
group = "com.hibiscusmc" group = "com.hibiscusmc"
version = "2.2.7" version = "2.4.0"
allprojects { allprojects {
apply(plugin = "java") apply(plugin = "java")
@@ -27,6 +27,7 @@ allprojects {
// ProtocolLib repo // ProtocolLib repo
maven("https://repo.dmulloy2.net/repository/public/") //ProtocolLib Repo, constantly down maven("https://repo.dmulloy2.net/repository/public/") //ProtocolLib Repo, constantly down
maven("https://repo.mineinabyss.com/releases/") maven("https://repo.mineinabyss.com/releases/")
maven("https://repo.mineinabyss.com/snapshots/")
// PlaceholderAPI // PlaceholderAPI
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
@@ -34,8 +35,8 @@ allprojects {
//Hikari //Hikari
maven("https://mvnrepository.com/artifact/com.zaxxer/HikariCP") maven("https://mvnrepository.com/artifact/com.zaxxer/HikariCP")
// Citizens // Citizens & Denizen
maven("https://repo.citizensnpcs.co") maven("https://maven.citizensnpcs.co/repo")
// Worldguard // Worldguard
maven("https://maven.enginehub.org/repo/") maven("https://maven.enginehub.org/repo/")
@@ -69,14 +70,12 @@ allprojects {
compileOnly("com.mojang:authlib:1.5.25") compileOnly("com.mojang:authlib:1.5.25")
compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT") compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT")
compileOnly("org.jetbrains:annotations:23.0.0") compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT") compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0")
compileOnly("me.clip:placeholderapi:2.11.1") compileOnly("me.clip:placeholderapi:2.11.1")
compileOnly("com.ticxo.modelengine:api:R3.0.1") compileOnly("com.ticxo:modelengine:R3.0.1")
compileOnly("com.github.oraxen:oraxen:-SNAPSHOT") compileOnly("com.github.oraxen:oraxen:-SNAPSHOT")
compileOnly("com.github.LoneDev6:API-ItemsAdder:3.2.5") compileOnly("com.github.LoneDev6:API-ItemsAdder:3.2.5")
compileOnly("com.mineinabyss:idofront:0.12.111") compileOnly("com.mineinabyss:geary-papermc:0.24-SNAPSHOT")
compileOnly("com.mineinabyss:geary-papermc-core:0.19.113")
compileOnly("com.mineinabyss:looty:0.8.67")
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT") compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT")
compileOnly("it.unimi.dsi:fastutil:8.5.11") compileOnly("it.unimi.dsi:fastutil:8.5.11")
compileOnly("com.github.LeonMangler:SuperVanish:6.2.6-4") compileOnly("com.github.LeonMangler:SuperVanish:6.2.6-4")
@@ -100,7 +99,9 @@ dependencies {
implementation("org.bstats:bstats-bukkit:3.0.0") implementation("org.bstats:bstats-bukkit:3.0.0")
implementation("com.jeff_media:SpigotUpdateChecker:3.0.0") implementation("com.jeff_media:SpigotUpdateChecker:3.0.0")
implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT") implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT")
implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.5") implementation("com.ticxo:PlayerAnimator:R1.2.6")
implementation("com.github.BG-Software-LLC:CommentedConfiguration:-SNAPSHOT")
//implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.5")
} }
tasks { tasks {
@@ -141,6 +142,7 @@ tasks {
relocate("com.jeff_media.updatechecker", "com.hisbiscusmc.hmccosmetics.updatechecker") relocate("com.jeff_media.updatechecker", "com.hisbiscusmc.hmccosmetics.updatechecker")
relocate("com.owen1212055.particlehelper", "com.hisbiscusmc.hmccosmetics.particlehelper") relocate("com.owen1212055.particlehelper", "com.hisbiscusmc.hmccosmetics.particlehelper")
relocate("com.ticxo.playeranimator", "com.hisbiscusmc.hmccosmetics.playeranimator") relocate("com.ticxo.playeranimator", "com.hisbiscusmc.hmccosmetics.playeranimator")
relocate("com.bgsoftware", "com.hisbiscusmc.hmccosmetics.configupdater")
archiveFileName.set("HMCCosmeticsRemapped-${project.version}.jar") archiveFileName.set("HMCCosmeticsRemapped-${project.version}.jar")
dependencies { dependencies {
@@ -168,7 +170,7 @@ bukkit {
apiVersion = "1.17" apiVersion = "1.17"
authors = listOf("LoJoSho") authors = listOf("LoJoSho")
depend = listOf("ProtocolLib") depend = listOf("ProtocolLib")
softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "Looty", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish") softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "Geary", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen")
version = "${project.version}" version = "${project.version}"
commands { commands {
@@ -210,7 +212,7 @@ bukkit {
register("hmccosmetics.cmd.emote.other") { register("hmccosmetics.cmd.emote.other") {
default = BukkitPluginDescription.Permission.Default.OP default = BukkitPluginDescription.Permission.Default.OP
} }
register("hmccosmetics.cmd.setlocation") { register("hmccosmetics.cmd.setwardrobesetting") {
default = BukkitPluginDescription.Permission.Default.OP default = BukkitPluginDescription.Permission.Default.OP
} }
register("hmccosmetics.cmd.dataclear") { register("hmccosmetics.cmd.dataclear") {

View File

@@ -7,18 +7,21 @@ dependencies {
compileOnly("com.mojang:authlib:1.5.25") compileOnly("com.mojang:authlib:1.5.25")
compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT") compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT")
compileOnly("org.jetbrains:annotations:23.0.0") compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT") compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0")
compileOnly("me.clip:placeholderapi:2.11.1") compileOnly("me.clip:placeholderapi:2.11.1")
compileOnly("com.ticxo.modelengine:api:R3.0.1") compileOnly("com.ticxo:modelengine:R3.0.1")
compileOnly("com.github.oraxen:oraxen:-SNAPSHOT") compileOnly("com.github.oraxen:oraxen:-SNAPSHOT")
compileOnly("com.github.LoneDev6:API-ItemsAdder:3.2.5") compileOnly("com.github.LoneDev6:API-ItemsAdder:3.2.5")
compileOnly("com.mineinabyss:geary-papermc-core:0.19.113") compileOnly("com.mineinabyss:geary-papermc:0.24-SNAPSHOT")
compileOnly("com.mineinabyss:looty:0.8.67")
compileOnly("com.hibiscus:hmccolor:0.3-SNAPSHOT") compileOnly("com.hibiscus:hmccolor:0.3-SNAPSHOT")
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT") compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT")
compileOnly("it.unimi.dsi:fastutil:8.5.11") compileOnly("it.unimi.dsi:fastutil:8.5.11")
compileOnly("io.lumine:Mythic-Dist:5.2.1") compileOnly("io.lumine:Mythic-Dist:5.2.1")
compileOnly("com.denizenscript:denizen:1.2.7-SNAPSHOT")
compileOnly("com.github.LeonMangler:SuperVanish:6.2.6-4") compileOnly("com.github.LeonMangler:SuperVanish:6.2.6-4")
compileOnlyApi("LibsDisguises:LibsDisguises:10.0.21") {
exclude("org.spigotmc", "spigot")
}
//compileOnly("com.github.Fisher2911:FisherLib:master-SNAPSHOT") //compileOnly("com.github.Fisher2911:FisherLib:master-SNAPSHOT")
implementation("net.kyori:adventure-api:4.12.0") implementation("net.kyori:adventure-api:4.12.0")
@@ -29,7 +32,9 @@ dependencies {
implementation("org.bstats:bstats-bukkit:3.0.0") implementation("org.bstats:bstats-bukkit:3.0.0")
implementation("com.jeff_media:SpigotUpdateChecker:3.0.0") implementation("com.jeff_media:SpigotUpdateChecker:3.0.0")
implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT") implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT")
implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.5") implementation("com.ticxo:PlayerAnimator:R1.2.6")
implementation("com.github.BG-Software-LLC:CommentedConfiguration:-SNAPSHOT")
//implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.5")
} }
java { java {

View File

@@ -1,5 +1,6 @@
package com.hibiscusmc.hmccosmetics; package com.hibiscusmc.hmccosmetics;
import com.bgsoftware.common.config.CommentedConfiguration;
import com.hibiscusmc.hmccosmetics.api.HMCCosmeticSetupEvent; import com.hibiscusmc.hmccosmetics.api.HMCCosmeticSetupEvent;
import com.hibiscusmc.hmccosmetics.command.CosmeticCommand; import com.hibiscusmc.hmccosmetics.command.CosmeticCommand;
import com.hibiscusmc.hmccosmetics.command.CosmeticCommandTabComplete; import com.hibiscusmc.hmccosmetics.command.CosmeticCommandTabComplete;
@@ -11,6 +12,8 @@ import com.hibiscusmc.hmccosmetics.config.serializer.LocationSerializer;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.database.Database; import com.hibiscusmc.hmccosmetics.database.Database;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus; import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.hooks.Hooks; import com.hibiscusmc.hmccosmetics.hooks.Hooks;
import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGHook; import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGHook;
@@ -20,15 +23,11 @@ import com.hibiscusmc.hmccosmetics.listener.PlayerGameListener;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers; import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.TranslationUtil; import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
import com.jeff_media.updatechecker.UpdateCheckSource; import com.jeff_media.updatechecker.UpdateCheckSource;
import com.jeff_media.updatechecker.UpdateChecker; import com.jeff_media.updatechecker.UpdateChecker;
import com.ticxo.playeranimator.PlayerAnimatorImpl; import com.ticxo.playeranimator.PlayerAnimatorImpl;
import com.ticxo.playeranimator.api.PlayerAnimator;
import com.ticxo.playeranimator.api.animation.pack.AnimationPack;
import org.apache.commons.io.FilenameUtils;
import org.bstats.bukkit.Metrics; import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@@ -44,7 +43,6 @@ import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.io.File; import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Map;
public final class HMCCosmeticsPlugin extends JavaPlugin { public final class HMCCosmeticsPlugin extends JavaPlugin {
@@ -90,13 +88,12 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
.checkNow(); .checkNow();
onLatestVersion = checker.isUsingLatestVersion(); onLatestVersion = checker.isUsingLatestVersion();
// File setup // File setup
if (!getDataFolder().exists()) {
saveDefaultConfig(); saveDefaultConfig();
saveResource("translations.yml", false); //saveResource("translations.yml", false);
saveResource("messages.yml", false); if (!Path.of(getDataFolder().getPath(), "messages.yml").toFile().exists()) saveResource("messages.yml", false);
saveResource("cosmetics/defaultcosmetics.yml", false); if (!Path.of(getDataFolder().getPath() + "/cosmetics/").toFile().exists()) saveResource("cosmetics/defaultcosmetics.yml", false);
saveResource("menus/defaultmenu.yml", false); if (!Path.of(getDataFolder().getPath() + "/menus/").toFile().exists()) saveResource("menus/defaultmenu.yml", false);
}
// Emote folder setup // Emote folder setup
File emoteFile = new File(getDataFolder().getPath() + "/emotes"); File emoteFile = new File(getDataFolder().getPath() + "/emotes");
if (!emoteFile.exists()) emoteFile.mkdir(); if (!emoteFile.exists()) emoteFile.mkdir();
@@ -104,6 +101,16 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
// Player Animator // Player Animator
PlayerAnimatorImpl.initialize(this); PlayerAnimatorImpl.initialize(this);
// Configuration Sync
final File configFile = Path.of(getInstance().getDataFolder().getPath(), "config.yml").toFile();
final File messageFile = Path.of(getInstance().getDataFolder().getPath(), "messages.yml").toFile();
try {
CommentedConfiguration.loadConfiguration(configFile).syncWithConfig(configFile, getInstance().getResource("config.yml"),
"database-settings", "debug-mode", "wardrobe.viewer-location", "wardrobe.npc-location", "wardrobe.wardrobe-location", "wardrobe.leave-location");
CommentedConfiguration.loadConfiguration(messageFile).syncWithConfig(messageFile, getInstance().getResource("messages.yml"));
} catch (Exception e) {}
// Setup
setup(); setup();
// Commands // Commands
@@ -174,7 +181,7 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
WardrobeSettings.load(loader.load().node("wardrobe")); WardrobeSettings.load(loader.load().node("wardrobe"));
DatabaseSettings.load(loader.load().node("database-settings")); DatabaseSettings.load(loader.load().node("database-settings"));
configLoader = loader; configLoader = loader;
} catch (ConfigurateException e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -240,28 +247,19 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
getInstance().getServer().getPluginManager().addPermission(new Permission(cosmetic.getPermission())); getInstance().getServer().getPluginManager().addPermission(new Permission(cosmetic.getPermission()));
} }
} }
for (Menu menu : Menus.values()) {
File emoteFolder = new File(getInstance().getDataFolder().getPath() + "/emotes/"); if (menu.getPermissionNode() != null) {
if (emoteFolder.exists()) { if (getInstance().getServer().getPluginManager().getPermission(menu.getPermissionNode()) != null) continue;
PlayerAnimator.api.getAnimationManager().clearRegistry(); getInstance().getServer().getPluginManager().addPermission(new Permission(menu.getPermissionNode()));
File[] emotesFiles = emoteFolder.listFiles(); }
for (File emoteFile : emotesFiles) {
if (!emoteFile.getName().contains("bbmodel")) continue;
String animationName = FilenameUtils.removeExtension(emoteFile.getName());
PlayerAnimator.api.getAnimationManager().importAnimations(animationName, emoteFile);
MessagesUtil.sendDebugMessages("Added '" + animationName + "' to Player Animator ");
} }
/* EmoteManager.loadEmotes();
for (Map.Entry<String, AnimationPack> packEntry : PlayerAnimator.api.getAnimationManager().getRegistry().entrySet()) {
Set<String> animationNames = packEntry.getValue().getAnimations().keySet().stream().map(animation -> packEntry.getKey().replace(":", ".") + "." + animation).collect(Collectors.toSet());
}
*/
}
getInstance().getLogger().info("Successfully Enabled HMCCosmetics"); getInstance().getLogger().info("Successfully Enabled HMCCosmetics");
getInstance().getLogger().info(Cosmetics.values().size() + " Cosmetics Successfully Setup"); getInstance().getLogger().info(Cosmetics.values().size() + " Cosmetics Successfully Setup");
getInstance().getLogger().info(Menus.getMenuNames().size() + " Menus Successfully Setup"); getInstance().getLogger().info(Menus.getMenuNames().size() + " Menus Successfully Setup");
getInstance().getLogger().info(WardrobeSettings.getWardrobes().size() + " Wardrobes Successfully Setup");
getInstance().getLogger().info("Data storage is set to " + DatabaseSettings.getDatabaseType()); getInstance().getLogger().info("Data storage is set to " + DatabaseSettings.getDatabaseType());
Bukkit.getPluginManager().callEvent(new HMCCosmeticSetupEvent()); Bukkit.getPluginManager().callEvent(new HMCCosmeticSetupEvent());

View File

@@ -1,5 +1,7 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeLocation;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
@@ -11,9 +13,11 @@ import org.jetbrains.annotations.NotNull;
public class PlayerWardrobeEnterEvent extends PlayerCosmeticEvent implements Cancellable { public class PlayerWardrobeEnterEvent extends PlayerCosmeticEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList(); private static final HandlerList handlers = new HandlerList();
private boolean cancel = false; private boolean cancel = false;
private Wardrobe wardrobe;
public PlayerWardrobeEnterEvent(@NotNull CosmeticUser who) { public PlayerWardrobeEnterEvent(@NotNull CosmeticUser who, @NotNull Wardrobe wardrobe) {
super(who); super(who);
this.wardrobe = wardrobe;
} }
@Override @Override
@@ -45,4 +49,12 @@ public class PlayerWardrobeEnterEvent extends PlayerCosmeticEvent implements Can
public static HandlerList getHandlerList() { public static HandlerList getHandlerList() {
return handlers; return handlers;
} }
public void setWardrobe(Wardrobe wardrobe) {
this.wardrobe = wardrobe;
}
public Wardrobe getWardrobe() {
return wardrobe;
}
} }

View File

@@ -2,12 +2,15 @@ package com.hibiscusmc.hmccosmetics.command;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeLocation;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings; import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType;
import com.hibiscusmc.hmccosmetics.database.Database; import com.hibiscusmc.hmccosmetics.database.Database;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.gui.Menu; import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus; import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu; import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
@@ -15,7 +18,6 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.ServerUtils; import com.hibiscusmc.hmccosmetics.util.ServerUtils;
import com.ticxo.playeranimator.api.PlayerAnimator;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.EnumUtils;
@@ -194,8 +196,14 @@ public class CosmeticCommand implements CommandExecutor {
} }
case ("wardrobe") -> { case ("wardrobe") -> {
if (sender instanceof Player) player = ((Player) sender).getPlayer(); if (sender instanceof Player) player = ((Player) sender).getPlayer();
if (args.length == 1) {
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true;
}
if (sender.hasPermission("hmccosmetics.cmd.wardrobe.other")) { if (sender.hasPermission("hmccosmetics.cmd.wardrobe.other")) {
if (args.length >= 2) player = Bukkit.getPlayer(args[1]); if (args.length >= 3) player = Bukkit.getPlayer(args[2]);
} }
if (!sender.hasPermission("hmccosmetics.cmd.wardrobe")) { if (!sender.hasPermission("hmccosmetics.cmd.wardrobe")) {
@@ -208,9 +216,19 @@ public class CosmeticCommand implements CommandExecutor {
return true; return true;
} }
if (!WardrobeSettings.getWardrobeNames().contains(args[1])) {
if (!silent) MessagesUtil.sendMessage(sender, "no-wardrobes");
return true;
}
Wardrobe wardrobe = WardrobeSettings.getWardrobe(args[1]);
CosmeticUser user = CosmeticUsers.getUser(player); CosmeticUser user = CosmeticUsers.getUser(player);
user.toggleWardrobe(); if (user.isInWardrobe()) {
user.leaveWardrobe();
} else {
user.enterWardrobe(false, wardrobe);
}
return true; return true;
} }
// cosmetic menu exampleMenu playerName // cosmetic menu exampleMenu playerName
@@ -289,36 +307,56 @@ public class CosmeticCommand implements CommandExecutor {
DyeMenu.openMenu(user, cosmetic); DyeMenu.openMenu(user, cosmetic);
} }
} }
case ("setlocation") -> { case ("setwardrobesetting") -> {
if (!sender.hasPermission("hmccosmetics.cmd.setlocation")) { if (!sender.hasPermission("hmccosmetics.cmd.setwardrobesetting")) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission"); if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true; return true;
} }
if (player == null) return true; if (player == null) return true;
if (args.length < 2) { if (args.length < 3) {
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args"); if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true; return true;
} }
Wardrobe wardrobe = WardrobeSettings.getWardrobe(args[1]);
if (wardrobe == null) {
wardrobe = new Wardrobe(args[1], new WardrobeLocation(null, null, null), null, -1);
WardrobeSettings.addWardrobe(wardrobe);
//MessagesUtil.sendMessage(player, "no-wardrobes");
//return true;
}
if (args[1].equalsIgnoreCase("wardrobelocation")) { if (args[2].equalsIgnoreCase("npclocation")) {
WardrobeSettings.setWardrobeLocation(player.getLocation()); WardrobeSettings.setNPCLocation(wardrobe, player.getLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-location"); if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-location");
return true; return true;
} }
if (args[1].equalsIgnoreCase("viewerlocation")) { if (args[2].equalsIgnoreCase("viewerlocation")) {
WardrobeSettings.setViewerLocation(player.getLocation()); WardrobeSettings.setViewerLocation(wardrobe, player.getLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-viewing"); if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-viewing");
return true; return true;
} }
if (args[1].equalsIgnoreCase("leavelocation")) { if (args[2].equalsIgnoreCase("leavelocation")) {
WardrobeSettings.setLeaveLocation(player.getLocation()); WardrobeSettings.setLeaveLocation(wardrobe, player.getLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-leaving"); if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-leaving");
return true; return true;
} }
if (args.length >= 4) {
if (args[2].equalsIgnoreCase("permission")) {
WardrobeSettings.setWardrobePermission(wardrobe, args[3]);
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-permission");
return true;
}
if (args[2].equalsIgnoreCase("distance")) {
WardrobeSettings.setWardrobeDistance(wardrobe, Integer.valueOf(args[3]));
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-distance");
return true;
}
}
} }
case ("dump") -> { case ("dump") -> {
if (player == null) return true; if (player == null) return true;
@@ -428,13 +466,11 @@ public class CosmeticCommand implements CommandExecutor {
return true; return true;
} }
if (args.length >= 2) { if (!EmoteManager.has(args[1])) {
if (!PlayerAnimator.api.getAnimationManager().getRegistry().keySet().contains(args[1])) {
MessagesUtil.sendDebugMessages("Did not contain " + args[1]); MessagesUtil.sendDebugMessages("Did not contain " + args[1]);
if (!silent) MessagesUtil.sendMessage(sender, "emote-invalid"); if (!silent) MessagesUtil.sendMessage(sender, "emote-invalid");
return true; return true;
} }
}
if (sender.hasPermission("hmccosmetics.cmd.playemote.other")) { if (sender.hasPermission("hmccosmetics.cmd.playemote.other")) {
if (args.length >= 3) player = Bukkit.getPlayer(args[2]); if (args.length >= 3) player = Bukkit.getPlayer(args[2]);
@@ -444,7 +480,7 @@ public class CosmeticCommand implements CommandExecutor {
return true; return true;
} }
CosmeticUser user = CosmeticUsers.getUser(player); CosmeticUser user = CosmeticUsers.getUser(player);
user.getUserEmoteManager().playEmote(args[1]); user.getUserEmoteManager().playEmote(EmoteManager.get(args[1]));
return true; return true;
} }
} }

View File

@@ -1,13 +1,15 @@
package com.hibiscusmc.hmccosmetics.command; package com.hibiscusmc.hmccosmetics.command;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.gui.Menu; import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus; import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.ticxo.playeranimator.api.PlayerAnimator;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@@ -36,7 +38,7 @@ public class CosmeticCommandTabComplete implements TabCompleter {
if (hasPermission(sender, "hmccosmetics.cmd.wardrobe")) completions.add("wardrobe"); if (hasPermission(sender, "hmccosmetics.cmd.wardrobe")) completions.add("wardrobe");
if (hasPermission(sender, "hmccosmetics.cmd.dataclear")) completions.add("dataclear"); if (hasPermission(sender, "hmccosmetics.cmd.dataclear")) completions.add("dataclear");
if (hasPermission(sender, "hmccosmetics.cmd.dye")) completions.add("dye"); if (hasPermission(sender, "hmccosmetics.cmd.dye")) completions.add("dye");
if (hasPermission(sender, "hmccosmetics.cmd.setlocation")) completions.add("setlocation"); if (hasPermission(sender, "hmccosmetics.cmd.setwardrobesetting")) completions.add("setwardrobesetting");
if (hasPermission(sender, "hmccosmetics.cmd.hide")) completions.add("hide"); if (hasPermission(sender, "hmccosmetics.cmd.hide")) completions.add("hide");
if (hasPermission(sender, "hmccosmetics.cmd.show")) completions.add("show"); if (hasPermission(sender, "hmccosmetics.cmd.show")) completions.add("show");
if (hasPermission(sender, "hmccosmetics.cmd.debug")) completions.add("debug"); if (hasPermission(sender, "hmccosmetics.cmd.debug")) completions.add("debug");
@@ -66,24 +68,31 @@ public class CosmeticCommandTabComplete implements TabCompleter {
if (menu.canOpen(user.getPlayer())) completions.add(menu.getId()); if (menu.canOpen(user.getPlayer())) completions.add(menu.getId());
} }
} }
case "dataclear", "wardrobe", "hide", "show", "emote" -> { case "dataclear", "hide", "show", "emote" -> {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
completions.add(player.getName()); completions.add(player.getName());
} }
} }
case "wardrobe" -> {
for (Wardrobe wardrobe : WardrobeSettings.getWardrobes()) {
if (wardrobe.hasPermission()) {
if (user.getPlayer().hasPermission(wardrobe.getPermission())) completions.add(wardrobe.getId());
} else {
completions.add(wardrobe.getId());
}
}
}
case "dye" -> { case "dye" -> {
for (CosmeticSlot slot : user.getDyeableSlots()) { for (CosmeticSlot slot : user.getDyeableSlots()) {
completions.add(slot.name()); completions.add(slot.name());
} }
} }
case "setlocation" -> { case "setwardrobesetting" -> {
completions.add("wardrobelocation"); for (Wardrobe wardrobe : WardrobeSettings.getWardrobes()) {
completions.add("viewerlocation"); completions.add(wardrobe.getId());
completions.add("leavelocation");
} }
case "playemote" -> {
completions.addAll(PlayerAnimator.api.getAnimationManager().getRegistry().keySet());
} }
case "playemote" -> completions.addAll(EmoteManager.getAllNames());
} }
StringUtil.copyPartialMatches(args[1], completions, finalCompletions); StringUtil.copyPartialMatches(args[1], completions, finalCompletions);
} }
@@ -93,11 +102,18 @@ public class CosmeticCommandTabComplete implements TabCompleter {
case "dye" -> { case "dye" -> {
completions.add("#FFFFFF"); completions.add("#FFFFFF");
} }
case "menu", "apply", "unapply", "playemote" -> { case "menu", "wardrobe", "apply", "unapply", "playemote" -> {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
completions.add(player.getName()); completions.add(player.getName());
} }
} }
case "setwardrobesetting" -> {
completions.add("npclocation");
completions.add("viewerlocation");
completions.add("leavelocation");
completions.add("permission");
completions.add("distance");
}
} }
StringUtil.copyPartialMatches(args[2], completions, finalCompletions); StringUtil.copyPartialMatches(args[2], completions, finalCompletions);
} }

View File

@@ -42,6 +42,7 @@ public class Settings {
private static final String HOOK_WG_MOVE_CHECK_PATH = "player-move-check"; private static final String HOOK_WG_MOVE_CHECK_PATH = "player-move-check";
private static final String HOOK_WG_MOVE_CHECK_PATH_LEGACY = "player_move_check"; private static final String HOOK_WG_MOVE_CHECK_PATH_LEGACY = "player_move_check";
private static final String COSMETIC_EMOTE_CHECK_PATH = "emote-block-check"; private static final String COSMETIC_EMOTE_CHECK_PATH = "emote-block-check";
private static final String COSMETIC_EMOTE_AIR_CHECK_PATH = "emote-air-check";
private static final String COSMETIC_EMOTE_DAMAGE_PATH = "emote-damage-leave"; private static final String COSMETIC_EMOTE_DAMAGE_PATH = "emote-damage-leave";
private static final String COSMETIC_EMOTE_INVINCIBLE_PATH = "emote-invincible"; private static final String COSMETIC_EMOTE_INVINCIBLE_PATH = "emote-invincible";
private static final String COSMETIC_ADD_ENCHANTS_HELMET_PATH = "helmet-add-enchantments"; private static final String COSMETIC_ADD_ENCHANTS_HELMET_PATH = "helmet-add-enchantments";
@@ -70,6 +71,7 @@ public class Settings {
private static boolean addChestplateEnchants; private static boolean addChestplateEnchants;
private static boolean addLeggingEnchants; private static boolean addLeggingEnchants;
private static boolean addBootsEnchants; private static boolean addBootsEnchants;
private static boolean emoteAirCheck;
private static boolean emoteDamageLeave; private static boolean emoteDamageLeave;
private static boolean emoteInvincible; private static boolean emoteInvincible;
private static boolean destroyLooseCosmetics; private static boolean destroyLooseCosmetics;
@@ -105,6 +107,7 @@ public class Settings {
forcePermissionJoin = cosmeticSettings.node(FORCE_PERMISSION_JOIN_PATH).getBoolean(false); forcePermissionJoin = cosmeticSettings.node(FORCE_PERMISSION_JOIN_PATH).getBoolean(false);
emoteDistance = cosmeticSettings.node(EMOTE_DISTANCE_PATH).getDouble(-3); emoteDistance = cosmeticSettings.node(EMOTE_DISTANCE_PATH).getDouble(-3);
cosmeticEmoteBlockCheck = cosmeticSettings.node(COSMETIC_EMOTE_CHECK_PATH).getBoolean(true); cosmeticEmoteBlockCheck = cosmeticSettings.node(COSMETIC_EMOTE_CHECK_PATH).getBoolean(true);
emoteAirCheck = cosmeticSettings.node(COSMETIC_EMOTE_AIR_CHECK_PATH).getBoolean(true);
emoteDamageLeave = cosmeticSettings.node(COSMETIC_EMOTE_DAMAGE_PATH).getBoolean(false); emoteDamageLeave = cosmeticSettings.node(COSMETIC_EMOTE_DAMAGE_PATH).getBoolean(false);
emoteInvincible = cosmeticSettings.node(COSMETIC_EMOTE_INVINCIBLE_PATH).getBoolean(false); emoteInvincible = cosmeticSettings.node(COSMETIC_EMOTE_INVINCIBLE_PATH).getBoolean(false);
destroyLooseCosmetics = cosmeticSettings.node(COSMETIC_DESTROY_LOOSE_COSMETIC_PATH).getBoolean(false); destroyLooseCosmetics = cosmeticSettings.node(COSMETIC_DESTROY_LOOSE_COSMETIC_PATH).getBoolean(false);
@@ -263,6 +266,10 @@ public class Settings {
return cosmeticEmoteBlockCheck; return cosmeticEmoteBlockCheck;
} }
public static boolean getEmoteAirCheck() {
return emoteAirCheck;
}
public static boolean isEmoteDamageLeave() { public static boolean isEmoteDamageLeave() {
return emoteDamageLeave; return emoteDamageLeave;
} }

View File

@@ -0,0 +1,61 @@
package com.hibiscusmc.hmccosmetics.config;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.Location;
import javax.annotation.Nullable;
public class Wardrobe {
private String id;
private int distance = WardrobeSettings.getDefaultDistance();
private String permission;
private WardrobeLocation location;
public Wardrobe(String id, WardrobeLocation location, @Nullable String permission, int distance) {
this.id = id;
this.location = location;
if (permission != null) this.permission = permission;
if (distance != -1) this.distance = distance;
}
public String getId() {
return id;
}
public WardrobeLocation getLocation() {
return location;
}
public void setDistance(int distance) {
this.distance = distance;
}
public void setPermission(String permission) {
this.permission = permission;
}
public boolean hasPermission() {
return permission != null;
}
public int getDistance() {
return distance;
}
public String getPermission() {
return permission;
}
public void setLocation(WardrobeLocation location) {
this.location = location;
}
public boolean canEnter(CosmeticUser user) {
Location wardrobeLocation = location.getNpcLocation();
Location location = user.getPlayer().getLocation();
if (wardrobeLocation == null) return false;
if (distance == -1) return true;
if (!wardrobeLocation.getWorld().equals(location.getWorld())) return false;
return wardrobeLocation.distanceSquared(location) <= distance * distance;
}
}

View File

@@ -0,0 +1,45 @@
package com.hibiscusmc.hmccosmetics.config;
import org.bukkit.Location;
public class WardrobeLocation {
private Location npcLocation;
private Location viewerLocation;
private Location leaveLocation;
public WardrobeLocation(Location npcLocation, Location viewerLocation, Location leaveLocation) {
this.npcLocation = npcLocation;
this.viewerLocation = viewerLocation;
this.leaveLocation = leaveLocation;
}
public Location getNpcLocation() {
return npcLocation.clone();
}
public Location getViewerLocation() {
return viewerLocation.clone();
}
public Location getLeaveLocation() {
return leaveLocation.clone();
}
public boolean hasAllLocations() {
if (npcLocation == null || viewerLocation == null || leaveLocation == null) return false;
return true;
}
public void setNPCLocation(Location wardrobeLocation) {
this.npcLocation = wardrobeLocation;
}
public void setViewerLocation(Location viewerLocation) {
this.viewerLocation = viewerLocation;
}
public void setLeaveLocation(Location leaveLocation) {
this.leaveLocation = leaveLocation;
}
}

View File

@@ -9,7 +9,9 @@ import org.apache.commons.lang3.EnumUtils;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.*;
import java.util.logging.Level;
public class WardrobeSettings { public class WardrobeSettings {
@@ -25,14 +27,18 @@ public class WardrobeSettings {
private static final String APPLY_COSMETICS_ON_CLOSE = "apply-cosmetics-on-close"; private static final String APPLY_COSMETICS_ON_CLOSE = "apply-cosmetics-on-close";
private static final String OPEN_SOUND = "open-sound"; private static final String OPEN_SOUND = "open-sound";
private static final String CLOSE_SOUND = "close-sound"; private static final String CLOSE_SOUND = "close-sound";
private static final String STATIC_LOCATION_PATH = "wardrobe-location"; private static final String NPC_LOCATION_PATH = "npc-location";
private static final String VIEWER_LOCATION_PATH = "viewer-location"; private static final String VIEWER_LOCATION_PATH = "viewer-location";
private static final String LEAVE_LOCATION_PATH = "leave-location"; private static final String LEAVE_LOCATION_PATH = "leave-location";
private static final String EQUIP_PUMPKIN_WARDROBE = "equip-pumpkin"; private static final String EQUIP_PUMPKIN_WARDROBE = "equip-pumpkin";
private static final String TRY_COSMETICS_WARDROBE = "unchecked-wardrobe-cosmetics";
private static final String RETURN_LAST_LOCATION = "return-last-location"; private static final String RETURN_LAST_LOCATION = "return-last-location";
private static final String GAMEMODE_OPTIONS_PATH = "gamemode-options"; private static final String GAMEMODE_OPTIONS_PATH = "gamemode-options";
private static final String FORCE_EXIT_GAMEMODE_PATH = "exit-gamemode-enabled"; private static final String FORCE_EXIT_GAMEMODE_PATH = "exit-gamemode-enabled";
private static final String EXIT_GAMEMODE_PATH = "exit-gamemode"; private static final String EXIT_GAMEMODE_PATH = "exit-gamemode";
private static final String WARDROBES_PATH = "wardrobes";
private static final String PERMISSION_PATH = "permission";
private static final String DISTANCE_PATH = "distance";
private static final String BOSSBAR_PATH = "bossbar"; private static final String BOSSBAR_PATH = "bossbar";
private static final String BOSSBAR_ENABLE_PATH = "enabled"; private static final String BOSSBAR_ENABLE_PATH = "enabled";
private static final String BOSSBAR_TEXT_PATH = "text"; private static final String BOSSBAR_TEXT_PATH = "text";
@@ -58,14 +64,13 @@ public class WardrobeSettings {
private static int despawnDelay; private static int despawnDelay;
private static float bossbarProgress; private static float bossbarProgress;
private static boolean applyCosmeticsOnClose; private static boolean applyCosmeticsOnClose;
private static boolean tryCosmeticsInWardrobe;
private static boolean equipPumpkin; private static boolean equipPumpkin;
private static boolean returnLastLocation; private static boolean returnLastLocation;
private static boolean enabledBossbar; private static boolean enabledBossbar;
private static boolean forceExitGamemode; private static boolean forceExitGamemode;
private static GameMode exitGamemode; private static GameMode exitGamemode;
private static Location wardrobeLocation; private static HashMap<String, Wardrobe> wardrobes;
private static Location viewerLocation;
private static Location leaveLocation;
private static String bossbarMessage; private static String bossbarMessage;
private static BossBar.Overlay bossbarOverlay; private static BossBar.Overlay bossbarOverlay;
private static BossBar.Color bossbarColor; private static BossBar.Color bossbarColor;
@@ -90,6 +95,7 @@ public class WardrobeSettings {
applyCosmeticsOnClose = source.node(APPLY_COSMETICS_ON_CLOSE).getBoolean(); applyCosmeticsOnClose = source.node(APPLY_COSMETICS_ON_CLOSE).getBoolean();
equipPumpkin = source.node(EQUIP_PUMPKIN_WARDROBE).getBoolean(); equipPumpkin = source.node(EQUIP_PUMPKIN_WARDROBE).getBoolean();
returnLastLocation = source.node(RETURN_LAST_LOCATION).getBoolean(false); returnLastLocation = source.node(RETURN_LAST_LOCATION).getBoolean(false);
tryCosmeticsInWardrobe = source.node(TRY_COSMETICS_WARDROBE).getBoolean(false);
ConfigurationNode gamemodeNode = source.node(GAMEMODE_OPTIONS_PATH); ConfigurationNode gamemodeNode = source.node(GAMEMODE_OPTIONS_PATH);
forceExitGamemode = gamemodeNode.node(FORCE_EXIT_GAMEMODE_PATH).getBoolean(false); forceExitGamemode = gamemodeNode.node(FORCE_EXIT_GAMEMODE_PATH).getBoolean(false);
@@ -119,17 +125,37 @@ public class WardrobeSettings {
transitionStay = transitionNode.node(TRANSITION_STAY_PATH).getInt(2000); transitionStay = transitionNode.node(TRANSITION_STAY_PATH).getInt(2000);
transitionFadeOut = transitionNode.node(TRANSITION_FADE_OUT_PATH).getInt(2000); transitionFadeOut = transitionNode.node(TRANSITION_FADE_OUT_PATH).getInt(2000);
wardrobes = new HashMap<>();
for (ConfigurationNode wardrobesNode : source.node(WARDROBES_PATH).childrenMap().values()) {
String id = wardrobesNode.key().toString();
try { try {
wardrobeLocation = LocationSerializer.INSTANCE.deserialize(Location.class, source.node(STATIC_LOCATION_PATH)); Location npcLocation = LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(NPC_LOCATION_PATH));
MessagesUtil.sendDebugMessages("Wardrobe Location: " + wardrobeLocation); MessagesUtil.sendDebugMessages("Wardrobe Location: " + npcLocation);
viewerLocation = LocationSerializer.INSTANCE.deserialize(Location.class, source.node(VIEWER_LOCATION_PATH)); Location viewerLocation = LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(VIEWER_LOCATION_PATH));
MessagesUtil.sendDebugMessages("Viewer Location: " + viewerLocation); MessagesUtil.sendDebugMessages("Viewer Location: " + viewerLocation);
leaveLocation = Utils.replaceIfNull(LocationSerializer.INSTANCE.deserialize(Location.class, source.node(LEAVE_LOCATION_PATH)), viewerLocation); Location leaveLocation = Utils.replaceIfNull(LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(LEAVE_LOCATION_PATH)), viewerLocation);
} catch (SerializationException e) { MessagesUtil.sendDebugMessages("Leave Location: " + leaveLocation);
throw new RuntimeException(e); WardrobeLocation wardrobeLocation = new WardrobeLocation(npcLocation, viewerLocation, leaveLocation);
String permission = null;
int distance = -1;
if (!wardrobesNode.node(PERMISSION_PATH).virtual()) permission = wardrobesNode.node(PERMISSION_PATH).getString();
if (!wardrobesNode.node(DISTANCE_PATH).virtual()) distance = wardrobesNode.node(DISTANCE_PATH).getInt();
Wardrobe wardrobe = new Wardrobe(id, wardrobeLocation, permission, distance);
addWardrobe(wardrobe);
} catch (Exception e) {
MessagesUtil.sendDebugMessages("Unable to create wardrobe " + id, Level.SEVERE);
} }
} }
//throw new RuntimeException(e);
}
public static int getDefaultDistance() {
return staticRadius;
}
public static boolean getDisableOnDamage() { public static boolean getDisableOnDamage() {
return disableOnDamage; return disableOnDamage;
} }
@@ -172,25 +198,36 @@ public class WardrobeSettings {
return returnLastLocation; return returnLastLocation;
} }
public static Location getWardrobeLocation() { public static Wardrobe getWardrobe(String key) {
return wardrobeLocation.clone(); return wardrobes.get(key);
} }
public static Location getViewerLocation() { public static Set<String> getWardrobeNames() {
return viewerLocation; return wardrobes.keySet();
} }
public static Location getLeaveLocation() { public static Collection<Wardrobe> getWardrobes() {
return leaveLocation; return wardrobes.values();
} }
public static void addWardrobe(Wardrobe wardrobe) {
wardrobes.put(wardrobe.getId(), wardrobe);
}
public static void removeWardrobe(String id) {
wardrobes.remove(id);
}
@Deprecated
public static boolean inDistanceOfWardrobe(final Location wardrobeLocation, final Location playerLocation) { public static boolean inDistanceOfWardrobe(final Location wardrobeLocation, final Location playerLocation) {
if (displayRadius == -1) return true; if (displayRadius == -1) return true;
if (!wardrobeLocation.getWorld().equals(playerLocation.getWorld())) return false; if (!wardrobeLocation.getWorld().equals(playerLocation.getWorld())) return false;
return playerLocation.distanceSquared(wardrobeLocation) <= displayRadius * displayRadius; return playerLocation.distanceSquared(wardrobeLocation) <= displayRadius * displayRadius;
} }
public static boolean inDistanceOfStatic(final Location location) { @Deprecated
public static boolean inDistanceOfStatic(Wardrobe wardrobe, final Location location) {
Location wardrobeLocation = wardrobe.getLocation().getNpcLocation();
if (wardrobeLocation == null) return false; if (wardrobeLocation == null) return false;
if (staticRadius == -1) return true; if (staticRadius == -1) return true;
if (!wardrobeLocation.getWorld().equals(location.getWorld())) return false; if (!wardrobeLocation.getWorld().equals(location.getWorld())) return false;
@@ -245,57 +282,84 @@ public class WardrobeSettings {
return exitGamemode; return exitGamemode;
} }
public static void setWardrobeLocation(Location newLocation) { public static boolean isTryCosmeticsInWardrobe() {
wardrobeLocation = newLocation; return tryCosmeticsInWardrobe;
}
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance(); /**
* Sets where the NPC/Mannequin will spawn in the wardrobe
plugin.getConfig().set("wardrobe.wardrobe-location." + "world", newLocation.getWorld().getName()); * @param newLocation
plugin.getConfig().set("wardrobe.wardrobe-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobe-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobe-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobe-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobe-location." + "pitch", newLocation.getPitch());
/* Configuration sets suck
source.node(WORLD).set(loc.getWorld().getName());
source.node(X).set(loc.getX());
source.node(Y).set(loc.getY());
source.node(Z).set(loc.getZ());
source.node(YAW).set(loc.getYaw());
source.node(PITCH).set(loc.getPitch());
*/ */
public static void setNPCLocation(Wardrobe wardrobe, Location newLocation) {
HMCCosmeticsPlugin.getInstance().saveConfig(); wardrobe.getLocation().setNPCLocation(newLocation);
}
public static void setViewerLocation(Location newLocation) {
viewerLocation = newLocation;
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance(); HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.viewer-location." + "world", newLocation.getWorld().getName()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.viewer-location." + "x", newLocation.getX()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.viewer-location." + "y", newLocation.getY()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.viewer-location." + "z", newLocation.getZ()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.viewer-location." + "yaw", newLocation.getYaw()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.viewer-location." + "pitch", newLocation.getPitch()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "pitch", newLocation.getPitch());
HMCCosmeticsPlugin.getInstance().saveConfig(); plugin.saveConfig();
} }
public static void setLeaveLocation(Location newLocation) { /**
leaveLocation = newLocation; * Sets where the player will view the wardrobe
* @param newLocation
*/
public static void setViewerLocation(Wardrobe wardrobe, Location newLocation) {
wardrobe.getLocation().setViewerLocation(newLocation);
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance(); HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.leave-location." + "world", newLocation.getWorld().getName()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.leave-location." + "x", newLocation.getX()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.x", newLocation.getX());
plugin.getConfig().set("wardrobe.leave-location." + "y", newLocation.getY()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.y", newLocation.getY());
plugin.getConfig().set("wardrobe.leave-location." + "z", newLocation.getZ()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.z", newLocation.getZ());
plugin.getConfig().set("wardrobe.leave-location." + "yaw", newLocation.getYaw()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.leave-location." + "pitch", newLocation.getPitch()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.pitch", newLocation.getPitch());
HMCCosmeticsPlugin.getInstance().saveConfig(); plugin.saveConfig();
}
/**
* Sets where a player will leave the wardrobe from
* @param newLocation
*/
public static void setLeaveLocation(Wardrobe wardrobe, Location newLocation) {
wardrobe.getLocation().setLeaveLocation(newLocation);
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.pitch", newLocation.getPitch());
plugin.saveConfig();
}
public static void setWardrobePermission(Wardrobe wardrobe, String permission) {
wardrobe.setPermission(permission);
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".permission", permission);
plugin.saveConfig();
}
public static void setWardrobeDistance(Wardrobe wardrobe, int distance) {
wardrobe.setDistance(distance);
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".distance", distance);
plugin.saveConfig();
} }
} }

View File

@@ -143,9 +143,6 @@ public class ItemSerializer implements TypeSerializer<ItemStack> {
} }
} }
NamespacedKey key = new NamespacedKey(HMCCosmeticsPlugin.getInstance(), source.key().toString());
itemMeta.getPersistentDataContainer().set(key, PersistentDataType.STRING, source.key().toString());
item.setItemMeta(itemMeta); item.setItemMeta(itemMeta);
return item; return item;
} }

View File

@@ -17,6 +17,7 @@ public abstract class Cosmetic {
private String id; private String id;
private String permission; private String permission;
private ItemStack item; private ItemStack item;
private String material;
private CosmeticSlot slot; private CosmeticSlot slot;
private boolean dyable; private boolean dyable;
@@ -29,7 +30,10 @@ public abstract class Cosmetic {
this.permission = null; this.permission = null;
} }
if (!config.node("item").virtual()) this.item = generateItemStack(config.node("item")); if (!config.node("item").virtual()) {
this.material = config.node("item", "material").getString();
this.item = generateItemStack(config.node("item"));
}
MessagesUtil.sendDebugMessages("Slot: " + config.node("slot").getString()); MessagesUtil.sendDebugMessages("Slot: " + config.node("slot").getString());
@@ -76,6 +80,10 @@ public abstract class Cosmetic {
return this.dyable; return this.dyable;
} }
public String getMaterial() {
return material;
}
public abstract void update(CosmeticUser user); public abstract void update(CosmeticUser user);
@Nullable @Nullable

View File

@@ -28,6 +28,7 @@ public class CosmeticArmorType extends Cosmetic {
public void update(@NotNull CosmeticUser user) { public void update(@NotNull CosmeticUser user) {
Player player = Bukkit.getPlayer(user.getUniqueId()); Player player = Bukkit.getPlayer(user.getUniqueId());
if (player == null) return; if (player == null) return;
if (user.getUserEmoteManager().isPlayingEmote()) return; // There has to be a better way of doing this...
ItemStack cosmeticItem = user.getUserCosmeticItem(this); ItemStack cosmeticItem = user.getUserCosmeticItem(this);
if (equipSlot.equals(EquipmentSlot.OFF_HAND)) { if (equipSlot.equals(EquipmentSlot.OFF_HAND)) {
if (!player.getInventory().getItemInOffHand().getType().isAir()) return; if (!player.getInventory().getItemInOffHand().getType().isAir()) return;

View File

@@ -34,7 +34,7 @@ public class CosmeticBackpackType extends Cosmetic {
if (user.isInWardrobe() || !user.isBackpackSpawned()) return; if (user.isInWardrobe() || !user.isBackpackSpawned()) return;
if (!user.getUserBackpackManager().getArmorStand().isValid()) { if (!user.getUserBackpackManager().getArmorStand().isValid()) {
MessagesUtil.sendDebugMessages("Invalid Backpack detected! Respawning backpack, report this on the discord if this happens often!", Level.WARNING); MessagesUtil.sendDebugMessages("Invalid Backpack Entity[owner=" + user.getUniqueId() + ",player_location=" + loc + "]!", Level.WARNING);
user.respawnBackpack(); user.respawnBackpack();
return; return;
} }

View File

@@ -0,0 +1,85 @@
package com.hibiscusmc.hmccosmetics.emotes;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.ticxo.playeranimator.api.PlayerAnimator;
import com.ticxo.playeranimator.api.animation.pack.AnimationPack;
import org.apache.commons.io.FilenameUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Manages Emotes
*/
@SuppressWarnings("SpellCheckingInspection")
public class EmoteManager {
private static final @NotNull Map<@NotNull String, @NotNull String> emotes = new HashMap<>();
/**
* Loads all BlockBench animations from the emotes folder and puts it into the animation manager registry and local registry
*/
public static void loadEmotes() {
// Clear the PlayerAnimator and local registries
PlayerAnimator.api.getAnimationManager().clearRegistry();
emotes.clear();
// Get the emote directory and check if it exists
File emoteDir = new File(HMCCosmeticsPlugin.getInstance().getDataFolder().getPath() + "/emotes/");
if (!emoteDir.exists()) return;
// Get all the files inside the directory and check if it isn't 0
File[] emoteFiles = emoteDir.listFiles();
if (emoteFiles == null || emoteFiles.length == 0) return;
// Remove any files that don't have the file extension ".bbmodel" and check if there are still resulting files
emoteFiles = Arrays.stream(emoteFiles).filter(file -> file.getPath().endsWith(".bbmodel")).distinct().toArray(File[]::new);
if (emoteFiles.length == 0) return;
// Loop through all files, importing all block bench animations into the registry
for (File animationFile : emoteFiles) {
String animationKey = FilenameUtils.removeExtension(animationFile.getName());
PlayerAnimator.api.getAnimationManager().importAnimations(animationKey, animationFile);
}
// Loops through all the entries in the registries and unpacks any animation packs to ensure if there were multiple animations
// inside a singular file, that they are added to the local registry individually for tab completion
for (Map.Entry<String, AnimationPack> packEntry : PlayerAnimator.api.getAnimationManager().getRegistry().entrySet()) {
packEntry.getValue().getAnimations().keySet().forEach(animationName -> {
// API key is the format "animationKey.animationFileName.animationName"
String apiKey = packEntry.getKey().replace(":", ".") + "." + animationName;
emotes.put(animationName, apiKey);
});
}
}
/**
* Returns true if there is an animation with the specified name
* @param animationName Name whose presence is to be tested
* @return True if this registry contains a mapping for the specified name
*/
public static boolean has(@NotNull String animationName) {
return emotes.containsKey(animationName);
}
/**
* Returns the {@code API key} to which the specified name is mapped, or {@code null} if this map contains no mapping for the name.
* @param animationName Name whose {@code API key} is to be fetched
* @return The {@code API key} of the specified name or {@code null} if there was no animation name found
*/
public static @Nullable String get(@NotNull String animationName) {
return emotes.get(animationName);
}
/**
* Gets a set of all the laoded animation names
* @return A set of all loaded animation names
*/
public static @NotNull Set<String> getAllNames() {
return emotes.keySet();
}
}

View File

@@ -105,7 +105,7 @@ public class Menu {
for (ConfigurationNode config : config.node("items").childrenMap().values()) { for (ConfigurationNode config : config.node("items").childrenMap().values()) {
List<String> slotString = null; List<String> slotString;
try { try {
slotString = config.node("slots").getList(String.class); slotString = config.node("slots").getList(String.class);
} catch (SerializationException e) { } catch (SerializationException e) {
@@ -118,17 +118,14 @@ public class Menu {
List<Integer> slots = getSlots(slotString); List<Integer> slots = getSlots(slotString);
if (slots == null) { if (slots == null) {
MessagesUtil.sendDebugMessages("Slot is null for " + config.key().toString()); MessagesUtil.sendDebugMessages("Slot is null for " + config.key().toString());
continue; continue;
} }
ItemStack item; ItemStack item;
try { try {
item = ItemSerializer.INSTANCE.deserialize(ItemStack.class, config.node("item")); item = ItemSerializer.INSTANCE.deserialize(ItemStack.class, config.node("item"));
//item = config.node("item").get(ItemStack.class);
} catch (SerializationException e) { } catch (SerializationException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -145,24 +142,25 @@ public class Menu {
if (Types.isType(typeId)) type = Types.getType(typeId); if (Types.isType(typeId)) type = Types.getType(typeId);
} }
ItemStack originalItem = item.clone(); for (int slot : slots) {
item = updateLore(user, item, type, config); ItemStack modifiedItem = getMenuItem(user, type, config, item.clone(), slot).clone();
GuiItem guiItem = ItemBuilder.from(modifiedItem).asGuiItem();
GuiItem guiItem = ItemBuilder.from(item).asGuiItem();
Type finalType = type; Type finalType = type;
guiItem.setAction(event -> { guiItem.setAction(event -> {
MessagesUtil.sendDebugMessages("Selected slot " + slot);
final ClickType clickType = event.getClick(); final ClickType clickType = event.getClick();
if (finalType != null) finalType.run(user, config, clickType); if (finalType != null) finalType.run(user, config, clickType);
// Need to delay the update by a tick so it will actually update with new values
for (int i : slots) { for (int guiSlot : slots) {
gui.updateItem(i, updateLore(user, originalItem.clone(), finalType, config)); gui.updateItem(guiSlot, getMenuItem(user, finalType, config, item.clone(), guiSlot));
MessagesUtil.sendDebugMessages("Updated slot " + i);
} }
MessagesUtil.sendDebugMessages("Updated slot " + slot);
}); });
MessagesUtil.sendDebugMessages("Added " + slots + " as " + guiItem + " in the menu"); MessagesUtil.sendDebugMessages("Added " + slots + " as " + guiItem + " in the menu");
gui.setItem(slots, guiItem); gui.setItem(slot, guiItem);
}
} }
return gui; return gui;
} }
@@ -195,11 +193,9 @@ public class Menu {
@Contract("_, _, _, _ -> param2") @Contract("_, _, _, _ -> param2")
@NotNull @NotNull
private ItemStack updateLore(CosmeticUser user, @NotNull ItemStack itemStack, Type type, ConfigurationNode config) { private ItemStack getMenuItem(CosmeticUser user, Type type, ConfigurationNode config, ItemStack itemStack, int slot) {
if (itemStack.hasItemMeta()) { if (!itemStack.hasItemMeta()) return itemStack;
itemStack.setItemMeta(type.setLore(user, config, itemStack.getItemMeta())); return type.setItem(user, config, itemStack, slot);
}
return itemStack;
} }
public String getPermissionNode() { public String getPermissionNode() {

View File

@@ -56,6 +56,10 @@ public class Menus {
return names; return names;
} }
public static Collection<Menu> values() {
return MENUS.values();
}
public static void setup() { public static void setup() {
MENUS.clear(); MENUS.clear();

View File

@@ -48,6 +48,7 @@ public class DyeMenu {
if (color == null) return; if (color == null) return;
addCosmetic(user, cosmetic, color); addCosmetic(user, cosmetic, color);
event.setCancelled(true);
} else event.setCancelled(true); } else event.setCancelled(true);
}); });

View File

@@ -2,6 +2,7 @@ package com.hibiscusmc.hmccosmetics.gui.type;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.ConfigurationNode;
@@ -24,5 +25,5 @@ public abstract class Type {
public abstract void run(CosmeticUser user, ConfigurationNode config, ClickType clickType); public abstract void run(CosmeticUser user, ConfigurationNode config, ClickType clickType);
public abstract ItemMeta setLore(CosmeticUser user, ConfigurationNode config, ItemMeta itemMeta); public abstract ItemStack setItem(CosmeticUser user, ConfigurationNode config, ItemStack itemStack, int slot);
} }

View File

@@ -1,6 +1,7 @@
package com.hibiscusmc.hmccosmetics.gui.type.types; package com.hibiscusmc.hmccosmetics.gui.type.types;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.serializer.ItemSerializer;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
@@ -17,12 +18,14 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.serialize.SerializationException;
import java.lang.invoke.TypeDescriptor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -72,7 +75,7 @@ public class TypeCosmetic extends Type {
if (!actionConfig.node("on-equip").virtual()) actionStrings.addAll(actionConfig.node("on-equip").getList(String.class)); if (!actionConfig.node("on-equip").virtual()) actionStrings.addAll(actionConfig.node("on-equip").getList(String.class));
MessagesUtil.sendDebugMessages("on-equip"); MessagesUtil.sendDebugMessages("on-equip");
// TODO: Redo this // TODO: Redo this
if (cosmetic.isDyable()) { if (cosmetic.isDyable() && Hooks.isActiveHook("HMCColor")) {
DyeMenu.openMenu(user, cosmetic); DyeMenu.openMenu(user, cosmetic);
} else { } else {
user.addPlayerCosmetic(cosmetic); user.addPlayerCosmetic(cosmetic);
@@ -89,62 +92,58 @@ public class TypeCosmetic extends Type {
if (cosmetic instanceof CosmeticArmorType) { if (cosmetic instanceof CosmeticArmorType) {
if (((CosmeticArmorType) cosmetic).getEquipSlot().equals(EquipmentSlot.OFF_HAND)) { if (((CosmeticArmorType) cosmetic).getEquipSlot().equals(EquipmentSlot.OFF_HAND)) {
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), run, 1); Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), run, 1);
return;
} }
} }
run.run(); run.run();
} }
@Override @Override
public ItemMeta setLore(CosmeticUser user, @NotNull ConfigurationNode config, ItemMeta itemMeta) { public ItemStack setItem(CosmeticUser user, @NotNull ConfigurationNode config, ItemStack itemStack, int slot) {
List<String> processedLore = new ArrayList<>(); itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
if (config.node("cosmetic").virtual()) return processLoreLines(user, itemMeta);; if (config.node("cosmetic").virtual()) {
return itemStack;
}
String cosmeticName = config.node("cosmetic").getString(); String cosmeticName = config.node("cosmetic").getString();
Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName); Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName);
if (cosmetic == null) { if (cosmetic == null) {
return processLoreLines(user, itemMeta); return itemStack;
} }
if (user.canEquipCosmetic(cosmetic)) { if (user.hasCosmeticInSlot(cosmetic) && !config.node("equipped-item").virtual()) {
return processLoreLines(user, itemMeta); MessagesUtil.sendDebugMessages("GUI Equipped Item");
} else { ConfigurationNode equippedItem = config.node("equipped-item");
ConfigurationNode itemConfig = config.node("item"); try {
if (itemConfig.virtual()) return itemMeta; if (equippedItem.node("material").virtual()) equippedItem.node("material").set(config.node("item", "material").getString());
if (itemConfig.node("locked-name").virtual() && itemConfig.node("locked-lore").virtual()) { } catch (SerializationException e) {
return processLoreLines(user, itemMeta); // Nothing >:)
} }
try { try {
List<String> lockedLore = itemMeta.getLore(); itemStack = ItemSerializer.INSTANCE.deserialize(ItemStack.class, equippedItem);
String lockedName = itemMeta.getDisplayName(); } catch (SerializationException e) {
throw new RuntimeException(e);
if (!itemConfig.node("locked-lore").virtual()) {
lockedLore = Utils.replaceIfNull(itemConfig.node("locked-lore").getList(String.class),
new ArrayList<String>()).
stream().map(StringUtils::parseStringToString).collect(Collectors.toList());
} }
if (!itemConfig.node("locked-name").virtual()) { itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
lockedName = StringUtils.parseStringToString(Utils.replaceIfNull(itemConfig.node("locked-name").getString(), "")); return itemStack;
} }
if (Hooks.isActiveHook("PlaceHolderAPI")) { if (!user.canEquipCosmetic(cosmetic) && !config.node("locked-item").virtual()) {
lockedName = PlaceholderAPI.setPlaceholders(user.getPlayer(), lockedName); MessagesUtil.sendDebugMessages("GUI Locked Item");
ConfigurationNode lockedItem = config.node("locked-item");
try {
if (lockedItem.node("material").virtual()) lockedItem.node("material").set(config.node("item", "material").getString());
} catch (SerializationException e) {
// Nothing >:)
} }
itemMeta.setDisplayName(lockedName); try {
if (itemMeta.hasLore()) { itemStack = ItemSerializer.INSTANCE.deserialize(ItemStack.class, lockedItem);
itemMeta.getLore().clear(); } catch (SerializationException e) {
for (String loreLine : lockedLore) { throw new RuntimeException(e);
if (Hooks.isActiveHook("PlaceHolderAPI")) loreLine = PlaceholderAPI.setPlaceholders(user.getPlayer(), loreLine);
processedLore.add(loreLine);
} }
itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
return itemStack;
} }
} catch (Exception e) { return itemStack;
e.printStackTrace();
}
}
itemMeta.setLore(processedLore);
return itemMeta;
} }
@Contract("_, _ -> param2") @Contract("_, _ -> param2")
@@ -155,12 +154,10 @@ public class TypeCosmetic extends Type {
if (itemMeta.hasLore()) { if (itemMeta.hasLore()) {
for (String loreLine : itemMeta.getLore()) { for (String loreLine : itemMeta.getLore()) {
if (Hooks.isActiveHook("PlaceholderAPI")) if (Hooks.isActiveHook("PlaceholderAPI")) loreLine = PlaceholderAPI.setPlaceholders(user.getPlayer(), loreLine);
loreLine = PlaceholderAPI.setPlaceholders(user.getPlayer(), loreLine);
processedLore.add(loreLine); processedLore.add(loreLine);
} }
} }
itemMeta.setLore(processedLore); itemMeta.setLore(processedLore);
return itemMeta; return itemMeta;
} }

View File

@@ -6,6 +6,7 @@ import com.hibiscusmc.hmccosmetics.hooks.Hooks;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.ConfigurationNode;
@@ -53,8 +54,9 @@ public class TypeEmpty extends Type {
@Override @Override
@SuppressWarnings("Duplicates") @SuppressWarnings("Duplicates")
public ItemMeta setLore(CosmeticUser user, ConfigurationNode config, @NotNull ItemMeta itemMeta) { public ItemStack setItem(CosmeticUser user, ConfigurationNode config, @NotNull ItemStack itemStack, int slot) {
List<String> processedLore = new ArrayList<>(); List<String> processedLore = new ArrayList<>();
ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta.hasLore()) { if (itemMeta.hasLore()) {
for (String loreLine : itemMeta.getLore()) { for (String loreLine : itemMeta.getLore()) {
@@ -63,8 +65,8 @@ public class TypeEmpty extends Type {
processedLore.add(loreLine); processedLore.add(loreLine);
} }
} }
itemStack.setItemMeta(itemMeta);
return itemMeta; return itemStack;
} }
// That's it! Now, add it as a static in another one of your classes (such as your main class) and you are good to go. // That's it! Now, add it as a static in another one of your classes (such as your main class) and you are good to go.

View File

@@ -2,10 +2,7 @@ package com.hibiscusmc.hmccosmetics.hooks;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.hooks.items.*; import com.hibiscusmc.hmccosmetics.hooks.items.*;
import com.hibiscusmc.hmccosmetics.hooks.misc.HookCMI; import com.hibiscusmc.hmccosmetics.hooks.misc.*;
import com.hibiscusmc.hmccosmetics.hooks.misc.HookHMCColor;
import com.hibiscusmc.hmccosmetics.hooks.misc.HookPremiumVanish;
import com.hibiscusmc.hmccosmetics.hooks.misc.HookSuperVanish;
import com.hibiscusmc.hmccosmetics.hooks.placeholders.HookPlaceholderAPI; import com.hibiscusmc.hmccosmetics.hooks.placeholders.HookPlaceholderAPI;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
@@ -20,14 +17,16 @@ public class Hooks {
private static final HashMap<String, Hook> hooks = new HashMap<>(); private static final HashMap<String, Hook> hooks = new HashMap<>();
private static HookOraxen ORAXEN_HOOK = new HookOraxen(); private static HookOraxen ORAXEN_HOOK = new HookOraxen();
private static HookItemAdder ITEMADDER_HOOK = new HookItemAdder(); private static HookItemAdder ITEMADDER_HOOK = new HookItemAdder();
private static HookLooty LOOTY_HOOK = new HookLooty(); private static HookGeary GEARY_HOOK = new HookGeary();
private static HookMythic MYTHIC_HOOK = new HookMythic(); private static HookMythic MYTHIC_HOOK = new HookMythic();
private static HookDenizen DENIZEN_HOOK = new HookDenizen();
private static HookHMCCosmetics HMCCOSMETIC_HOOK = new HookHMCCosmetics(); private static HookHMCCosmetics HMCCOSMETIC_HOOK = new HookHMCCosmetics();
private static HookPlaceholderAPI PAPI_HOOK = new HookPlaceholderAPI(); private static HookPlaceholderAPI PAPI_HOOK = new HookPlaceholderAPI();
private static HookPremiumVanish PREMIUM_VANISH_HOOK = new HookPremiumVanish(); private static HookPremiumVanish PREMIUM_VANISH_HOOK = new HookPremiumVanish();
private static HookSuperVanish SUPER_VANISH_HOOK = new HookSuperVanish(); private static HookSuperVanish SUPER_VANISH_HOOK = new HookSuperVanish();
private static HookHMCColor HMC_COLOR_HOOK = new HookHMCColor(); private static HookHMCColor HMC_COLOR_HOOK = new HookHMCColor();
private static HookCMI CMI_HOOK = new HookCMI(); private static HookCMI CMI_HOOK = new HookCMI();
private static HookLibsDisguises LIBS_DISGUISES_HOOK = new HookLibsDisguises();
public static Hook getHook(@NotNull String id) { public static Hook getHook(@NotNull String id) {
return hooks.get(id.toLowerCase()); return hooks.get(id.toLowerCase());

View File

@@ -0,0 +1,27 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.denizenscript.denizen.objects.ItemTag;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* A hook that integrates the plugin {@link com.denizenscript.denizen.Denizen Denizen} to provide custom items
*/
@SuppressWarnings("SpellCheckingInspection")
public class HookDenizen extends Hook {
public HookDenizen() {
super("denizen");
setEnabledItemHook(true);
}
/**
* Gets a cosmetic {@link ItemStack} that is associated with the provided id from the plugin {@link com.denizenscript.denizen.Denizen Denizen}
*/
@Override
public ItemStack getItem(@NotNull String itemId) {
ItemTag item = ItemTag.valueOf(itemId, CoreUtilities.noDebugContext);
return item == null ? null : item.getItemStack();
}
}

View File

@@ -0,0 +1,41 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import com.mineinabyss.geary.addons.GearyPhase;
import com.mineinabyss.geary.modules.GearyModuleKt;
import com.mineinabyss.geary.papermc.tracking.items.ItemTrackingKt;
import com.mineinabyss.geary.prefabs.PrefabKey;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* A hook that integrates the plugin {@link com.mineinabyss.geary.papermc.GearyPlugin Geary} to provide custom items
*/
@SuppressWarnings("SpellCheckingInspection")
public class HookGeary extends Hook {
private boolean enabled = false;
public HookGeary() {
super("geary");
setEnabledItemHook(true);
GearyModuleKt.getGeary().getPipeline().intercept(GearyPhase.ENABLE, () -> {
enabled = true;
HMCCosmeticsPlugin.setup();
return null;
});
}
/**
* Gets a cosmetic {@link ItemStack} that is associated with the provided id from the plugin {@link com.mineinabyss.geary.papermc.GearyPlugin Geary}
*/
@Override
public ItemStack getItem(@NotNull String itemId) {
if (enabled) {
PrefabKey prefabKey = PrefabKey.Companion.ofOrNull(itemId);
if (prefabKey == null) return null;
return ItemTrackingKt.getItemTracking().getProvider().serializePrefabToItemStack(prefabKey, null);
} else return new ItemStack(Material.AIR);
}
}

View File

@@ -1,28 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import com.mineinabyss.geary.prefabs.PrefabKey;
import com.mineinabyss.looty.LootyFactory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* A hook that integrates the plugin {@link com.mineinabyss.looty.LootyPlugin Looty} to provide custom items
*/
@SuppressWarnings("SpellCheckingInspection")
public class HookLooty extends Hook {
public HookLooty() {
super("looty");
setEnabledItemHook(true);
}
/**
* Gets a cosmetic {@link ItemStack} that is associated with the provided id from the plugin {@link com.mineinabyss.looty.LootyPlugin Looty}
*/
@Override
public ItemStack getItem(@NotNull String itemId) {
PrefabKey prefabKey = PrefabKey.Companion.ofOrNull(itemId);
if (prefabKey == null) return null;
return LootyFactory.INSTANCE.createFromPrefab(prefabKey);
}
}

View File

@@ -0,0 +1,32 @@
package com.hibiscusmc.hmccosmetics.hooks.misc;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import me.libraryaddict.disguise.events.DisguiseEvent;
import me.libraryaddict.disguise.events.UndisguiseEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.jetbrains.annotations.NotNull;
public class HookLibsDisguises extends Hook {
public HookLibsDisguises() {
super("LibsDisguises");
}
@EventHandler
public void onPlayerVanish(@NotNull DisguiseEvent event) {
if (!(event.getEntity() instanceof Player player)) return;
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
user.hideCosmetics(CosmeticUser.HiddenReason.PLUGIN);
}
@EventHandler
public void onPlayerShow(@NotNull UndisguiseEvent event) {
if (!(event.getEntity() instanceof Player player)) return;
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
user.showCosmetics();
}
}

View File

@@ -47,6 +47,11 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
return HMCCosmeticsPlugin.getInstance().getDescription().getVersion(); return HMCCosmeticsPlugin.getInstance().getDescription().getVersion();
} }
@Override
public boolean persist() {
return true;
}
@Override @Override
public String onRequest(@NotNull OfflinePlayer player, @NotNull String params) { public String onRequest(@NotNull OfflinePlayer player, @NotNull String params) {
if (!player.isOnline()) return null; if (!player.isOnline()) return null;
@@ -62,8 +67,9 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
} }
if (placeholderArgs.get(1) != null) { if (placeholderArgs.get(1) != null) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1)); Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (cosmetic == null) return "INVALID_COSMETIC";
Cosmetic currentCosmetic = user.getCosmetic(cosmetic.getSlot()); Cosmetic currentCosmetic = user.getCosmetic(cosmetic.getSlot());
if (cosmetic == null || currentCosmetic == null) return "false"; if (currentCosmetic == null) return "false";
if (currentCosmetic.getId() == cosmetic.getId()) return "true"; if (currentCosmetic.getId() == cosmetic.getId()) return "true";
return "false"; return "false";
} }
@@ -104,12 +110,16 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
if (placeholderArgs.get(1) != null) { if (placeholderArgs.get(1) != null) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1)); Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (cosmetic == null) { if (cosmetic == null) {
if (placeholderArgs.size() >= 3) {
Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2)); Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2));
if (secondAttemptCosmetic == null) { if (secondAttemptCosmetic == null) {
return "INVALID_COSMETIC"; return "INVALID_COSMETIC";
} else { } else {
cosmetic = secondAttemptCosmetic; cosmetic = secondAttemptCosmetic;
} }
} else {
return "INVALID_COSMETIC";
}
} }
return TranslationUtil.getTranslation("unlockedCosmetic", String.valueOf(user.canEquipCosmetic(cosmetic))); return TranslationUtil.getTranslation("unlockedCosmetic", String.valueOf(user.canEquipCosmetic(cosmetic)));
} }

View File

@@ -4,6 +4,7 @@ import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.flags.Flag; import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.StateFlag; import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.StringFlag;
import com.sk89q.worldguard.protection.flags.registry.FlagConflictException; import com.sk89q.worldguard.protection.flags.registry.FlagConflictException;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry; import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
@@ -21,13 +22,13 @@ public class WGHook {
/** /**
* @implNote Please use {@link #getCosmeticWardrobeFlag()} instead * @implNote Please use {@link #getCosmeticWardrobeFlag()} instead
*/ */
public static StateFlag COSMETIC_WARDROBE_FLAG; public static StringFlag COSMETIC_WARDROBE_FLAG;
public WGHook() { public WGHook() {
FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry(); FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry();
try { try {
StateFlag cosmeticFlag = new StateFlag("cosmetic-enable", false); StateFlag cosmeticFlag = new StateFlag("cosmetic-enable", false);
StateFlag wardrobeFlag = new StateFlag("cosmetic-wardrobe", false); StringFlag wardrobeFlag = new StringFlag("cosmetic-wardrobe");
registry.register(cosmeticFlag); registry.register(cosmeticFlag);
registry.register(wardrobeFlag); registry.register(wardrobeFlag);
COSMETIC_ENABLE_FLAG = cosmeticFlag; COSMETIC_ENABLE_FLAG = cosmeticFlag;
@@ -56,7 +57,7 @@ public class WGHook {
* Gets the cosmetic wardrobe {@link StateFlag} * Gets the cosmetic wardrobe {@link StateFlag}
* @return The cosmetic wardrobe {@link StateFlag} * @return The cosmetic wardrobe {@link StateFlag}
*/ */
public static StateFlag getCosmeticWardrobeFlag() { public static StringFlag getCosmeticWardrobeFlag() {
return COSMETIC_WARDROBE_FLAG; return COSMETIC_WARDROBE_FLAG;
} }

View File

@@ -1,7 +1,10 @@
package com.hibiscusmc.hmccosmetics.hooks.worldguard; package com.hibiscusmc.hmccosmetics.hooks.worldguard;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.ApplicableRegionSet; import com.sk89q.worldguard.protection.ApplicableRegionSet;
@@ -34,13 +37,17 @@ public class WGListener implements Listener {
} }
for (ProtectedRegion protectedRegion : set.getRegions()) { for (ProtectedRegion protectedRegion : set.getRegions()) {
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticEnableFlag())) { if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticEnableFlag())) {
if (protectedRegion.getFlags().get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) return; if (protectedRegion.getFlags().get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) {
if (user.getHiddenReason() == CosmeticUser.HiddenReason.WORLDGUARD) user.showCosmetics();
return;
}
user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD); user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
return; return;
} }
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticWardrobeFlag())) { if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticWardrobeFlag())) {
if (!protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString().equalsIgnoreCase("ALLOW")) return; if (!WardrobeSettings.getWardrobeNames().contains(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString())) return;
user.enterWardrobe(); Wardrobe wardrobe = WardrobeSettings.getWardrobe(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString());
user.enterWardrobe(true, wardrobe);
} }
} }
} }

View File

@@ -328,11 +328,27 @@ public class PlayerGameListener implements Listener {
CosmeticUser user = CosmeticUsers.getUser(event.getEntity()); CosmeticUser user = CosmeticUsers.getUser(event.getEntity());
if (user == null) return; if (user == null) return;
if (user.isInWardrobe()) user.leaveWardrobe();
if (Settings.getUnapplyOnDeath() && !event.getEntity().hasPermission("hmccosmetics.unapplydeath.bypass")) { if (Settings.getUnapplyOnDeath() && !event.getEntity().hasPermission("hmccosmetics.unapplydeath.bypass")) {
user.removeCosmetics(); user.removeCosmetics();
} }
} }
@EventHandler
public void onPlayerGamemodeSwitch(PlayerGameModeChangeEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return;
if (Settings.isDestroyLooseCosmetics()) {
ItemStack[] equippedArmor = event.getPlayer().getInventory().getArmorContents();
if (equippedArmor.length == 0) return;
for (ItemStack armor : equippedArmor) {
if (InventoryUtils.isCosmeticItem(armor)) armor.setAmount(0);
}
}
}
private void registerInventoryClickListener() { private void registerInventoryClickListener() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.WINDOW_CLICK) { ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.WINDOW_CLICK) {
@Override @Override

View File

@@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableList;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.api.*; import com.hibiscusmc.hmccosmetics.api.*;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings; import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
@@ -30,7 +31,7 @@ import java.util.logging.Level;
public class CosmeticUser { public class CosmeticUser {
private UUID uniqueId; private final UUID uniqueId;
private int taskId; private int taskId;
private HashMap<CosmeticSlot, Cosmetic> playerCosmetics = new HashMap<>(); private HashMap<CosmeticSlot, Cosmetic> playerCosmetics = new HashMap<>();
private UserWardrobeManager userWardrobeManager; private UserWardrobeManager userWardrobeManager;
@@ -52,7 +53,7 @@ public class CosmeticUser {
private void tick() { private void tick() {
// Occasionally updates the entity cosmetics // Occasionally updates the entity cosmetics
Runnable run = () -> { Runnable run = () -> {
MessagesUtil.sendDebugMessages("tick " + uniqueId, Level.INFO); MessagesUtil.sendDebugMessages("Tick[uuid=" + uniqueId + "]", Level.INFO);
updateCosmetic(); updateCosmetic();
}; };
@@ -105,11 +106,11 @@ public class CosmeticUser {
playerCosmetics.put(cosmetic.getSlot(), cosmetic); playerCosmetics.put(cosmetic.getSlot(), cosmetic);
if (color != null) colors.put(cosmetic.getSlot(), color); if (color != null) colors.put(cosmetic.getSlot(), color);
MessagesUtil.sendDebugMessages("addPlayerCosmetic " + cosmetic.getId()); MessagesUtil.sendDebugMessages("addPlayerCosmetic[id=" + cosmetic.getId() + "]");
if (cosmetic.getSlot() == CosmeticSlot.BACKPACK) { if (cosmetic.getSlot() == CosmeticSlot.BACKPACK) {
CosmeticBackpackType backpackType = (CosmeticBackpackType) cosmetic; CosmeticBackpackType backpackType = (CosmeticBackpackType) cosmetic;
spawnBackpack(backpackType); spawnBackpack(backpackType);
MessagesUtil.sendDebugMessages("addPlayerCosmetic spawnBackpack " + cosmetic.getId()); MessagesUtil.sendDebugMessages("addPlayerCosmetic[spawnBackpack,id=" + cosmetic.getId() + "]");
} }
if (cosmetic.getSlot() == CosmeticSlot.BALLOON) { if (cosmetic.getSlot() == CosmeticSlot.BALLOON) {
CosmeticBalloonType balloonType = (CosmeticBalloonType) cosmetic; CosmeticBalloonType balloonType = (CosmeticBalloonType) cosmetic;
@@ -156,6 +157,11 @@ public class CosmeticUser {
return playerCosmetics.containsKey(slot); return playerCosmetics.containsKey(slot);
} }
public boolean hasCosmeticInSlot(Cosmetic cosmetic) {
if (getCosmetic(cosmetic.getSlot()) == null) return false;
return Objects.equals(cosmetic.getId(), getCosmetic(cosmetic.getSlot()).getId());
}
public Set<CosmeticSlot> getSlotsWithCosmetics() { public Set<CosmeticSlot> getSlotsWithCosmetics() {
return Set.copyOf(playerCosmetics.keySet()); return Set.copyOf(playerCosmetics.keySet());
} }
@@ -173,7 +179,7 @@ public class CosmeticUser {
} }
public void updateCosmetic() { public void updateCosmetic() {
for (Cosmetic cosmetic : playerCosmetics.values()) { for (Cosmetic cosmetic : getCosmetics()) {
updateCosmetic(cosmetic.getSlot()); updateCosmetic(cosmetic.getSlot());
} }
} }
@@ -210,7 +216,8 @@ public class CosmeticUser {
mapMeta.setColor(color); mapMeta.setColor(color);
} }
} }
itemMeta.getPersistentDataContainer().set(InventoryUtils.getKey(), PersistentDataType.STRING, "true"); itemMeta.getPersistentDataContainer().set(InventoryUtils.getCosmeticKey(), PersistentDataType.STRING, cosmetic.getId());
itemMeta.getPersistentDataContainer().set(InventoryUtils.getOwnerKey(), PersistentDataType.STRING, getPlayer().getUniqueId().toString());
item.setItemMeta(itemMeta); item.setItemMeta(itemMeta);
} }
@@ -233,27 +240,28 @@ public class CosmeticUser {
return userEmoteManager; return userEmoteManager;
} }
public void enterWardrobe() { public void enterWardrobe(boolean ignoreDistance, Wardrobe wardrobe) {
enterWardrobe(false); if (wardrobe.hasPermission() && !getPlayer().hasPermission(wardrobe.getPermission())) {
MessagesUtil.sendMessage(getPlayer(), "no-permission");
return;
} }
if (!wardrobe.canEnter(this) && !ignoreDistance) {
public void enterWardrobe(boolean ignoreDistance) {
enterWardrobe(ignoreDistance, WardrobeSettings.getLeaveLocation(), WardrobeSettings.getViewerLocation(), WardrobeSettings.getWardrobeLocation());
}
public void enterWardrobe(boolean ignoreDistance, Location exitLocation, Location viewingLocation, Location npcLocation) {
if (!WardrobeSettings.inDistanceOfStatic(getPlayer().getLocation()) && !ignoreDistance) {
MessagesUtil.sendMessage(getPlayer(), "not-near-wardrobe"); MessagesUtil.sendMessage(getPlayer(), "not-near-wardrobe");
return; return;
} }
PlayerWardrobeEnterEvent event = new PlayerWardrobeEnterEvent(this); if (!wardrobe.getLocation().hasAllLocations()) {
MessagesUtil.sendMessage(getPlayer(), "wardrobe-not-setup");
return;
}
PlayerWardrobeEnterEvent event = new PlayerWardrobeEnterEvent(this, wardrobe);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
} }
wardrobe = event.getWardrobe();
if (userWardrobeManager == null) { if (userWardrobeManager == null) {
userWardrobeManager = new UserWardrobeManager(this, exitLocation, viewingLocation, npcLocation); userWardrobeManager = new UserWardrobeManager(this, wardrobe);
userWardrobeManager.start(); userWardrobeManager.start();
} }
} }
@@ -264,6 +272,7 @@ public class CosmeticUser {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
} }
MessagesUtil.sendDebugMessages("Leaving Wardrobe");
if (!getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return; if (!getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return;
getWardrobeManager().setWardrobeStatus(UserWardrobeManager.WardrobeStatus.STOPPING); getWardrobeManager().setWardrobeStatus(UserWardrobeManager.WardrobeStatus.STOPPING);
@@ -280,20 +289,14 @@ public class CosmeticUser {
userWardrobeManager.end(); userWardrobeManager.end();
userWardrobeManager = null; userWardrobeManager = null;
}, WardrobeSettings.getTransitionDelay()); }, WardrobeSettings.getTransitionDelay());
} else {
userWardrobeManager.end();
userWardrobeManager = null;
} }
} }
public boolean isInWardrobe() { public boolean isInWardrobe() {
if (userWardrobeManager == null) return false; return userWardrobeManager != null;
return true;
}
public void toggleWardrobe() {
if (isInWardrobe()) {
leaveWardrobe();
} else {
enterWardrobe();
}
} }
public void spawnBackpack(CosmeticBackpackType cosmeticBackpackType) { public void spawnBackpack(CosmeticBackpackType cosmeticBackpackType) {
@@ -309,8 +312,7 @@ public class CosmeticUser {
} }
public boolean isBackpackSpawned() { public boolean isBackpackSpawned() {
if (this.userBackpackManager == null) return false; return this.userBackpackManager != null;
return true;
} }
public void spawnBalloon(CosmeticBalloonType cosmeticBalloonType) { public void spawnBalloon(CosmeticBalloonType cosmeticBalloonType) {
@@ -361,7 +363,7 @@ public class CosmeticUser {
} }
public List<CosmeticSlot> getDyeableSlots() { public List<CosmeticSlot> getDyeableSlots() {
ArrayList<CosmeticSlot> dyableSlots = new ArrayList(); ArrayList<CosmeticSlot> dyableSlots = new ArrayList<>();
for (Cosmetic cosmetic : getCosmetics()) { for (Cosmetic cosmetic : getCosmetics()) {
if (cosmetic.isDyable()) dyableSlots.add(cosmetic.getSlot()); if (cosmetic.isDyable()) dyableSlots.add(cosmetic.getSlot());
@@ -372,8 +374,8 @@ public class CosmeticUser {
public boolean canEquipCosmetic(Cosmetic cosmetic) { public boolean canEquipCosmetic(Cosmetic cosmetic) {
if (!cosmetic.requiresPermission()) return true; if (!cosmetic.requiresPermission()) return true;
if (getPlayer().hasPermission(cosmetic.getPermission())) return true; if (isInWardrobe() && WardrobeSettings.isTryCosmeticsInWardrobe()) return true;
return false; return getPlayer().hasPermission(cosmetic.getPermission());
} }
public void hidePlayer() { public void hidePlayer() {
@@ -395,7 +397,7 @@ public class CosmeticUser {
} }
public void hideCosmetics(HiddenReason reason) { public void hideCosmetics(HiddenReason reason) {
if (hideCosmetics == true) return; if (hideCosmetics) return;
PlayerCosmeticHideEvent event = new PlayerCosmeticHideEvent(this, reason); PlayerCosmeticHideEvent event = new PlayerCosmeticHideEvent(this, reason);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {

View File

@@ -3,6 +3,7 @@ package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.api.PlayerEmoteStartEvent; import com.hibiscusmc.hmccosmetics.api.PlayerEmoteStartEvent;
import com.hibiscusmc.hmccosmetics.api.PlayerEmoteStopEvent; import com.hibiscusmc.hmccosmetics.api.PlayerEmoteStopEvent;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -19,7 +20,7 @@ public class UserEmoteManager {
public void playEmote(@NotNull CosmeticEmoteType cosmeticEmoteType) { public void playEmote(@NotNull CosmeticEmoteType cosmeticEmoteType) {
MessagesUtil.sendDebugMessages("playEmote " + cosmeticEmoteType.getAnimationId()); MessagesUtil.sendDebugMessages("playEmote " + cosmeticEmoteType.getAnimationId());
playEmote(cosmeticEmoteType.getAnimationId()); playEmote(EmoteManager.get(cosmeticEmoteType.getAnimationId()));
} }
public void playEmote(String animationId) { public void playEmote(String animationId) {

View File

@@ -57,11 +57,21 @@ public class UserEmoteModel extends PlayerModel {
double DISTANCE = Settings.getEmoteDistance(); double DISTANCE = Settings.getEmoteDistance();
Location thirdPersonLocation = newLocation.add(newLocation.getDirection().normalize().multiply(DISTANCE)); Location thirdPersonLocation = newLocation.add(newLocation.getDirection().normalize().multiply(DISTANCE));
if (DISTANCE > 0) {
MessagesUtil.sendDebugMessages("Yaw " + (int) thirdPersonLocation.getYaw());
MessagesUtil.sendDebugMessages("New Yaw " + ServerUtils.getNextYaw((int) thirdPersonLocation.getYaw(), 180));
thirdPersonLocation.setYaw(ServerUtils.getNextYaw((int) thirdPersonLocation.getYaw(), 180));
}
if (Settings.getCosmeticEmoteBlockCheck() && thirdPersonLocation.getBlock().getType().isOccluding()) { if (Settings.getCosmeticEmoteBlockCheck() && thirdPersonLocation.getBlock().getType().isOccluding()) {
stopAnimation(); stopAnimation();
MessagesUtil.sendMessage(player, "emote-blocked"); MessagesUtil.sendMessage(player, "emote-blocked");
return; return;
} }
// Check if block below player is an air block
if (Settings.getEmoteAirCheck() && newLocation.clone().subtract(0, 1, 0).getBlock().getType().isAir()) {
stopAnimation();
MessagesUtil.sendMessage(player, "emote-blocked");
}
user.getPlayer().setInvisible(true); user.getPlayer().setInvisible(true);
user.hideCosmetics(CosmeticUser.HiddenReason.EMOTE); user.hideCosmetics(CosmeticUser.HiddenReason.EMOTE);
@@ -70,7 +80,7 @@ public class UserEmoteModel extends PlayerModel {
PacketManager.sendEntitySpawnPacket(thirdPersonLocation, armorStandId, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer); PacketManager.sendEntitySpawnPacket(thirdPersonLocation, armorStandId, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer);
PacketManager.sendInvisibilityPacket(armorStandId, viewer); PacketManager.sendInvisibilityPacket(armorStandId, viewer);
PacketManager.sendLookPacket(armorStandId, player.getLocation(), viewer); PacketManager.sendLookPacket(armorStandId, thirdPersonLocation, viewer);
PacketManager.gamemodeChangePacket(player, 3); PacketManager.gamemodeChangePacket(player, 3);
PacketManager.sendCameraPacket(armorStandId, viewer); PacketManager.sendCameraPacket(armorStandId, viewer);

View File

@@ -2,6 +2,8 @@ package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeLocation;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings; import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
@@ -38,6 +40,8 @@ public class UserWardrobeManager {
private String npcName; private String npcName;
private GameMode originalGamemode; private GameMode originalGamemode;
private final CosmeticUser user; private final CosmeticUser user;
private final Wardrobe wardrobe;
private final WardrobeLocation wardrobeLocation;
private final Location viewingLocation; private final Location viewingLocation;
private final Location npcLocation; private final Location npcLocation;
private Location exitLocation; private Location exitLocation;
@@ -45,15 +49,18 @@ public class UserWardrobeManager {
private boolean active; private boolean active;
private WardrobeStatus wardrobeStatus; private WardrobeStatus wardrobeStatus;
public UserWardrobeManager(CosmeticUser user, Location exitLocation, Location viewingLocation, Location npcLocation) { public UserWardrobeManager(CosmeticUser user, Wardrobe wardrobe) {
NPC_ID = NMSHandlers.getHandler().getNextEntityId(); NPC_ID = NMSHandlers.getHandler().getNextEntityId();
ARMORSTAND_ID = NMSHandlers.getHandler().getNextEntityId(); ARMORSTAND_ID = NMSHandlers.getHandler().getNextEntityId();
WARDROBE_UUID = UUID.randomUUID(); WARDROBE_UUID = UUID.randomUUID();
this.user = user; this.user = user;
this.exitLocation = exitLocation; this.wardrobe = wardrobe;
this.viewingLocation = viewingLocation; this.wardrobeLocation = wardrobe.getLocation();
this.npcLocation = npcLocation;
this.exitLocation = wardrobeLocation.getLeaveLocation();
this.viewingLocation = wardrobeLocation.getViewerLocation();
this.npcLocation = wardrobeLocation.getNpcLocation();
wardrobeStatus = WardrobeStatus.SETUP; wardrobeStatus = WardrobeStatus.SETUP;
} }
@@ -208,9 +215,7 @@ public class UserWardrobeManager {
// For Wardrobe Temp Cosmetics // For Wardrobe Temp Cosmetics
for (Cosmetic cosmetic : user.getCosmetics()) { for (Cosmetic cosmetic : user.getCosmetics()) {
if (cosmetic.requiresPermission()) { if (!user.canEquipCosmetic(cosmetic)) user.removeCosmeticSlot(cosmetic.getSlot());
if (!player.hasPermission(cosmetic.getPermission())) user.removeCosmeticSlot(cosmetic.getSlot());
}
} }
user.updateCosmetic(); user.updateCosmetic();
@@ -226,16 +231,16 @@ public class UserWardrobeManager {
public void run() { public void run() {
Player player = user.getPlayer(); Player player = user.getPlayer();
if (!active || player == null) { if (!active || player == null) {
MessagesUtil.sendDebugMessages("Active is false"); MessagesUtil.sendDebugMessages("WardrobeEnd[user=" + user.getUniqueId() + ",reason=Active is false]");
this.cancel(); this.cancel();
return; return;
} }
MessagesUtil.sendDebugMessages("Update "); MessagesUtil.sendDebugMessages("WardrobeUpdate[user=" + user.getUniqueId() + ",status=" + getWardrobeStatus() + "]");
List<Player> viewer = Collections.singletonList(player); List<Player> viewer = Collections.singletonList(player);
List<Player> outsideViewers = PacketManager.getViewers(viewingLocation); List<Player> outsideViewers = PacketManager.getViewers(viewingLocation);
outsideViewers.remove(player); outsideViewers.remove(player);
Location location = WardrobeSettings.getWardrobeLocation().clone(); Location location = npcLocation;
int yaw = data.get(); int yaw = data.get();
location.setYaw(yaw); location.setYaw(yaw);
@@ -259,8 +264,8 @@ public class UserWardrobeManager {
} }
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) { if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
PacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), WardrobeSettings.getWardrobeLocation().add(Settings.getBalloonOffset()), false, viewer); PacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), npcLocation.add(Settings.getBalloonOffset()), false, viewer);
user.getBalloonManager().getModelEntity().teleport(WardrobeSettings.getWardrobeLocation().add(Settings.getBalloonOffset())); user.getBalloonManager().getModelEntity().teleport(npcLocation.add(Settings.getBalloonOffset()));
user.getBalloonManager().sendRemoveLeashPacket(outsideViewers); user.getBalloonManager().sendRemoveLeashPacket(outsideViewers);
PacketManager.sendEntityDestroyPacket(user.getBalloonManager().getModelId(), outsideViewers); PacketManager.sendEntityDestroyPacket(user.getBalloonManager().getModelId(), outsideViewers);
user.getBalloonManager().sendLeashPacket(NPC_ID); user.getBalloonManager().sendLeashPacket(NPC_ID);

View File

@@ -143,12 +143,17 @@ public class InventoryUtils {
} }
public static boolean isCosmeticItem(ItemStack itemStack) { public static boolean isCosmeticItem(ItemStack itemStack) {
if (itemStack == null) return false;
itemStack = itemStack.clone(); itemStack = itemStack.clone();
if (!itemStack.hasItemMeta()) return false; if (!itemStack.hasItemMeta()) return false;
return itemStack.getItemMeta().getPersistentDataContainer().has(getKey(), PersistentDataType.STRING); return itemStack.getItemMeta().getPersistentDataContainer().has(getCosmeticKey(), PersistentDataType.STRING);
} }
public static NamespacedKey getKey() { public static NamespacedKey getCosmeticKey() {
return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmetic"); return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmetic");
} }
public static NamespacedKey getOwnerKey() {
return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "owner");
}
} }

View File

@@ -306,15 +306,21 @@ public class PacketManager extends BasePacket {
WrappedGameProfile wrappedGameProfile = new WrappedGameProfile(uuid, name); WrappedGameProfile wrappedGameProfile = new WrappedGameProfile(uuid, name);
WrappedSignedProperty skinData = PlayerUtils.getSkin(skinnedPlayer); WrappedSignedProperty skinData = PlayerUtils.getSkin(skinnedPlayer);
if (skinData != null) wrappedGameProfile.getProperties().put("textures", skinData); if (skinData != null) wrappedGameProfile.getProperties().put("textures", skinData);
if (NMSHandlers.getVersion().contains("v1_17_R1") || NMSHandlers.getVersion().contains("v1_18_R2") || NMSHandlers.getVersion().contains("v1_19_R1") || NMSHandlers.getVersion().contains("v1_19_R3")) { // For sor some reason 1.19.2 handles it on the 0 field index, every other verison handles it on the 1
info.getHandle().getPlayerInfoDataLists().write(1, Collections.singletonList(new PlayerInfoData( if (NMSHandlers.getVersion().contains("v1_19_R1")) {
info.getHandle().getPlayerInfoDataLists().write(0, Collections.singletonList(new PlayerInfoData(
wrappedGameProfile, wrappedGameProfile,
0, 0,
EnumWrappers.NativeGameMode.CREATIVE, EnumWrappers.NativeGameMode.CREATIVE,
WrappedChatComponent.fromText(name) WrappedChatComponent.fromText(name)
))); )));
} else { } else {
info.setData(List.of(new PlayerInfoData(wrappedGameProfile, 0, EnumWrappers.NativeGameMode.CREATIVE, WrappedChatComponent.fromText(name)))); info.getHandle().getPlayerInfoDataLists().write(1, Collections.singletonList(new PlayerInfoData(
wrappedGameProfile,
0,
EnumWrappers.NativeGameMode.CREATIVE,
WrappedChatComponent.fromText(name)
)));
} }
for (final Player p : sendTo) sendPacket(p, info.getHandle()); for (final Player p : sendTo) sendPacket(p, info.getHandle());
} }

View File

@@ -25,6 +25,7 @@ cosmetic-settings:
emote-distance: -3 # This shows how far away the camera should be while a player is doing an emote. Negative is behind player. emote-distance: -3 # This shows how far away the camera should be while a player is doing an emote. Negative is behind player.
emote-block-check: true # If the server should check if the block is open where the camera is placed (prevents players viewing through blocks) emote-block-check: true # If the server should check if the block is open where the camera is placed (prevents players viewing through blocks)
emote-air-check: true # Check if there is air under a player, if there is, don't play emote
emote-damage-leave: true # If the player should leave the emote when they take damage emote-damage-leave: true # If the player should leave the emote when they take damage
emote-invincible: false # If the player should not take damage while doing an emote emote-invincible: false # If the player should not take damage while doing an emote
@@ -70,10 +71,12 @@ wardrobe:
equip-pumpkin: false equip-pumpkin: false
# Rather than having a set exit location, this will send the player back to where they entered the wardrobe. Not recommended for WG regions # Rather than having a set exit location, this will send the player back to where they entered the wardrobe. Not recommended for WG regions
return-last-location: false return-last-location: false
# If players in wardrobes should be able to equip any cosmetic, regardless of permission (Cosmetics they do not have access to will be removed when they leave the wardrobe)
unchecked-wardrobe-cosmetics: false
gamemode-options: gamemode-options:
exit-gamemode-enabled: false # Setting this to false will set the gamemode the player came in as. True sets to exit-gamemode gamemode exit-gamemode-enabled: false # Setting this to false will set the gamemode the player came in as. True sets to exit-gamemode gamemode
exit-gamemode: "SURVIVAL" # Only activates if force-exit-gamemode is true, find gamemodes here: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/GameMode.html exit-gamemode: "SURVIVAL" # Only activates if exit-gamemode-enabled is true, find gamemodes here: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/GameMode.html
# Bossbar that shows when a player is in a wardrobe. # Bossbar that shows when a player is in a wardrobe.
bossbar: bossbar:
@@ -91,22 +94,24 @@ wardrobe:
title-fade-in: 1000 # milliseconds title-fade-in: 1000 # milliseconds
title-stay: 500 # milliseconds title-stay: 500 # milliseconds
title-fade-out: 1000 # milliseconds title-fade-out: 1000 # milliseconds
wardrobe-location: wardrobes:
world: "World" default:
npc-location:
world: "world"
x: 0 x: 0
y: 0 y: 0
z: 0 z: 0
yaw: 0 yaw: 0
pitch: 0 pitch: 0
viewer-location: viewer-location:
world: "World" world: "world"
x: 5 x: 5
y: 0 y: 0
z: 5 z: 5
yaw: 0 yaw: 0
pitch: 0 pitch: 0
leave-location: leave-location:
world: "World" world: "world"
x: 5 x: 5
y: 5 y: 5
z: 5 z: 5

View File

@@ -124,7 +124,6 @@ earth_day_grabber:
slot: OFFHAND slot: OFFHAND
dyeable: true dyeable: true
permission: "hmccosmetics.earth_day_grabber" permission: "hmccosmetics.earth_day_grabber"
model: earth_day_grabber
item: item:
material: LEATHER_HORSE_ARMOR material: LEATHER_HORSE_ARMOR
model-data: 4 model-data: 4

View File

@@ -11,6 +11,10 @@ not-near-wardrobe: "%prefix% <red>You are not near the wardrobe!"
set-wardrobe-location: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe location!" set-wardrobe-location: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe location!"
set-wardrobe-viewing: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe viewing location!" set-wardrobe-viewing: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe viewing location!"
set-wardrobe-leaving: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe leaving location!" set-wardrobe-leaving: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe leaving location!"
set-wardrobe-permission: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe permission!"
set-wardrobe-distance: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe distance!"
no-wardrobes: "%prefix% <red>There are no wardrobes with that name!"
wardrobe-not-setup: "%prefix% <red>This wardrobe does not have all required locations set!"
equip-cosmetic: "%prefix% <gradient:#6D9DC5:#45CDE9>You have equipped <cosmetic>!" equip-cosmetic: "%prefix% <gradient:#6D9DC5:#45CDE9>You have equipped <cosmetic>!"
unequip-cosmetic: "%prefix% <gradient:#6D9DC5:#45CDE9>You have unequipped <cosmetic>!" unequip-cosmetic: "%prefix% <gradient:#6D9DC5:#45CDE9>You have unequipped <cosmetic>!"